xref: /trunk/main/slideshow/source/engine/shapes/drawshapesubsetting.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_SLIDESHOW_DRAWSHAPESUBSETTING_HXX
29 #define INCLUDED_SLIDESHOW_DRAWSHAPESUBSETTING_HXX
30 
31 #include <boost/shared_ptr.hpp>
32 #include <boost/noncopyable.hpp>
33 
34 #include "doctreenode.hxx"
35 #include "attributableshape.hxx"
36 
37 
38 class GDIMetaFile;
39 
40 namespace slideshow
41 {
42     namespace internal
43     {
44         /** This class encapsulates the subsetting aspects of a
45             DrawShape.
46          */
47         class DrawShapeSubsetting : private boost::noncopyable
48         {
49         public:
50             /** Create empty shape subset handling.
51 
52                 This method creates a subset handler which contains no
53                 subset information. All methods will return default
54                 values.
55 
56                 @param rMtf
57                 Metafile to retrieve subset info from (must have been
58                 generated with verbose text comments switched on).
59              */
60             DrawShapeSubsetting();
61 
62             /** Create new shape subset handling.
63 
64                 This method creates a subset handler which initially
65                 displays the whole shape.
66 
67                 @param rMtf
68                 Metafile to retrieve subset info from (must have been
69                 generated with verbose text comments switched on).
70              */
71             explicit DrawShapeSubsetting( const ::boost::shared_ptr< GDIMetaFile >& rMtf );
72 
73             /** Create new shape subset handling.
74 
75                 @param rShapeSubset
76                 The subset this object represents (can be empty, then
77                 denoting 'represents a whole shape')
78 
79                 @param rMtf
80                 Metafile to retrieve subset info from (must have been
81                 generated with verbose text comments switched on).
82              */
83             DrawShapeSubsetting( const DocTreeNode&                         rShapeSubset,
84                                  const ::boost::shared_ptr< GDIMetaFile >&  rMtf );
85 
86             /** Reset metafile.
87 
88                 Use this method to completely reset the
89                 ShapeSubsetting, with a new metafile. Note that any
90                 information previously set will be lost, including
91                 added subset shapes!
92 
93                 @param rMtf
94                 Metafile to retrieve subset info from (must have been
95                 generated with verbose text comments switched on).
96              */
97             void reset( const ::boost::shared_ptr< GDIMetaFile >&   rMtf );
98 
99             /** Reset metafile and subset.
100 
101                 Use this method to completely reset the
102                 ShapeSubsetting, with a new metafile and subset
103                 range. Note that any information previously set will
104                 be lost, including added subset shapes!
105 
106                 @param rShapeSubset
107                 The subset this object represents (can be empty, then
108                 denoting 'represents a whole shape')
109 
110                 @param rMtf
111                 Metafile to retrieve subset info from (must have been
112                 generated with verbose text comments switched on).
113              */
114             void reset( const DocTreeNode&                          rShapeSubset,
115                         const ::boost::shared_ptr< GDIMetaFile >&   rMtf );
116 
117 
118             // Shape subsetting methods
119             // ========================================================
120 
121             /// Return subset node for this shape
122             DocTreeNode                 getSubsetNode       () const;
123 
124             /// Return true, if any child subset shapes exist
125             bool                        hasSubsetShapes     () const;
126 
127             /// Get subset shape for given node, if any
128             AttributableShapeSharedPtr  getSubsetShape      ( const DocTreeNode& rTreeNode ) const;
129 
130             /// Add child subset shape (or increase use count, if already existent)
131             void                        addSubsetShape      ( const AttributableShapeSharedPtr& rShape );
132 
133             /** Revoke subset shape
134 
135                 This method revokes a subset shape, decrementing the
136                 use count for this subset by one. If the use count
137                 reaches zero (i.e. when the number of addSubsetShape()
138                 matches the number of revokeSubsetShape() calls for
139                 the same subset), the subset entry is removed from the
140                 internal list, and subsequent getSubsetShape() calls
141                 will return the empty pointer for this subset.
142 
143                 @return true, if the subset shape was physically
144                 removed from the list (false is returned, when nothing
145                 was removed, either because only the use count was
146                 decremented, or there was no such subset found, in the
147                 first place).
148              */
149             bool                        revokeSubsetShape   ( const AttributableShapeSharedPtr& rShape );
150 
151 
152             // Doc tree methods
153             // ========================================================
154 
155             /// Return overall number of nodes for given type
156             sal_Int32   getNumberOfTreeNodes        ( DocTreeNode::NodeType eNodeType ) const;
157 
158             /// Return tree node of given index and given type
159             DocTreeNode getTreeNode                 ( sal_Int32             nNodeIndex,
160                                                       DocTreeNode::NodeType eNodeType ) const;
161 
162             /// Return number of nodes of given type, below parent node
163             sal_Int32   getNumberOfSubsetTreeNodes  ( const DocTreeNode&    rParentNode,
164                                                       DocTreeNode::NodeType eNodeType ) const;
165 
166             /// Return tree node of given index and given type, relative to parent node
167             DocTreeNode getSubsetTreeNode           ( const DocTreeNode&    rParentNode,
168                                                       sal_Int32             nNodeIndex,
169                                                       DocTreeNode::NodeType eNodeType ) const;
170 
171             // Helper
172             // ========================================================
173 
174             /** Return a vector of currently active subsets.
175 
176                 Needed when rendering a shape, this method provides a
177                 vector of subsets currently visible (the range as
178                 returned by getEffectiveSubset(), minus the parts that
179                 are currently hidden, because displayed by child
180                 shapes).
181              */
182             const VectorOfDocTreeNodes& getActiveSubsets() const;
183 
184             /** This enum classifies each action index in the
185                 metafile.
186 
187                 Of interest are, of course, the places where
188                 structural shape and/or text elements end. The
189                 remainder of the action gets classified as 'noop'
190              */
191             enum IndexClassificator
192             {
193                 CLASS_NOOP,
194                 CLASS_SHAPE_START,
195                 CLASS_SHAPE_END,
196 
197                 CLASS_LINE_END,
198                 CLASS_PARAGRAPH_END,
199                 CLASS_SENTENCE_END,
200                 CLASS_WORD_END,
201                 CLASS_CHARACTER_CELL_END
202             };
203 
204             typedef ::std::vector< IndexClassificator > IndexClassificatorVector;
205 
206         private:
207             /** Entry for subset shape
208 
209                 This struct contains data for every subset shape
210                 generated. Note that for a given start/end action
211                 index combination, only one subset instance is
212                 generated (and reused for subsequent queries).
213              */
214             struct SubsetEntry
215             {
216                 AttributableShapeSharedPtr  mpShape;
217                 sal_Int32                   mnStartActionIndex;
218                 sal_Int32                   mnEndActionIndex;
219 
220                 /// Number of times this subset was queried, and not yet revoked
221                 int                         mnSubsetQueriedCount;
222 
223                 sal_Int32 getHashValue() const
224                 {
225                     // TODO(Q3): That's a hack. We assume that start
226                     // index will always be less than 65535 (if this
227                     // assumption is violated, hash map performance
228                     // will degrade severely)
229                     return mnStartActionIndex*SAL_MAX_INT16 + mnEndActionIndex;
230                 }
231 
232                 /// The shape set is ordered according to this method
233                 bool operator<(const SubsetEntry& rOther) const
234                 {
235                     return getHashValue() < rOther.getHashValue();
236                 }
237 
238             };
239 
240             typedef ::std::set< SubsetEntry >       ShapeSet;
241 
242             void ensureInitializedNodeTree() const;
243             void updateSubsetBounds( const SubsetEntry& rSubsetEntry );
244             void updateSubsets();
245             void initCurrentSubsets();
246             void reset();
247 
248             sal_Int32   implGetNumberOfTreeNodes( const IndexClassificatorVector::const_iterator&   rBegin,
249                                                   const IndexClassificatorVector::const_iterator&   rEnd,
250                                                   DocTreeNode::NodeType                             eNodeType ) const;
251             DocTreeNode implGetTreeNode( const IndexClassificatorVector::const_iterator&    rBegin,
252                                          const IndexClassificatorVector::const_iterator&    rEnd,
253                                          sal_Int32                                          nNodeIndex,
254                                          DocTreeNode::NodeType                              eNodeType ) const;
255 
256             mutable IndexClassificatorVector    maActionClassVector;
257 
258             /// Metafile to retrieve subset info from
259             ::boost::shared_ptr< GDIMetaFile >  mpMtf;
260 
261             /// Subset of the metafile represented by this object
262             DocTreeNode                         maSubset;
263 
264             /// the list of subset shapes spawned from this one.
265             ShapeSet                            maSubsetShapes;
266 
267             /// caches minimal subset index from maSubsetShapes
268             sal_Int32                           mnMinSubsetActionIndex;
269 
270             /// caches maximal subset index from maSubsetShapes
271             sal_Int32                           mnMaxSubsetActionIndex;
272 
273             /** Current number of subsets to render (calculated from
274                 maSubset and mnMin/MaxSubsetActionIndex).
275 
276                 Note that this is generally _not_ equivalent to
277                 maSubset, as it excludes all active subset children!
278              */
279             mutable VectorOfDocTreeNodes        maCurrentSubsets;
280 
281             /// Whether the shape's doc tree has been initialized successfully, or not
282             mutable bool                        mbNodeTreeInitialized;
283         };
284 
285     }
286 }
287 
288 #endif /* INCLUDED_SLIDESHOW_DRAWSHAPESUBSETTING_HXX */
289