LibreOffice Module canvas (master) 1
spriteredrawmanager.hxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#pragma once
21
27
28#include <utility>
29#include <vector>
30#include <algorithm>
31
32#include "base/sprite.hxx"
34
35/* Definition of SpriteRedrawManager class */
36
37namespace canvas
38{
58 {
59 public:
63 {
64 public:
81 const ::basegfx::B2DRange& rTrueUpdateArea,
82 bool bNeedsUpdate ) :
83 mpSprite(std::move( aRef )),
84 maTrueUpdateArea( rTrueUpdateArea ),
85 mbNeedsUpdate( bNeedsUpdate ),
86 mbIsPureMove( false )
87 {
88 }
89
110 const ::basegfx::B2DRange& rTrueUpdateArea,
111 bool bNeedsUpdate,
112 bool bIsPureMove ) :
113 mpSprite(std::move( aRef )),
114 maTrueUpdateArea( rTrueUpdateArea ),
115 mbNeedsUpdate( bNeedsUpdate ),
116 mbIsPureMove( bIsPureMove )
117 {
118 }
119
120 const Sprite::Reference& getSprite() const { return mpSprite; }
121
122 // #i61843# need to return by value here, to be used safely from bind
123 const ::basegfx::B2DRange& getUpdateArea() const { return maTrueUpdateArea; }
124 bool needsUpdate() const { return mbNeedsUpdate; }
125 bool isPureMove() const { return mbIsPureMove; }
126
127 private:
132 };
133
134
141 {
142 enum class ChangeType { move, update };
143
145 const ::basegfx::B2DPoint& rOldPos,
146 const ::basegfx::B2DPoint& rNewPos,
147 const ::basegfx::B2DVector& rSpriteSize ) :
148 meChangeType( ChangeType::move ),
149 mpAffectedSprite(std::move( rSprite )),
150 maOldPos( rOldPos ),
151 maUpdateArea( rNewPos.getX(),
152 rNewPos.getY(),
153 rNewPos.getX() + rSpriteSize.getX(),
154 rNewPos.getY() + rSpriteSize.getY() )
155 {
156 }
157
159 const ::basegfx::B2DPoint& rPos,
160 const ::basegfx::B2DRange& rUpdateArea ) :
161 meChangeType( ChangeType::update ),
162 mpAffectedSprite(std::move( rSprite )),
163 maOldPos( rPos ),
164 maUpdateArea( rUpdateArea )
165 {
166 }
167
169
174 };
175
176 typedef ::std::vector< SpriteChangeRecord > VectorOfChangeRecords;
177 typedef ::basegfx::B2DConnectedRanges< SpriteInfo > SpriteConnectedRanges;
180 typedef ::std::vector< Sprite::Reference > VectorOfSprites;
181
185
189 void disposing();
190
193 template< typename Functor > struct AreaUpdateCaller
194 {
195 AreaUpdateCaller( Functor& rFunc,
196 const SpriteRedrawManager& rManager ) :
197 mrFunc( rFunc ),
198 mrManager( rManager )
199 {
200 }
201
202 void operator()( const UpdateArea& rUpdateArea )
203 {
204 mrManager.handleArea( mrFunc, rUpdateArea );
205 }
206
207 Functor& mrFunc;
209 };
210
238 template< typename Functor > void forEachSpriteArea( Functor& rFunc ) const
239 {
240 SpriteConnectedRanges aUpdateAreas;
241
242 setupUpdateAreas( aUpdateAreas );
243
244 aUpdateAreas.forEachAggregate(
245 AreaUpdateCaller< Functor >( rFunc, *this ) );
246 }
247
257 template< typename Functor > void forEachSprite( const Functor& rFunc ) const
258 {
259 ::std::for_each( maSprites.begin(),
260 maSprites.end(),
261 rFunc );
262 }
263
265 void clearChangeRecords();
266
267 // SpriteSurface interface, is delegated to e.g. from SpriteCanvas
268 void showSprite( const Sprite::Reference& rSprite );
269 void hideSprite( const Sprite::Reference& rSprite );
270 void moveSprite( const Sprite::Reference& rSprite,
271 const ::basegfx::B2DPoint& rOldPos,
272 const ::basegfx::B2DPoint& rNewPos,
273 const ::basegfx::B2DVector& rSpriteSize );
274 void updateSprite( const Sprite::Reference& rSprite,
275 const ::basegfx::B2DPoint& rPos,
276 const ::basegfx::B2DRange& rUpdateArea );
277
285 template< typename Functor > void handleArea( Functor& rFunc,
286 const UpdateArea& rUpdateArea ) const
287 {
288 // check whether this area contains changed sprites at all
289 // (if not, just ignore it)
290 if( !areSpritesChanged( rUpdateArea ) )
291 return;
292
293 // at least one of the sprites actually needs an
294 // update - process whole area.
295
296 // check whether this area could be handled special
297 // (background paint, direct update, scroll, etc.)
298 ::basegfx::B2DRange aMoveStart;
299 ::basegfx::B2DRange aMoveEnd;
300 if( rUpdateArea.maComponentList.empty() )
301 {
302 rFunc.backgroundPaint( rUpdateArea.maTotalBounds );
303 }
304 else
305 {
306 // cache number of sprites in this area (it's a
307 // list, and both isAreaUpdateScroll() and
308 // isAreaUpdateOpaque() need it).
309 const ::std::size_t nNumSprites(
310 rUpdateArea.maComponentList.size() );
311
312 if( isAreaUpdateScroll( aMoveStart,
313 aMoveEnd,
314 rUpdateArea,
315 nNumSprites ) )
316 {
317 rFunc.scrollUpdate( aMoveStart,
318 aMoveEnd,
319 rUpdateArea );
320 }
321 else
322 {
323 // potentially, more than a single sprite
324 // involved. Have to sort component lists for
325 // sprite prio.
326 VectorOfSprites aSortedUpdateSprites;
327 for (auto const& elem : rUpdateArea.maComponentList)
328 {
329 const Sprite::Reference& rSprite( elem.second.getSprite() );
330 if( rSprite.is() )
331 aSortedUpdateSprites.push_back( rSprite );
332 }
333
334 ::std::sort( aSortedUpdateSprites.begin(),
335 aSortedUpdateSprites.end(),
336 SpriteWeakOrder() );
337
338 if( isAreaUpdateOpaque( rUpdateArea,
339 nNumSprites ) )
340 {
341 rFunc.opaqueUpdate( rUpdateArea.maTotalBounds,
342 aSortedUpdateSprites );
343 }
344 else
345 {
346 rFunc.genericUpdate( rUpdateArea.maTotalBounds,
347 aSortedUpdateSprites );
348 }
349 }
350 }
351 }
352
353 private:
357 void setupUpdateAreas( SpriteConnectedRanges& rUpdateAreas ) const;
358
359 bool areSpritesChanged( const UpdateArea& rUpdateArea ) const;
360
361 bool isAreaUpdateNotOpaque( const ::basegfx::B2DRectangle& rUpdateRect,
362 const AreaComponent& rComponent ) const;
363
364 bool isAreaUpdateOpaque( const UpdateArea& rUpdateArea,
365 ::std::size_t nNumSprites ) const;
366
380 bool isAreaUpdateScroll( ::basegfx::B2DRectangle& o_rMoveStart,
381 ::basegfx::B2DRectangle& o_rMoveEnd,
382 const UpdateArea& rUpdateArea,
383 ::std::size_t nNumSprites ) const;
384
385
386 VectorOfSprites maSprites; // list of active
387 // sprite
388 // objects. this
389 // list is only
390 // used for full
391 // repaints,
392 // otherwise, we
393 // rely on the
394 // active sprites
395 // itself to notify
396 // us.
397
399 // sprites
400 // changes
401 // since last
402 // updateScreen()
403 // call
404 };
405}
406
407/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define CANVASTOOLS_DLLPUBLIC
UnaryFunctor forEachAggregate(UnaryFunctor aFunctor) const
::std::pair< B2DRange, UserData > ComponentType
Data container for the connected components list.
SpriteInfo(Sprite::Reference aRef, const ::basegfx::B2DRange &rTrueUpdateArea, bool bNeedsUpdate)
Create sprite info.
const ::basegfx::B2DRange & getUpdateArea() const
const Sprite::Reference & getSprite() const
SpriteInfo(Sprite::Reference aRef, const ::basegfx::B2DRange &rTrueUpdateArea, bool bNeedsUpdate, bool bIsPureMove)
Create sprite info, specify move type.
This class manages smooth SpriteCanvas updates.
::std::vector< SpriteChangeRecord > VectorOfChangeRecords
void forEachSpriteArea(Functor &rFunc) const
Call given functor for each sprite area that needs an update.
::basegfx::B2DConnectedRanges< SpriteInfo > SpriteConnectedRanges
void handleArea(Functor &rFunc, const UpdateArea &rUpdateArea) const
Internal, handles each distinct component for forEachAggregate()
SpriteRedrawManager & operator=(const SpriteRedrawManager &)=delete
SpriteConnectedRanges::ConnectedComponents UpdateArea
void forEachSprite(const Functor &rFunc) const
Call given functor for each active sprite.
SpriteRedrawManager(const SpriteRedrawManager &)=delete
SpriteConnectedRanges::ComponentType AreaComponent
::std::vector< Sprite::Reference > VectorOfSprites
VectorOfChangeRecords maChangeRecords
std::weak_ptr< cppcanvas::CustomSprite > mpSprite
SpriteVector maSprites
Sprite::Reference mpAffectedSprite
Functor, to be used from forEachSpriteArea.
AreaUpdateCaller(Functor &rFunc, const SpriteRedrawManager &rManager)
void operator()(const UpdateArea &rUpdateArea)
Helper struct for SpriteTracer template.
SpriteChangeRecord(Sprite::Reference rSprite, const ::basegfx::B2DPoint &rOldPos, const ::basegfx::B2DPoint &rNewPos, const ::basegfx::B2DVector &rSpriteSize)
SpriteChangeRecord(Sprite::Reference rSprite, const ::basegfx::B2DPoint &rPos, const ::basegfx::B2DRange &rUpdateArea)
Functor providing a StrictWeakOrdering for sprite references.
bool update()