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