Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_SDEXT_SOURCE_PDFIMPORT_TREE_STYLE_HXX
21 : #define INCLUDED_SDEXT_SOURCE_PDFIMPORT_TREE_STYLE_HXX
22 :
23 : #include "pdfihelper.hxx"
24 : #include <boost/unordered_map.hpp>
25 : #include <vector>
26 : #include <rtl/ustring.hxx>
27 : #include <rtl/string.hxx>
28 : #include "treevisiting.hxx"
29 :
30 : namespace pdfi
31 : {
32 : struct Element;
33 : struct EmitContext;
34 : struct ElementTreeVisitable;
35 :
36 0 : class StyleContainer
37 : {
38 : public:
39 0 : struct Style
40 : {
41 : OString Name;
42 : PropertyMap Properties;
43 : OUString Contents;
44 : Element* ContainedElement;
45 : std::vector< Style* > SubStyles;
46 :
47 : Style() : ContainedElement( NULL ) {}
48 0 : Style( const OString& rName, const PropertyMap& rProps ) :
49 : Name( rName ),
50 : Properties( rProps ),
51 0 : ContainedElement( NULL )
52 0 : {}
53 : };
54 :
55 : private:
56 0 : struct HashedStyle
57 : {
58 : OString Name;
59 : PropertyMap Properties;
60 : OUString Contents;
61 : Element* ContainedElement;
62 : std::vector<sal_Int32> SubStyles;
63 :
64 : bool IsSubStyle;
65 : sal_Int32 RefCount;
66 :
67 0 : HashedStyle() : ContainedElement( NULL ), IsSubStyle( true ), RefCount( 0 ) {}
68 :
69 0 : HashedStyle( const HashedStyle& rRight ) :
70 : Name( rRight.Name ),
71 : Properties( rRight.Properties ),
72 : Contents( rRight.Contents ),
73 : ContainedElement( rRight.ContainedElement ),
74 : SubStyles( rRight.SubStyles ),
75 : IsSubStyle( rRight.IsSubStyle ),
76 0 : RefCount( 0 )
77 0 : {}
78 :
79 0 : size_t hashCode() const
80 : {
81 0 : size_t nRet = size_t(Name.hashCode());
82 0 : for( PropertyMap::const_iterator it = Properties.begin();
83 0 : it != Properties.end(); ++it )
84 : {
85 0 : nRet ^= size_t(it->first.hashCode());
86 0 : nRet ^= size_t(it->second.hashCode());
87 : }
88 0 : nRet = size_t(Contents.hashCode());
89 0 : nRet ^= size_t(ContainedElement);
90 0 : for( unsigned int n = 0; n < SubStyles.size(); ++n )
91 0 : nRet ^= size_t(SubStyles[n]);
92 0 : return nRet;
93 : }
94 :
95 0 : bool operator==(const HashedStyle& rRight) const
96 : {
97 0 : if( Name != rRight.Name ||
98 0 : Properties != rRight.Properties ||
99 0 : Contents != rRight.Contents ||
100 0 : ContainedElement != rRight.ContainedElement ||
101 0 : SubStyles.size() != rRight.SubStyles.size()
102 : )
103 0 : return false;
104 0 : for( unsigned int n = 0; n < SubStyles.size(); ++n )
105 : {
106 0 : if( SubStyles[n] != rRight.SubStyles[n] )
107 0 : return false;
108 : }
109 0 : return true;
110 : }
111 : };
112 :
113 : struct StyleHash;
114 : friend struct StyleHash;
115 : struct StyleHash
116 : {
117 0 : size_t operator()( const StyleContainer::HashedStyle& rStyle ) const
118 : {
119 0 : return rStyle.hashCode();
120 : }
121 : };
122 :
123 : struct StyleIdNameSort;
124 : friend struct StyleIdNameSort;
125 : struct StyleIdNameSort
126 : {
127 : const boost::unordered_map< sal_Int32, HashedStyle >* m_pMap;
128 :
129 0 : StyleIdNameSort( const boost::unordered_map< sal_Int32, HashedStyle >* pMap ) :
130 0 : m_pMap(pMap)
131 0 : {}
132 0 : bool operator()( sal_Int32 nLeft, sal_Int32 nRight )
133 : {
134 : const boost::unordered_map< sal_Int32, HashedStyle >::const_iterator left_it =
135 0 : m_pMap->find( nLeft );
136 : const boost::unordered_map< sal_Int32, HashedStyle >::const_iterator right_it =
137 0 : m_pMap->find( nRight );
138 0 : if( left_it == m_pMap->end() )
139 0 : return false;
140 0 : else if( right_it == m_pMap->end() )
141 0 : return true;
142 : else
143 0 : return left_it->second.Name < right_it->second.Name;
144 : }
145 : };
146 :
147 : sal_Int32 m_nNextId;
148 : boost::unordered_map< sal_Int32, HashedStyle > m_aIdToStyle;
149 : boost::unordered_map< HashedStyle, sal_Int32, StyleHash > m_aStyleToId;
150 :
151 : void impl_emitStyle( sal_Int32 nStyleId,
152 : EmitContext& rContext,
153 : ElementTreeVisitor& rContainedElemVisitor );
154 :
155 : public:
156 : StyleContainer();
157 :
158 : void emit( EmitContext& rContext,
159 : ElementTreeVisitor& rContainedElemVisitor );
160 :
161 : sal_Int32 impl_getStyleId( const Style& rStyle, bool bSubStyle );
162 0 : sal_Int32 getStyleId( const Style& rStyle )
163 0 : { return impl_getStyleId( rStyle, false ); }
164 : sal_Int32 getStandardStyleId( const OString& rFamily );
165 :
166 : // returns NULL for an invalid style id
167 : const PropertyMap* getProperties( sal_Int32 nStyleId ) const;
168 : sal_Int32 setProperties( sal_Int32 nStyleId, const PropertyMap &rNewProps );
169 : OUString getStyleName( sal_Int32 nStyle ) const;
170 : };
171 : }
172 :
173 : #endif
174 :
175 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|