1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef INCLUDED_PDFI_STYLE_HXX 25 #define INCLUDED_PDFI_STYLE_HXX 26 27 #include "pdfihelper.hxx" 28 #include <hash_map> 29 #include <vector> 30 #include <rtl/ustring.hxx> 31 #include <rtl/string.hxx> 32 #include "treevisiting.hxx" 33 34 namespace pdfi 35 { 36 struct Element; 37 struct EmitContext; 38 struct ElementTreeVisitable; 39 40 class StyleContainer 41 { 42 public: 43 struct Style 44 { 45 rtl::OString Name; 46 PropertyMap Properties; 47 rtl::OUString Contents; 48 Element* ContainedElement; 49 std::vector< Style* > SubStyles; 50 Stylepdfi::StyleContainer::Style51 Style() : ContainedElement( NULL ) {} Stylepdfi::StyleContainer::Style52 Style( const rtl::OString& rName, const PropertyMap& rProps ) : 53 Name( rName ), 54 Properties( rProps ), 55 ContainedElement( NULL ) 56 {} 57 }; 58 59 private: 60 struct HashedStyle 61 { 62 rtl::OString Name; 63 PropertyMap Properties; 64 rtl::OUString Contents; 65 Element* ContainedElement; 66 std::vector<sal_Int32> SubStyles; 67 68 bool IsSubStyle; 69 sal_Int32 RefCount; 70 HashedStylepdfi::StyleContainer::HashedStyle71 HashedStyle() : ContainedElement( NULL ), IsSubStyle( true ), RefCount( 0 ) {} 72 HashedStylepdfi::StyleContainer::HashedStyle73 HashedStyle( const HashedStyle& rRight ) : 74 Name( rRight.Name ), 75 Properties( rRight.Properties ), 76 Contents( rRight.Contents ), 77 ContainedElement( rRight.ContainedElement ), 78 SubStyles( rRight.SubStyles ), 79 IsSubStyle( rRight.IsSubStyle ), 80 RefCount( 0 ) 81 {} 82 hashCodepdfi::StyleContainer::HashedStyle83 size_t hashCode() const 84 { 85 size_t nRet = size_t(Name.hashCode()); 86 for( PropertyMap::const_iterator it = Properties.begin(); 87 it != Properties.end(); ++it ) 88 { 89 nRet ^= size_t(it->first.hashCode()); 90 nRet ^= size_t(it->second.hashCode()); 91 } 92 nRet = size_t(Contents.hashCode()); 93 nRet ^= size_t(ContainedElement); 94 for( unsigned int n = 0; n < SubStyles.size(); ++n ) 95 nRet ^= size_t(SubStyles[n]); 96 return nRet; 97 } 98 operator ==pdfi::StyleContainer::HashedStyle99 bool operator==(const HashedStyle& rRight) const 100 { 101 if( Name != rRight.Name || 102 Properties != rRight.Properties || 103 Contents != rRight.Contents || 104 ContainedElement != rRight.ContainedElement || 105 SubStyles.size() != rRight.SubStyles.size() 106 ) 107 return false; 108 for( unsigned int n = 0; n < SubStyles.size(); ++n ) 109 { 110 if( SubStyles[n] != rRight.SubStyles[n] ) 111 return false; 112 } 113 return true; 114 } 115 }; 116 117 struct StyleHash; 118 friend struct StyleHash; 119 struct StyleHash 120 { operator ()pdfi::StyleContainer::StyleHash121 size_t operator()( const StyleContainer::HashedStyle& rStyle ) const 122 { 123 return rStyle.hashCode(); 124 } 125 }; 126 127 struct StyleIdNameSort; 128 friend struct StyleIdNameSort; 129 struct StyleIdNameSort 130 { 131 const std::hash_map< sal_Int32, HashedStyle >* m_pMap; 132 StyleIdNameSortpdfi::StyleContainer::StyleIdNameSort133 StyleIdNameSort( const std::hash_map< sal_Int32, HashedStyle >* pMap ) : 134 m_pMap(pMap) 135 {} operator ()pdfi::StyleContainer::StyleIdNameSort136 bool operator()( sal_Int32 nLeft, sal_Int32 nRight ) 137 { 138 const std::hash_map< sal_Int32, HashedStyle >::const_iterator left_it = 139 m_pMap->find( nLeft ); 140 const std::hash_map< sal_Int32, HashedStyle >::const_iterator right_it = 141 m_pMap->find( nRight ); 142 if( left_it == m_pMap->end() ) 143 return false; 144 else if( right_it == m_pMap->end() ) 145 return true; 146 else 147 return left_it->second.Name < right_it->second.Name; 148 } 149 }; 150 151 sal_Int32 m_nNextId; 152 std::hash_map< sal_Int32, HashedStyle > m_aIdToStyle; 153 std::hash_map< HashedStyle, sal_Int32, StyleHash > m_aStyleToId; 154 155 void impl_emitStyle( sal_Int32 nStyleId, 156 EmitContext& rContext, 157 ElementTreeVisitor& rContainedElemVisitor ); 158 159 public: 160 StyleContainer(); 161 162 void emit( EmitContext& rContext, 163 ElementTreeVisitor& rContainedElemVisitor ); 164 165 sal_Int32 impl_getStyleId( const Style& rStyle, bool bSubStyle ); getStyleId(const Style & rStyle)166 sal_Int32 getStyleId( const Style& rStyle ) 167 { return impl_getStyleId( rStyle, false ); } 168 sal_Int32 getStandardStyleId( const rtl::OString& rFamily ); 169 170 // returns NULL for an invalid style id 171 const PropertyMap* getProperties( sal_Int32 nStyleId ) const; 172 sal_Int32 setProperties( sal_Int32 nStyleId, const PropertyMap &rNewProps ); 173 rtl::OUString getStyleName( sal_Int32 nStyle ) const; 174 }; 175 } 176 177 #endif 178