1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef INCLUDED_PDFI_STYLE_HXX 29 #define INCLUDED_PDFI_STYLE_HXX 30 31 #include "pdfihelper.hxx" 32 #include <hash_map> 33 #include <vector> 34 #include <rtl/ustring.hxx> 35 #include <rtl/string.hxx> 36 #include "treevisiting.hxx" 37 38 namespace pdfi 39 { 40 struct Element; 41 struct EmitContext; 42 struct ElementTreeVisitable; 43 44 class StyleContainer 45 { 46 public: 47 struct Style 48 { 49 rtl::OString Name; 50 PropertyMap Properties; 51 rtl::OUString Contents; 52 Element* ContainedElement; 53 std::vector< Style* > SubStyles; 54 55 Style() : ContainedElement( NULL ) {} 56 Style( const rtl::OString& rName, const PropertyMap& rProps ) : 57 Name( rName ), 58 Properties( rProps ), 59 ContainedElement( NULL ) 60 {} 61 }; 62 63 private: 64 struct HashedStyle 65 { 66 rtl::OString Name; 67 PropertyMap Properties; 68 rtl::OUString Contents; 69 Element* ContainedElement; 70 std::vector<sal_Int32> SubStyles; 71 72 bool IsSubStyle; 73 sal_Int32 RefCount; 74 75 HashedStyle() : ContainedElement( NULL ), IsSubStyle( true ), RefCount( 0 ) {} 76 77 HashedStyle( const HashedStyle& rRight ) : 78 Name( rRight.Name ), 79 Properties( rRight.Properties ), 80 Contents( rRight.Contents ), 81 ContainedElement( rRight.ContainedElement ), 82 SubStyles( rRight.SubStyles ), 83 IsSubStyle( rRight.IsSubStyle ), 84 RefCount( 0 ) 85 {} 86 87 size_t hashCode() const 88 { 89 size_t nRet = size_t(Name.hashCode()); 90 for( PropertyMap::const_iterator it = Properties.begin(); 91 it != Properties.end(); ++it ) 92 { 93 nRet ^= size_t(it->first.hashCode()); 94 nRet ^= size_t(it->second.hashCode()); 95 } 96 nRet = size_t(Contents.hashCode()); 97 nRet ^= size_t(ContainedElement); 98 for( unsigned int n = 0; n < SubStyles.size(); ++n ) 99 nRet ^= size_t(SubStyles[n]); 100 return nRet; 101 } 102 103 bool operator==(const HashedStyle& rRight) const 104 { 105 if( Name != rRight.Name || 106 Properties != rRight.Properties || 107 Contents != rRight.Contents || 108 ContainedElement != rRight.ContainedElement || 109 SubStyles.size() != rRight.SubStyles.size() 110 ) 111 return false; 112 for( unsigned int n = 0; n < SubStyles.size(); ++n ) 113 { 114 if( SubStyles[n] != rRight.SubStyles[n] ) 115 return false; 116 } 117 return true; 118 } 119 }; 120 121 struct StyleHash; 122 friend struct StyleHash; 123 struct StyleHash 124 { 125 size_t operator()( const StyleContainer::HashedStyle& rStyle ) const 126 { 127 return rStyle.hashCode(); 128 } 129 }; 130 131 struct StyleIdNameSort; 132 friend struct StyleIdNameSort; 133 struct StyleIdNameSort 134 { 135 const std::hash_map< sal_Int32, HashedStyle >* m_pMap; 136 137 StyleIdNameSort( const std::hash_map< sal_Int32, HashedStyle >* pMap ) : 138 m_pMap(pMap) 139 {} 140 bool operator()( sal_Int32 nLeft, sal_Int32 nRight ) 141 { 142 const std::hash_map< sal_Int32, HashedStyle >::const_iterator left_it = 143 m_pMap->find( nLeft ); 144 const std::hash_map< sal_Int32, HashedStyle >::const_iterator right_it = 145 m_pMap->find( nRight ); 146 if( left_it == m_pMap->end() ) 147 return false; 148 else if( right_it == m_pMap->end() ) 149 return true; 150 else 151 return left_it->second.Name < right_it->second.Name; 152 } 153 }; 154 155 sal_Int32 m_nNextId; 156 std::hash_map< sal_Int32, HashedStyle > m_aIdToStyle; 157 std::hash_map< HashedStyle, sal_Int32, StyleHash > m_aStyleToId; 158 159 void impl_emitStyle( sal_Int32 nStyleId, 160 EmitContext& rContext, 161 ElementTreeVisitor& rContainedElemVisitor ); 162 163 public: 164 StyleContainer(); 165 166 void emit( EmitContext& rContext, 167 ElementTreeVisitor& rContainedElemVisitor ); 168 169 sal_Int32 impl_getStyleId( const Style& rStyle, bool bSubStyle ); 170 sal_Int32 getStyleId( const Style& rStyle ) 171 { return impl_getStyleId( rStyle, false ); } 172 sal_Int32 getStandardStyleId( const rtl::OString& rFamily ); 173 174 // returns NULL for an invalid style id 175 const PropertyMap* getProperties( sal_Int32 nStyleId ) const; 176 sal_Int32 setProperties( sal_Int32 nStyleId, const PropertyMap &rNewProps ); 177 rtl::OUString getStyleName( sal_Int32 nStyle ) const; 178 }; 179 } 180 181 #endif 182