LCOV - code coverage report
Current view: top level - solver/unxlngi6.pro/inc/canvas - spriteredrawmanager.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 58 0.0 %
Date: 2012-08-25 Functions: 0 26 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 2 0.0 %

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

Generated by: LCOV version 1.10