191c99ff4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
391c99ff4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
491c99ff4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
591c99ff4SAndrew Rist  * distributed with this work for additional information
691c99ff4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
791c99ff4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
891c99ff4SAndrew Rist  * "License"); you may not use this file except in compliance
991c99ff4SAndrew Rist  * with the License.  You may obtain a copy of the License at
1091c99ff4SAndrew Rist  *
1191c99ff4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1291c99ff4SAndrew Rist  *
1391c99ff4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1491c99ff4SAndrew Rist  * software distributed under the License is distributed on an
1591c99ff4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1691c99ff4SAndrew Rist  * KIND, either express or implied.  See the License for the
1791c99ff4SAndrew Rist  * specific language governing permissions and limitations
1891c99ff4SAndrew Rist  * under the License.
1991c99ff4SAndrew Rist  *
2091c99ff4SAndrew Rist  *************************************************************/
2191c99ff4SAndrew Rist 
2291c99ff4SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef INCLUDED_CANVAS_SPRITEREDRAWMANAGER_HXX
25cdf0e10cSrcweir #define INCLUDED_CANVAS_SPRITEREDRAWMANAGER_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <basegfx/range/b2dconnectedranges.hxx>
28cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
29cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx>
30cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
31cdf0e10cSrcweir #include <basegfx/range/b2irange.hxx>
32cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
33cdf0e10cSrcweir #include <canvas/base/spritesurface.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <list>
36cdf0e10cSrcweir #include <vector>
37cdf0e10cSrcweir #include <algorithm>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include <boost/utility.hpp>
40cdf0e10cSrcweir #include <boost/bind.hpp>
41cdf0e10cSrcweir 
42*b63233d8Sdamjan #include <canvas/canvastoolsdllapi.h>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir /* Definition of SpriteRedrawManager class */
45cdf0e10cSrcweir 
46cdf0e10cSrcweir namespace canvas
47cdf0e10cSrcweir {
48cdf0e10cSrcweir     /** This class manages smooth SpriteCanvas updates
49cdf0e10cSrcweir 
50cdf0e10cSrcweir     	Use this class to handle the ::canvas::SpriteSurface methods,
51cdf0e10cSrcweir     	that track and process sprite update events. Recorded update
52cdf0e10cSrcweir     	events are later grouped by connected areas (i.e. all sprites
53cdf0e10cSrcweir     	that somehow overlap over a rectangular area are grouped
54cdf0e10cSrcweir     	together); the forEachSpriteArea() method calls the passed
55cdf0e10cSrcweir     	functor for each of those connected areas.
56cdf0e10cSrcweir 
57cdf0e10cSrcweir         Note that, although this class generally works with IEEE
58cdf0e10cSrcweir         doubles, the calculation of connected areas happens in the
59cdf0e10cSrcweir         integer domain - it is generally expected that repaints can
60cdf0e10cSrcweir         only be divided at pixel boundaries, without causing visible
61cdf0e10cSrcweir         artifacts. Therefore, sprites that touch the same pixel (but
62cdf0e10cSrcweir         don't necessarily have the same floating point coordinates
63cdf0e10cSrcweir         there) will reside in a common sprite area and handled
64cdf0e10cSrcweir         together in the forEachSpriteArea functor call.
65cdf0e10cSrcweir      */
66*b63233d8Sdamjan     class CANVASTOOLS_DLLPUBLIC SpriteRedrawManager : private ::boost::noncopyable
67cdf0e10cSrcweir     {
68cdf0e10cSrcweir     public:
69cdf0e10cSrcweir         /** Data container for the connected components list
70cdf0e10cSrcweir          */
71cdf0e10cSrcweir         class SpriteInfo
72cdf0e10cSrcweir         {
73cdf0e10cSrcweir         public:
~SpriteInfo()74cdf0e10cSrcweir 			~SpriteInfo() {}
75cdf0e10cSrcweir 
76cdf0e10cSrcweir             /** Create sprite info
77cdf0e10cSrcweir 
78cdf0e10cSrcweir             	@param rRef
79cdf0e10cSrcweir                 Sprite this info represents (might be the NULL ref)
80cdf0e10cSrcweir 
81cdf0e10cSrcweir                 @param rTrueUpdateArea
82cdf0e10cSrcweir                 True (un-rounded) update area this sprite has recorded
83cdf0e10cSrcweir 
84cdf0e10cSrcweir                 @param bNeedsUpdate
85cdf0e10cSrcweir                 When false, this sprite is not a member of the change
86cdf0e10cSrcweir                 record list. Thus, it only needs redraw if within the
87cdf0e10cSrcweir                 update area of other, changed sprites.
88cdf0e10cSrcweir 
89cdf0e10cSrcweir                 @internal
90cdf0e10cSrcweir              */
SpriteInfo(const Sprite::Reference & rRef,const::basegfx::B2DRange & rTrueUpdateArea,bool bNeedsUpdate)91cdf0e10cSrcweir             SpriteInfo( const Sprite::Reference& 	rRef,
92cdf0e10cSrcweir                         const ::basegfx::B2DRange&	rTrueUpdateArea,
93cdf0e10cSrcweir                         bool 					 	bNeedsUpdate ) :
94cdf0e10cSrcweir                 mpSprite( rRef ),
95cdf0e10cSrcweir                 maTrueUpdateArea( rTrueUpdateArea ),
96cdf0e10cSrcweir                 mbNeedsUpdate( bNeedsUpdate ),
97cdf0e10cSrcweir                 mbIsPureMove( false )
98cdf0e10cSrcweir             {
99cdf0e10cSrcweir             }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir             /** Create sprite info, specify move type
102cdf0e10cSrcweir 
103cdf0e10cSrcweir             	@param rRef
104cdf0e10cSrcweir                 Sprite this info represents (might be the NULL ref)
105cdf0e10cSrcweir 
106cdf0e10cSrcweir                 @param rTrueUpdateArea
107cdf0e10cSrcweir                 True (un-rounded) update area this sprite has recorded
108cdf0e10cSrcweir 
109cdf0e10cSrcweir                 @param bNeedsUpdate
110cdf0e10cSrcweir                 When false, this sprite is not a member of the change
111cdf0e10cSrcweir                 record list. Thus, it only needs redraw if within the
112cdf0e10cSrcweir                 update area of other, changed sprites.
113cdf0e10cSrcweir 
114cdf0e10cSrcweir                 @param bIsPureMove
115cdf0e10cSrcweir                 When true, this sprite is _only_ moved, no other
116cdf0e10cSrcweir                 changes happened.
117cdf0e10cSrcweir 
118cdf0e10cSrcweir                 @internal
119cdf0e10cSrcweir              */
SpriteInfo(const Sprite::Reference & rRef,const::basegfx::B2DRange & rTrueUpdateArea,bool bNeedsUpdate,bool bIsPureMove)120cdf0e10cSrcweir             SpriteInfo( const Sprite::Reference& 	rRef,
121cdf0e10cSrcweir                         const ::basegfx::B2DRange&	rTrueUpdateArea,
122cdf0e10cSrcweir                         bool 					 	bNeedsUpdate,
123cdf0e10cSrcweir                         bool 					 	bIsPureMove ) :
124cdf0e10cSrcweir                 mpSprite( rRef ),
125cdf0e10cSrcweir                 maTrueUpdateArea( rTrueUpdateArea ),
126cdf0e10cSrcweir                 mbNeedsUpdate( bNeedsUpdate ),
127cdf0e10cSrcweir                 mbIsPureMove( bIsPureMove )
128cdf0e10cSrcweir             {
129cdf0e10cSrcweir             }
130cdf0e10cSrcweir 
getSprite() const131cdf0e10cSrcweir             const Sprite::Reference&	getSprite() const { return mpSprite; }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir             // #i61843# need to return by value here, to be used safely from bind
getUpdateArea() const134cdf0e10cSrcweir             ::basegfx::B2DRange         getUpdateArea() const { return maTrueUpdateArea; }
needsUpdate() const135cdf0e10cSrcweir             bool						needsUpdate() const { return mbNeedsUpdate; }
isPureMove() const136cdf0e10cSrcweir             bool						isPureMove() const { return mbIsPureMove; }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir         private:
139cdf0e10cSrcweir             Sprite::Reference 		mpSprite;
140cdf0e10cSrcweir             ::basegfx::B2DRange		maTrueUpdateArea;
141cdf0e10cSrcweir             bool					mbNeedsUpdate;
142cdf0e10cSrcweir             bool 					mbIsPureMove;
143cdf0e10cSrcweir         };
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 
146cdf0e10cSrcweir         /** Helper struct for SpriteTracer template
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         	This struct stores change information to a sprite's visual
149cdf0e10cSrcweir         	appearance (move, content updated, and the like).
150cdf0e10cSrcweir          */
151cdf0e10cSrcweir         struct SpriteChangeRecord
152cdf0e10cSrcweir         {
153cdf0e10cSrcweir             typedef enum{ none=0, move, update } ChangeType;
154cdf0e10cSrcweir 
SpriteChangeRecordcanvas::SpriteRedrawManager::SpriteChangeRecord155cdf0e10cSrcweir             SpriteChangeRecord() :
156cdf0e10cSrcweir                 meChangeType( none ),
157cdf0e10cSrcweir                 mpAffectedSprite(),
158cdf0e10cSrcweir                 maOldPos(),
159cdf0e10cSrcweir                 maUpdateArea()
160cdf0e10cSrcweir             {
161cdf0e10cSrcweir             }
162cdf0e10cSrcweir 
SpriteChangeRecordcanvas::SpriteRedrawManager::SpriteChangeRecord163cdf0e10cSrcweir             SpriteChangeRecord( const Sprite::Reference&	rSprite,
164cdf0e10cSrcweir                                 const ::basegfx::B2DPoint& 	rOldPos,
165cdf0e10cSrcweir                                 const ::basegfx::B2DPoint& 	rNewPos,
166cdf0e10cSrcweir                                 const ::basegfx::B2DVector&	rSpriteSize ) :
167cdf0e10cSrcweir                 meChangeType( move ),
168cdf0e10cSrcweir                 mpAffectedSprite( rSprite ),
169cdf0e10cSrcweir                 maOldPos( rOldPos ),
170cdf0e10cSrcweir                 maUpdateArea( rNewPos.getX(),
171cdf0e10cSrcweir                               rNewPos.getY(),
172cdf0e10cSrcweir                               rNewPos.getX() + rSpriteSize.getX(),
173cdf0e10cSrcweir                               rNewPos.getY() + rSpriteSize.getY() )
174cdf0e10cSrcweir             {
175cdf0e10cSrcweir             }
176cdf0e10cSrcweir 
SpriteChangeRecordcanvas::SpriteRedrawManager::SpriteChangeRecord177cdf0e10cSrcweir             SpriteChangeRecord( const Sprite::Reference&	rSprite,
178cdf0e10cSrcweir                                 const ::basegfx::B2DPoint& 	rPos,
179cdf0e10cSrcweir                                 const ::basegfx::B2DRange& 	rUpdateArea ) :
180cdf0e10cSrcweir                 meChangeType( update ),
181cdf0e10cSrcweir                 mpAffectedSprite( rSprite ),
182cdf0e10cSrcweir                 maOldPos( rPos ),
183cdf0e10cSrcweir                 maUpdateArea( rUpdateArea )
184cdf0e10cSrcweir             {
185cdf0e10cSrcweir             }
186cdf0e10cSrcweir 
getSpritecanvas::SpriteRedrawManager::SpriteChangeRecord187cdf0e10cSrcweir             Sprite::Reference getSprite() const { return mpAffectedSprite; }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir             ChangeType			meChangeType;
190cdf0e10cSrcweir             Sprite::Reference	mpAffectedSprite;
191cdf0e10cSrcweir             ::basegfx::B2DPoint	maOldPos;
192cdf0e10cSrcweir             ::basegfx::B2DRange	maUpdateArea;
193cdf0e10cSrcweir         };
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         typedef ::std::vector< SpriteChangeRecord > 			VectorOfChangeRecords;
196cdf0e10cSrcweir         typedef ::std::list< Sprite::Reference > 				ListOfSprites;
197cdf0e10cSrcweir         typedef ::basegfx::B2DConnectedRanges< SpriteInfo >		SpriteConnectedRanges;
198cdf0e10cSrcweir         typedef SpriteConnectedRanges::ComponentType			AreaComponent;
199cdf0e10cSrcweir         typedef SpriteConnectedRanges::ConnectedComponents		UpdateArea;
200cdf0e10cSrcweir         typedef ::std::vector< Sprite::Reference >              VectorOfSprites;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir         SpriteRedrawManager();
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         /** Must be called when user of this object gets
205cdf0e10cSrcweir             disposed. Frees all internal references.
206cdf0e10cSrcweir          */
207cdf0e10cSrcweir         void disposing();
208cdf0e10cSrcweir 
209cdf0e10cSrcweir         /** Functor, to be used from forEachSpriteArea
210cdf0e10cSrcweir          */
211cdf0e10cSrcweir         template< typename Functor > struct AreaUpdateCaller
212cdf0e10cSrcweir         {
AreaUpdateCallercanvas::SpriteRedrawManager::AreaUpdateCaller213cdf0e10cSrcweir             AreaUpdateCaller( Functor& 						rFunc,
214cdf0e10cSrcweir                               const SpriteRedrawManager&	rManager ) :
215cdf0e10cSrcweir                 mrFunc( rFunc ),
216cdf0e10cSrcweir                 mrManager( rManager )
217cdf0e10cSrcweir             {
218cdf0e10cSrcweir             }
219cdf0e10cSrcweir 
operator ()canvas::SpriteRedrawManager::AreaUpdateCaller220cdf0e10cSrcweir             void operator()( const UpdateArea& rUpdateArea )
221cdf0e10cSrcweir             {
222cdf0e10cSrcweir                 mrManager.handleArea( mrFunc, rUpdateArea );
223cdf0e10cSrcweir             }
224cdf0e10cSrcweir 
225cdf0e10cSrcweir             Functor& 					mrFunc;
226cdf0e10cSrcweir             const SpriteRedrawManager&	mrManager;
227cdf0e10cSrcweir         };
228cdf0e10cSrcweir 
229cdf0e10cSrcweir         /** Call given functor for each sprite area that needs an
230cdf0e10cSrcweir             update.
231cdf0e10cSrcweir 
232cdf0e10cSrcweir         	This method calls the given functor for each update area
233cdf0e10cSrcweir         	(calculated from the sprite change records).
234cdf0e10cSrcweir 
235cdf0e10cSrcweir             @tpl Functor
236cdf0e10cSrcweir             Must provide the following four methods:
237cdf0e10cSrcweir             <pre>
238cdf0e10cSrcweir             void backgroundPaint( ::basegfx::B2DRange aUpdateRect );
239cdf0e10cSrcweir             void scrollUpdate( ::basegfx::B2DRange& o_rMoveStart,
240cdf0e10cSrcweir             				   ::basegfx::B2DRange& o_rMoveEnd,
241cdf0e10cSrcweir                                UpdateArea 		  	aUpdateArea );
242cdf0e10cSrcweir             void opaqueUpdate( const ::basegfx::B2DRange&                          rTotalArea,
243cdf0e10cSrcweir                                const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites );
244cdf0e10cSrcweir             void genericUpdate( const ::basegfx::B2DRange&                          rTotalArea,
245cdf0e10cSrcweir                                 const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites );
246cdf0e10cSrcweir             </pre>
247cdf0e10cSrcweir             The backgroundPaint() method is called to simply repaint
248cdf0e10cSrcweir             background content, the scrollUpdate() method is used to
249cdf0e10cSrcweir             scroll a given area, and paint background in the uncovered
250cdf0e10cSrcweir             areas, the opaqueUpdate() method is called when a sprite
251cdf0e10cSrcweir             can be painted in the given area without taking background
252cdf0e10cSrcweir             content into account, and finally, genericUpdate() is
253cdf0e10cSrcweir             called for complex updates, where first the background and
254cdf0e10cSrcweir             then all sprites consecutively have to be repainted.
255cdf0e10cSrcweir          */
forEachSpriteArea(Functor & rFunc) const256cdf0e10cSrcweir         template< typename Functor > void forEachSpriteArea( Functor& rFunc ) const
257cdf0e10cSrcweir         {
258cdf0e10cSrcweir             SpriteConnectedRanges aUpdateAreas;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir             setupUpdateAreas( aUpdateAreas );
261cdf0e10cSrcweir 
262cdf0e10cSrcweir             aUpdateAreas.forEachAggregate(
263cdf0e10cSrcweir                 AreaUpdateCaller< Functor >( rFunc, *this ) );
264cdf0e10cSrcweir         }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir         /** Call given functor for each active sprite.
267cdf0e10cSrcweir 
268cdf0e10cSrcweir         	This method calls the given functor for each active
269cdf0e10cSrcweir         	sprite, in the order of sprite priority.
270cdf0e10cSrcweir 
271cdf0e10cSrcweir             @tpl Functor
272cdf0e10cSrcweir             Must provide a Functor::operator( Sprite::Reference& )
273cdf0e10cSrcweir             method.
274cdf0e10cSrcweir          */
forEachSprite(const Functor & rFunc) const275cdf0e10cSrcweir         template< typename Functor > void forEachSprite( const Functor& rFunc ) const
276cdf0e10cSrcweir         {
277cdf0e10cSrcweir             ::std::for_each( maSprites.begin(),
278cdf0e10cSrcweir                              maSprites.end(),
279cdf0e10cSrcweir                              rFunc );
280cdf0e10cSrcweir         }
281cdf0e10cSrcweir 
282cdf0e10cSrcweir         /// Clear sprite change records (typically directly after a screen update)
283cdf0e10cSrcweir         void clearChangeRecords();
284cdf0e10cSrcweir 
285cdf0e10cSrcweir         // SpriteSurface interface, is delegated to e.g. from SpriteCanvas
286cdf0e10cSrcweir         void showSprite( const Sprite::Reference& rSprite );
287cdf0e10cSrcweir         void hideSprite( const Sprite::Reference& rSprite );
288cdf0e10cSrcweir         void moveSprite( const Sprite::Reference&		rSprite,
289cdf0e10cSrcweir                          const ::basegfx::B2DPoint& 	rOldPos,
290cdf0e10cSrcweir                          const ::basegfx::B2DPoint&		rNewPos,
291cdf0e10cSrcweir                          const ::basegfx::B2DVector& 	rSpriteSize );
292cdf0e10cSrcweir         void updateSprite( const Sprite::Reference& 	rSprite,
293cdf0e10cSrcweir                            const ::basegfx::B2DPoint& 	rPos,
294cdf0e10cSrcweir                            const ::basegfx::B2DRange&	rUpdateArea );
295cdf0e10cSrcweir 
296cdf0e10cSrcweir         /** Internal, handles each distinct component for forEachAggregate()
297cdf0e10cSrcweir 
298cdf0e10cSrcweir             The reason why this must be public is that it needs to be
299cdf0e10cSrcweir             accessible from the AreaUpdateCaller functor.
300cdf0e10cSrcweir 
301cdf0e10cSrcweir             @internal
302cdf0e10cSrcweir          */
handleArea(Functor & rFunc,const UpdateArea & rUpdateArea) const303cdf0e10cSrcweir         template< typename Functor > void handleArea( Functor& 			rFunc,
304cdf0e10cSrcweir                                                       const UpdateArea&	rUpdateArea ) const
305cdf0e10cSrcweir         {
306cdf0e10cSrcweir             // check whether this area contains changed sprites at all
307cdf0e10cSrcweir             // (if not, just ignore it)
308cdf0e10cSrcweir             if( areSpritesChanged( rUpdateArea ) )
309cdf0e10cSrcweir             {
310cdf0e10cSrcweir                 // at least one of the sprites actually needs an
311cdf0e10cSrcweir                 // update - process whole area.
312cdf0e10cSrcweir 
313cdf0e10cSrcweir                 // check whether this area could be handled special
314cdf0e10cSrcweir                 // (background paint, direct update, scroll, etc.)
315cdf0e10cSrcweir                 ::basegfx::B2DRange aMoveStart;
316cdf0e10cSrcweir                 ::basegfx::B2DRange aMoveEnd;
317cdf0e10cSrcweir                 if( rUpdateArea.maComponentList.empty() )
318cdf0e10cSrcweir                 {
319cdf0e10cSrcweir                     rFunc.backgroundPaint( rUpdateArea.maTotalBounds );
320cdf0e10cSrcweir                 }
321cdf0e10cSrcweir                 else
322cdf0e10cSrcweir                 {
323cdf0e10cSrcweir                     // cache number of sprites in this area (it's a
324cdf0e10cSrcweir                     // list, and both isAreaUpdateScroll() and
325cdf0e10cSrcweir                     // isAreaUpdateOpaque() need it).
326cdf0e10cSrcweir                     const ::std::size_t nNumSprites(
327cdf0e10cSrcweir                         rUpdateArea.maComponentList.size() );
328cdf0e10cSrcweir 
329cdf0e10cSrcweir                     if( isAreaUpdateScroll( aMoveStart,
330cdf0e10cSrcweir                                             aMoveEnd,
331cdf0e10cSrcweir                                             rUpdateArea,
332cdf0e10cSrcweir                                             nNumSprites ) )
333cdf0e10cSrcweir                     {
334cdf0e10cSrcweir                         rFunc.scrollUpdate( aMoveStart,
335cdf0e10cSrcweir                                             aMoveEnd,
336cdf0e10cSrcweir                                             rUpdateArea );
337cdf0e10cSrcweir                     }
338cdf0e10cSrcweir                     else
339cdf0e10cSrcweir                     {
340cdf0e10cSrcweir                         // potentially, more than a single sprite
341cdf0e10cSrcweir                         // involved. Have to sort component lists for
342cdf0e10cSrcweir                         // sprite prio.
343cdf0e10cSrcweir                         VectorOfSprites aSortedUpdateSprites;
344cdf0e10cSrcweir                         SpriteConnectedRanges::ComponentListType::const_iterator aCurr(
345cdf0e10cSrcweir                             rUpdateArea.maComponentList.begin() );
346cdf0e10cSrcweir                         const SpriteConnectedRanges::ComponentListType::const_iterator aEnd(
347cdf0e10cSrcweir                             rUpdateArea.maComponentList.end() );
348cdf0e10cSrcweir                         while( aCurr != aEnd )
349cdf0e10cSrcweir                         {
350cdf0e10cSrcweir                             const Sprite::Reference& rSprite( aCurr->second.getSprite() );
351cdf0e10cSrcweir                             if( rSprite.is() )
352cdf0e10cSrcweir                                 aSortedUpdateSprites.push_back( rSprite );
353cdf0e10cSrcweir 
354cdf0e10cSrcweir                             ++aCurr;
355cdf0e10cSrcweir                         }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir                         ::std::sort( aSortedUpdateSprites.begin(),
358cdf0e10cSrcweir                                      aSortedUpdateSprites.end(),
359cdf0e10cSrcweir                                      SpriteComparator() );
360cdf0e10cSrcweir 
361cdf0e10cSrcweir                         if( isAreaUpdateOpaque( rUpdateArea,
362cdf0e10cSrcweir                                                 nNumSprites ) )
363cdf0e10cSrcweir                         {
364cdf0e10cSrcweir                             rFunc.opaqueUpdate( rUpdateArea.maTotalBounds,
365cdf0e10cSrcweir                                                 aSortedUpdateSprites );
366cdf0e10cSrcweir                         }
367cdf0e10cSrcweir                         else
368cdf0e10cSrcweir                         {
369cdf0e10cSrcweir                             rFunc.genericUpdate( rUpdateArea.maTotalBounds,
370cdf0e10cSrcweir                                                  aSortedUpdateSprites );
371cdf0e10cSrcweir                         }
372cdf0e10cSrcweir                     }
373cdf0e10cSrcweir                 }
374cdf0e10cSrcweir             }
375cdf0e10cSrcweir         }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir     private:
378cdf0e10cSrcweir         /** Central method of this class. Calculates the set of
379cdf0e10cSrcweir             disjunct components that need an update.
380cdf0e10cSrcweir          */
381cdf0e10cSrcweir         void setupUpdateAreas( SpriteConnectedRanges& rUpdateAreas ) const;
382cdf0e10cSrcweir 
383cdf0e10cSrcweir         bool areSpritesChanged( const UpdateArea& rUpdateArea ) const;
384cdf0e10cSrcweir 
385cdf0e10cSrcweir         bool isAreaUpdateNotOpaque( const ::basegfx::B2DRange&	rUpdateRect,
386cdf0e10cSrcweir                                     const AreaComponent&		rComponent ) const;
387cdf0e10cSrcweir 
388cdf0e10cSrcweir         bool isAreaUpdateOpaque( const UpdateArea&	rUpdateArea,
389cdf0e10cSrcweir                                  ::std::size_t		nNumSprites ) const;
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         /** Check whether given update area can be handled by a simple
392cdf0e10cSrcweir             scroll
393cdf0e10cSrcweir 
394cdf0e10cSrcweir             @param o_rMoveStart
395cdf0e10cSrcweir             Start rect of the move
396cdf0e10cSrcweir 
397cdf0e10cSrcweir             @param o_rMoveEnd
398cdf0e10cSrcweir             End rect of the move. The content must be moved from start
399cdf0e10cSrcweir             to end rect
400cdf0e10cSrcweir 
401cdf0e10cSrcweir             @param rUpdateArea
402cdf0e10cSrcweir             Area to check for scroll update optimization
403cdf0e10cSrcweir          */
404cdf0e10cSrcweir         bool isAreaUpdateScroll( ::basegfx::B2DRange& 	o_rMoveStart,
405cdf0e10cSrcweir                                  ::basegfx::B2DRange& 	o_rMoveEnd,
406cdf0e10cSrcweir                                  const UpdateArea& 		rUpdateArea,
407cdf0e10cSrcweir                                  ::std::size_t			nNumSprites ) const;
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 
410cdf0e10cSrcweir         ListOfSprites					maSprites; // list of active
411cdf0e10cSrcweir             		                        	   // sprite
412cdf0e10cSrcweir             		                        	   // objects. this
413cdf0e10cSrcweir             		                        	   // list is only
414cdf0e10cSrcweir             		                        	   // used for full
415cdf0e10cSrcweir             		                        	   // repaints,
416cdf0e10cSrcweir             		                        	   // otherwise, we
417cdf0e10cSrcweir             		                        	   // rely on the
418cdf0e10cSrcweir             		                        	   // active sprites
419cdf0e10cSrcweir             		                        	   // itself to notify
420cdf0e10cSrcweir             		                        	   // us.
421cdf0e10cSrcweir 
422cdf0e10cSrcweir         VectorOfChangeRecords			maChangeRecords; // vector of
423cdf0e10cSrcweir                                                     	 // sprites
424cdf0e10cSrcweir                                                     	 // changes
425cdf0e10cSrcweir                                                     	 // since last
426cdf0e10cSrcweir                                                     	 // updateScreen()
427cdf0e10cSrcweir                                                     	 // call
428cdf0e10cSrcweir     };
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir #endif /* INCLUDED_CANVAS_SPRITEREDRAWMANAGER_HXX */
432