fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / include / canvas / spriteredrawmanager.hxx
blob7609b4f8f4a6c542eedbc63dcd498fc5b30b4eef
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_CANVAS_SPRITEREDRAWMANAGER_HXX
21 #define INCLUDED_CANVAS_SPRITEREDRAWMANAGER_HXX
23 #include <basegfx/range/b2dconnectedranges.hxx>
24 #include <basegfx/point/b2dpoint.hxx>
25 #include <basegfx/vector/b2dvector.hxx>
26 #include <basegfx/range/b2drange.hxx>
27 #include <basegfx/range/b2irange.hxx>
28 #include <basegfx/matrix/b2dhommatrix.hxx>
29 #include <canvas/base/spritesurface.hxx>
31 #include <list>
32 #include <vector>
33 #include <algorithm>
35 #include <boost/utility.hpp>
36 #include <boost/bind.hpp>
38 #include <canvas/canvastoolsdllapi.h>
40 /* Definition of SpriteRedrawManager class */
42 namespace canvas
44 /** This class manages smooth SpriteCanvas updates
46 Use this class to handle the ::canvas::SpriteSurface methods,
47 that track and process sprite update events. Recorded update
48 events are later grouped by connected areas (i.e. all sprites
49 that somehow overlap over a rectangular area are grouped
50 together); the forEachSpriteArea() method calls the passed
51 functor for each of those connected areas.
53 Note that, although this class generally works with IEEE
54 doubles, the calculation of connected areas happens in the
55 integer domain - it is generally expected that repaints can
56 only be divided at pixel boundaries, without causing visible
57 artifacts. Therefore, sprites that touch the same pixel (but
58 don't necessarily have the same floating point coordinates
59 there) will reside in a common sprite area and handled
60 together in the forEachSpriteArea functor call.
62 class CANVASTOOLS_DLLPUBLIC SpriteRedrawManager : private ::boost::noncopyable
64 public:
65 /** Data container for the connected components list
67 class SpriteInfo
69 public:
70 ~SpriteInfo() {}
72 /** Create sprite info
74 @param rRef
75 Sprite this info represents (might be the NULL ref)
77 @param rTrueUpdateArea
78 True (un-rounded) update area this sprite has recorded
80 @param bNeedsUpdate
81 When false, this sprite is not a member of the change
82 record list. Thus, it only needs redraw if within the
83 update area of other, changed sprites.
85 @internal
87 SpriteInfo( const Sprite::Reference& rRef,
88 const ::basegfx::B2DRange& rTrueUpdateArea,
89 bool bNeedsUpdate ) :
90 mpSprite( rRef ),
91 maTrueUpdateArea( rTrueUpdateArea ),
92 mbNeedsUpdate( bNeedsUpdate ),
93 mbIsPureMove( false )
97 /** Create sprite info, specify move type
99 @param rRef
100 Sprite this info represents (might be the NULL ref)
102 @param rTrueUpdateArea
103 True (un-rounded) update area this sprite has recorded
105 @param bNeedsUpdate
106 When false, this sprite is not a member of the change
107 record list. Thus, it only needs redraw if within the
108 update area of other, changed sprites.
110 @param bIsPureMove
111 When true, this sprite is _only_ moved, no other
112 changes happened.
114 @internal
116 SpriteInfo( const Sprite::Reference& rRef,
117 const ::basegfx::B2DRange& rTrueUpdateArea,
118 bool bNeedsUpdate,
119 bool bIsPureMove ) :
120 mpSprite( rRef ),
121 maTrueUpdateArea( rTrueUpdateArea ),
122 mbNeedsUpdate( bNeedsUpdate ),
123 mbIsPureMove( bIsPureMove )
127 const Sprite::Reference& getSprite() const { return mpSprite; }
129 // #i61843# need to return by value here, to be used safely from bind
130 ::basegfx::B2DRange getUpdateArea() const { return maTrueUpdateArea; }
131 bool needsUpdate() const { return mbNeedsUpdate; }
132 bool isPureMove() const { return mbIsPureMove; }
134 private:
135 Sprite::Reference mpSprite;
136 ::basegfx::B2DRange maTrueUpdateArea;
137 bool mbNeedsUpdate;
138 bool mbIsPureMove;
142 /** Helper struct for SpriteTracer template
144 This struct stores change information to a sprite's visual
145 appearance (move, content updated, and the like).
147 struct SpriteChangeRecord
149 typedef enum{ none=0, move, update } ChangeType;
151 SpriteChangeRecord() :
152 meChangeType( none ),
153 mpAffectedSprite(),
154 maOldPos(),
155 maUpdateArea()
159 SpriteChangeRecord( const Sprite::Reference& rSprite,
160 const ::basegfx::B2DPoint& rOldPos,
161 const ::basegfx::B2DPoint& rNewPos,
162 const ::basegfx::B2DVector& rSpriteSize ) :
163 meChangeType( move ),
164 mpAffectedSprite( rSprite ),
165 maOldPos( rOldPos ),
166 maUpdateArea( rNewPos.getX(),
167 rNewPos.getY(),
168 rNewPos.getX() + rSpriteSize.getX(),
169 rNewPos.getY() + rSpriteSize.getY() )
173 SpriteChangeRecord( const Sprite::Reference& rSprite,
174 const ::basegfx::B2DPoint& rPos,
175 const ::basegfx::B2DRange& rUpdateArea ) :
176 meChangeType( update ),
177 mpAffectedSprite( rSprite ),
178 maOldPos( rPos ),
179 maUpdateArea( rUpdateArea )
183 Sprite::Reference getSprite() const { return mpAffectedSprite; }
185 ChangeType meChangeType;
186 Sprite::Reference mpAffectedSprite;
187 ::basegfx::B2DPoint maOldPos;
188 ::basegfx::B2DRange maUpdateArea;
191 typedef ::std::vector< SpriteChangeRecord > VectorOfChangeRecords;
192 typedef ::std::list< Sprite::Reference > ListOfSprites;
193 typedef ::basegfx::B2DConnectedRanges< SpriteInfo > SpriteConnectedRanges;
194 typedef SpriteConnectedRanges::ComponentType AreaComponent;
195 typedef SpriteConnectedRanges::ConnectedComponents UpdateArea;
196 typedef ::std::vector< Sprite::Reference > VectorOfSprites;
198 SpriteRedrawManager();
200 /** Must be called when user of this object gets
201 disposed. Frees all internal references.
203 void disposing();
205 /** Functor, to be used from forEachSpriteArea
207 template< typename Functor > struct AreaUpdateCaller
209 AreaUpdateCaller( Functor& rFunc,
210 const SpriteRedrawManager& rManager ) :
211 mrFunc( rFunc ),
212 mrManager( rManager )
216 void operator()( const UpdateArea& rUpdateArea )
218 mrManager.handleArea( mrFunc, rUpdateArea );
221 Functor& mrFunc;
222 const SpriteRedrawManager& mrManager;
225 /** Call given functor for each sprite area that needs an
226 update.
228 This method calls the given functor for each update area
229 (calculated from the sprite change records).
231 @tpl Functor
232 Must provide the following four methods:
233 <pre>
234 void backgroundPaint( ::basegfx::B2DRange aUpdateRect );
235 void scrollUpdate( ::basegfx::B2DRange& o_rMoveStart,
236 ::basegfx::B2DRange& o_rMoveEnd,
237 UpdateArea aUpdateArea );
238 void opaqueUpdate( const ::basegfx::B2DRange& rTotalArea,
239 const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites );
240 void genericUpdate( const ::basegfx::B2DRange& rTotalArea,
241 const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites );
242 </pre>
243 The backgroundPaint() method is called to simply repaint
244 background content, the scrollUpdate() method is used to
245 scroll a given area, and paint background in the uncovered
246 areas, the opaqueUpdate() method is called when a sprite
247 can be painted in the given area without taking background
248 content into account, and finally, genericUpdate() is
249 called for complex updates, where first the background and
250 then all sprites consecutively have to be repainted.
252 template< typename Functor > void forEachSpriteArea( Functor& rFunc ) const
254 SpriteConnectedRanges aUpdateAreas;
256 setupUpdateAreas( aUpdateAreas );
258 aUpdateAreas.forEachAggregate(
259 AreaUpdateCaller< Functor >( rFunc, *this ) );
262 /** Call given functor for each active sprite.
264 This method calls the given functor for each active
265 sprite, in the order of sprite priority.
267 @tpl Functor
268 Must provide a Functor::operator( Sprite::Reference& )
269 method.
271 template< typename Functor > void forEachSprite( const Functor& rFunc ) const
273 ::std::for_each( maSprites.begin(),
274 maSprites.end(),
275 rFunc );
278 /// Clear sprite change records (typically directly after a screen update)
279 void clearChangeRecords();
281 // SpriteSurface interface, is delegated to e.g. from SpriteCanvas
282 void showSprite( const Sprite::Reference& rSprite );
283 void hideSprite( const Sprite::Reference& rSprite );
284 void moveSprite( const Sprite::Reference& rSprite,
285 const ::basegfx::B2DPoint& rOldPos,
286 const ::basegfx::B2DPoint& rNewPos,
287 const ::basegfx::B2DVector& rSpriteSize );
288 void updateSprite( const Sprite::Reference& rSprite,
289 const ::basegfx::B2DPoint& rPos,
290 const ::basegfx::B2DRange& rUpdateArea );
292 /** Internal, handles each distinct component for forEachAggregate()
294 The reason why this must be public is that it needs to be
295 accessible from the AreaUpdateCaller functor.
297 @internal
299 template< typename Functor > void handleArea( Functor& rFunc,
300 const UpdateArea& rUpdateArea ) const
302 // check whether this area contains changed sprites at all
303 // (if not, just ignore it)
304 if( areSpritesChanged( rUpdateArea ) )
306 // at least one of the sprites actually needs an
307 // update - process whole area.
309 // check whether this area could be handled special
310 // (background paint, direct update, scroll, etc.)
311 ::basegfx::B2DRange aMoveStart;
312 ::basegfx::B2DRange aMoveEnd;
313 if( rUpdateArea.maComponentList.empty() )
315 rFunc.backgroundPaint( rUpdateArea.maTotalBounds );
317 else
319 // cache number of sprites in this area (it's a
320 // list, and both isAreaUpdateScroll() and
321 // isAreaUpdateOpaque() need it).
322 const ::std::size_t nNumSprites(
323 rUpdateArea.maComponentList.size() );
325 if( isAreaUpdateScroll( aMoveStart,
326 aMoveEnd,
327 rUpdateArea,
328 nNumSprites ) )
330 rFunc.scrollUpdate( aMoveStart,
331 aMoveEnd,
332 rUpdateArea );
334 else
336 // potentially, more than a single sprite
337 // involved. Have to sort component lists for
338 // sprite prio.
339 VectorOfSprites aSortedUpdateSprites;
340 SpriteConnectedRanges::ComponentListType::const_iterator aCurr(
341 rUpdateArea.maComponentList.begin() );
342 const SpriteConnectedRanges::ComponentListType::const_iterator aEnd(
343 rUpdateArea.maComponentList.end() );
344 while( aCurr != aEnd )
346 const Sprite::Reference& rSprite( aCurr->second.getSprite() );
347 if( rSprite.is() )
348 aSortedUpdateSprites.push_back( rSprite );
350 ++aCurr;
353 ::std::sort( aSortedUpdateSprites.begin(),
354 aSortedUpdateSprites.end(),
355 SpriteWeakOrder() );
357 if( isAreaUpdateOpaque( rUpdateArea,
358 nNumSprites ) )
360 rFunc.opaqueUpdate( rUpdateArea.maTotalBounds,
361 aSortedUpdateSprites );
363 else
365 rFunc.genericUpdate( rUpdateArea.maTotalBounds,
366 aSortedUpdateSprites );
373 private:
374 /** Central method of this class. Calculates the set of
375 disjunct components that need an update.
377 void setupUpdateAreas( SpriteConnectedRanges& rUpdateAreas ) const;
379 bool areSpritesChanged( const UpdateArea& rUpdateArea ) const;
381 bool isAreaUpdateNotOpaque( const ::basegfx::B2DRange& rUpdateRect,
382 const AreaComponent& rComponent ) const;
384 bool isAreaUpdateOpaque( const UpdateArea& rUpdateArea,
385 ::std::size_t nNumSprites ) const;
387 /** Check whether given update area can be handled by a simple
388 scroll
390 @param o_rMoveStart
391 Start rect of the move
393 @param o_rMoveEnd
394 End rect of the move. The content must be moved from start
395 to end rect
397 @param rUpdateArea
398 Area to check for scroll update optimization
400 bool isAreaUpdateScroll( ::basegfx::B2DRange& o_rMoveStart,
401 ::basegfx::B2DRange& o_rMoveEnd,
402 const UpdateArea& rUpdateArea,
403 ::std::size_t nNumSprites ) const;
406 ListOfSprites maSprites; // list of active
407 // sprite
408 // objects. this
409 // list is only
410 // used for full
411 // repaints,
412 // otherwise, we
413 // rely on the
414 // active sprites
415 // itself to notify
416 // us.
418 VectorOfChangeRecords maChangeRecords; // vector of
419 // sprites
420 // changes
421 // since last
422 // updateScreen()
423 // call
427 #endif /* INCLUDED_CANVAS_SPRITEREDRAWMANAGER_HXX */
429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */