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