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