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