LCOV - code coverage report
Current view: top level - libreoffice/slideshow/source/engine - slideview.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 338 0.0 %
Date: 2012-12-27 Functions: 0 64 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include <canvas/debug.hxx>
      21             : #include <tools/diagnose_ex.h>
      22             : #include <canvas/canvastools.hxx>
      23             : 
      24             : #include "eventqueue.hxx"
      25             : #include "eventmultiplexer.hxx"
      26             : #include "slideview.hxx"
      27             : #include "delayevent.hxx"
      28             : #include "unoview.hxx"
      29             : 
      30             : #include <rtl/instance.hxx>
      31             : #include <cppuhelper/basemutex.hxx>
      32             : #include <cppuhelper/compbase2.hxx>
      33             : #include <cppuhelper/implementationentry.hxx>
      34             : #include <cppuhelper/interfacecontainer.h>
      35             : #include <comphelper/make_shared_from_uno.hxx>
      36             : 
      37             : #include <cppcanvas/spritecanvas.hxx>
      38             : #include <cppcanvas/customsprite.hxx>
      39             : #include <cppcanvas/vclfactory.hxx>
      40             : #include <cppcanvas/basegfxfactory.hxx>
      41             : 
      42             : #include <tools/debug.hxx>
      43             : 
      44             : #include <basegfx/range/b1drange.hxx>
      45             : #include <basegfx/range/b2drange.hxx>
      46             : #include <basegfx/range/b2irange.hxx>
      47             : #include <basegfx/point/b2dpoint.hxx>
      48             : #include <basegfx/polygon/b2dpolygon.hxx>
      49             : #include <basegfx/matrix/b2dhommatrix.hxx>
      50             : #include <basegfx/polygon/b2dpolygontools.hxx>
      51             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      52             : #include <basegfx/tools/canvastools.hxx>
      53             : #include <basegfx/polygon/b2dpolygonclipper.hxx>
      54             : #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
      55             : 
      56             : #include <com/sun/star/presentation/XSlideShow.hpp>
      57             : 
      58             : #include <boost/noncopyable.hpp>
      59             : #include <boost/bind.hpp>
      60             : #include <boost/weak_ptr.hpp>
      61             : 
      62             : #include <vector>
      63             : #include <iterator>
      64             : #include <algorithm>
      65             : 
      66             : using namespace com::sun::star;
      67             : 
      68             : namespace slideshow {
      69             : namespace internal {
      70             : 
      71             : namespace {
      72             : 
      73             : struct StaticUnitRectPoly : public rtl::StaticWithInit<basegfx::B2DPolygon, StaticUnitRectPoly>
      74             : {
      75             :     basegfx::B2DPolygon operator()()
      76             :     {
      77             :         return basegfx::tools::createUnitPolygon();
      78             :     }
      79             : };
      80             : 
      81             : /** Sprite entry, to store sprite plus priority
      82             : 
      83             :     The operator<() defines a strict weak ordering of sprites, sort
      84             :     key is the sprite priority.
      85             :  */
      86           0 : struct SpriteEntry
      87             : {
      88           0 :     SpriteEntry( const cppcanvas::CustomSpriteSharedPtr& rSprite,
      89             :                  double                                  nPrio ) :
      90             :         mpSprite( rSprite ),
      91           0 :         mnPriority( nPrio )
      92             :     {
      93           0 :     }
      94             : 
      95           0 :     bool operator<(const SpriteEntry& rRHS) const
      96             :     {
      97           0 :         return mnPriority < rRHS.mnPriority;
      98             :     }
      99             : 
     100             :     boost::weak_ptr< cppcanvas::CustomSprite > mpSprite;
     101             :     double                                     mnPriority;
     102             : };
     103             : 
     104             : typedef std::vector< SpriteEntry > SpriteVector;
     105             : 
     106             : 
     107             : /** Create a clip polygon for slide views
     108             : 
     109             :     @param rClip
     110             :     Clip to set (can be empty)
     111             : 
     112             :     @param rCanvas
     113             :     Canvas to create the clip polygon for
     114             : 
     115             :     @param rUserSize
     116             :     The size of the view. Note that the returned clip will
     117             :     <em>always</em> clip to at least the rect defined herein.
     118             : 
     119             :     @return the view clip polygon, in view coordinates, which is
     120             :     guaranteed to at least clip to the view size.
     121             :  */
     122           0 : basegfx::B2DPolyPolygon createClipPolygon( const basegfx::B2DPolyPolygon&    rClip,
     123             :                                            const cppcanvas::CanvasSharedPtr& /*rCanvas*/,
     124             :                                            const basegfx::B2DSize&           rUserSize )
     125             : {
     126             :     // setup canvas clipping
     127             :     // =====================
     128             : 
     129             :     // AW: Simplified
     130           0 :     const basegfx::B2DRange aClipRange(0, 0, rUserSize.getX(), rUserSize.getY());
     131             : 
     132           0 :     if(rClip.count())
     133             :     {
     134           0 :         return basegfx::tools::clipPolyPolygonOnRange(rClip, aClipRange, true, false);
     135             :     }
     136             :     else
     137             :     {
     138           0 :         return basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aClipRange));
     139             :     }
     140             : }
     141             : 
     142             : /** Prepare given clip polygon to be stored as the current clip
     143             : 
     144             :     Note that this is separate from createClipPolygon(), to allow
     145             :     SlideView implementations to store this intermediate result
     146             :     (createClipPolygon() has to be called every time the view size
     147             :     changes)
     148             :  */
     149           0 : basegfx::B2DPolyPolygon prepareClip( const basegfx::B2DPolyPolygon& rClip )
     150             : {
     151           0 :     basegfx::B2DPolyPolygon aClip( rClip );
     152             : 
     153             :     // TODO(P2): unnecessary, once XCanvas is correctly handling this
     154             :     // AW: Should be no longer necessary; tools are now bezier-safe
     155           0 :     if( aClip.areControlPointsUsed() )
     156           0 :         aClip = basegfx::tools::adaptiveSubdivideByAngle( aClip );
     157             : 
     158             :     // normalize polygon, preparation for clipping
     159             :     // in updateCanvas()
     160           0 :     aClip = basegfx::tools::correctOrientations(aClip);
     161           0 :     aClip = basegfx::tools::solveCrossovers(aClip);
     162           0 :     aClip = basegfx::tools::stripNeutralPolygons(aClip);
     163           0 :     aClip = basegfx::tools::stripDispensablePolygons(aClip, false);
     164             : 
     165           0 :     return aClip;
     166             : }
     167             : 
     168             : 
     169           0 : void clearRect( ::cppcanvas::CanvasSharedPtr const& pCanvas,
     170             :                 basegfx::B2IRange const&            rArea )
     171             : {
     172             :     // convert clip polygon to device coordinate system
     173           0 :     ::basegfx::B2DPolyPolygon const* pClipPoly( pCanvas->getClip() );
     174           0 :     if( pClipPoly )
     175             :     {
     176           0 :         ::basegfx::B2DPolyPolygon aClipPoly( *pClipPoly );
     177           0 :         aClipPoly.transform( pCanvas->getTransformation() );
     178           0 :         pCanvas->setClip( aClipPoly );
     179             :     }
     180             : 
     181             :     // set transformation to identitiy (->device pixel)
     182           0 :     pCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
     183             : 
     184             :     // #i42440# Fill the _full_ background in
     185             :     // black. Since we had to extend the bitmap by one
     186             :     // pixel, and the bitmap is initialized white,
     187             :     // depending on the slide content a one pixel wide
     188             :     // line will show to the bottom and the right.
     189             :     const ::basegfx::B2DPolygon aPoly(
     190             :         ::basegfx::tools::createPolygonFromRect(
     191           0 :             basegfx::B2DRange(rArea)));
     192             : 
     193             :     ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
     194           0 :         ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( pCanvas,
     195           0 :                                                                       aPoly ) );
     196             : 
     197           0 :     if( pPolyPoly )
     198             :     {
     199           0 :         pPolyPoly->setCompositeOp( cppcanvas::CanvasGraphic::SOURCE );
     200           0 :         pPolyPoly->setRGBAFillColor( 0xFFFFFF00U );
     201           0 :         pPolyPoly->draw();
     202           0 :     }
     203             : 
     204             : #if OSL_DEBUG_LEVEL >= 2 && defined(DBG_UTIL)
     205             :     ::cppcanvas::CanvasSharedPtr pCliplessCanvas( pCanvas->clone() );
     206             :     pCliplessCanvas->setClip();
     207             : 
     208             :     if( pCanvas->getClip() )
     209             :     {
     210             :         ::cppcanvas::PolyPolygonSharedPtr pPolyPoly2(
     211             :             ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( pCliplessCanvas,
     212             :                                                                           aPoly ));
     213             :         if( pPolyPoly2 )
     214             :         {
     215             :             pPolyPoly2->setRGBALineColor( 0x008000FFU );
     216             :             pPolyPoly2->draw();
     217             :         }
     218             :     }
     219             : #endif
     220           0 : }
     221             : 
     222             : /** Get bounds in pixel
     223             : 
     224             :     @param rLayerBounds
     225             :     Bound rect, in user space coordinates
     226             : 
     227             :     @param rTransformation
     228             :     User space to device pixel transformation
     229             : 
     230             :     @return the layer bounds in pixel, extended by one pixel to the
     231             :     right and bottom
     232             :  */
     233           0 : basegfx::B2IRange getLayerBoundsPixel( basegfx::B2DRange const&     rLayerBounds,
     234             :                                        basegfx::B2DHomMatrix const& rTransformation )
     235             : {
     236           0 :     ::basegfx::B2DRange aTmpRect;
     237             :     ::canvas::tools::calcTransformedRectBounds( aTmpRect,
     238             :                                                 rLayerBounds,
     239           0 :                                                 rTransformation );
     240             : 
     241           0 :     if( aTmpRect.isEmpty() )
     242           0 :         return ::basegfx::B2IRange();
     243             : 
     244             :     // #i42440# Returned layer size is one pixel too small, as
     245             :     // rendering happens one pixel to the right and below the
     246             :     // actual bound rect.
     247             :     return ::basegfx::B2IRange( ::basegfx::fround(aTmpRect.getMinX()),
     248             :                                 ::basegfx::fround(aTmpRect.getMinY()),
     249           0 :                                 ::basegfx::fround(aTmpRect.getMaxX()) + 1,
     250           0 :                                 ::basegfx::fround(aTmpRect.getMaxY()) + 1 );
     251             : }
     252             : 
     253             : 
     254             : // ----------------------------------------------------------------
     255             : 
     256             : /** Container class for sprites issued by a ViewLayer
     257             : 
     258             :     This class handles the sprite prioritization issues, that are
     259             :     needed for layer sprites (e.g. the need to re-prioritize sprites
     260             :     when the layer changes prio).
     261             :  */
     262           0 : class LayerSpriteContainer
     263             : {
     264             :     /** Max fill level of maSprites, before we try to prune it from
     265             :         deceased sprites
     266             :     */
     267             :     enum{ SPRITE_ULLAGE=256 };
     268             : 
     269             :     /** All sprites that have been issued by this container (pruned
     270             :         from time to time, for invalid references). This vector is
     271             :         kept sorted with increasing sprite priority.
     272             :     */
     273             :     SpriteVector       maSprites;
     274             : 
     275             :     /// Priority of this layer, relative to other view layers
     276             :     basegfx::B1DRange  maLayerPrioRange;
     277             : 
     278           0 :     double getSpritePriority( std::size_t nSpriteNum ) const
     279             :     {
     280             :         // divide the available layer range equally between all
     281             :         // sprites, assign upper bound of individual sprite range as
     282             :         // sprite prio (the layer itself gets assigned the lower bound
     283             :         // of sprite 0's individual range):
     284             :         //
     285             :         // | layer 0                    | layer 1                    | ...
     286             :         // |    sprite 0 |    sprite 1  |    sprite 0 |    sprite 1  | ...
     287           0 :         return maLayerPrioRange.getMinimum() + maLayerPrioRange.getRange()*(nSpriteNum+1)/(maSprites.size()+1);
     288             :     }
     289             : 
     290             :     /** Rescan sprite vector, and remove deceased sprites (and reset
     291             :         sprite prio)
     292             : 
     293             :         @param aBegin
     294             :         Iterator to the first entry to rescan
     295             :      */
     296           0 :     void updateSprites()
     297             :     {
     298           0 :         SpriteVector aValidSprites;
     299             : 
     300             :         // check all sprites for validity and set new priority
     301           0 :         SpriteVector::iterator       aCurrSprite( maSprites.begin() );
     302           0 :         const SpriteVector::iterator aEnd( maSprites.end() );
     303           0 :         while( aCurrSprite != aEnd )
     304             :         {
     305           0 :             cppcanvas::CustomSpriteSharedPtr pCurrSprite( aCurrSprite->mpSprite.lock() );
     306             : 
     307           0 :             if( pCurrSprite )
     308             :             {
     309             :                 // only copy still valid sprites over to the refreshed
     310             :                 // sprite vector.
     311           0 :                 aValidSprites.push_back( *aCurrSprite );
     312             : 
     313           0 :                 pCurrSprite->setPriority(
     314           0 :                     getSpritePriority( aValidSprites.size()-1 ));
     315             :             }
     316             : 
     317           0 :             ++aCurrSprite;
     318           0 :         }
     319             : 
     320             :         // replace sprite list with pruned one
     321           0 :         maSprites.swap( aValidSprites );
     322           0 :     }
     323             : 
     324             : public:
     325           0 :     LayerSpriteContainer() :
     326             :         maSprites(),
     327           0 :         maLayerPrioRange()
     328             :     {
     329           0 :     }
     330             : 
     331           0 :     basegfx::B1DRange getLayerPriority() const
     332             :     {
     333           0 :         return maLayerPrioRange;
     334             :     }
     335             : 
     336           0 :     void setLayerPriority( const basegfx::B1DRange& rRange )
     337             :     {
     338           0 :         if( rRange != maLayerPrioRange )
     339             :         {
     340           0 :             maLayerPrioRange = rRange;
     341             : 
     342             :             // prune and recalc sprite prios
     343           0 :             updateSprites();
     344             :         }
     345           0 :     }
     346             : 
     347           0 :     void addSprite( const cppcanvas::CustomSpriteSharedPtr& pSprite,
     348             :                     double                                  nPriority )
     349             :     {
     350           0 :         if( !pSprite )
     351           0 :             return;
     352             : 
     353           0 :         SpriteEntry aEntry( pSprite,nPriority );
     354             : 
     355             :         // insert new sprite, such that vector stays sorted
     356             :         SpriteVector::iterator aInsertPos(
     357             :             maSprites.insert(
     358             :                 std::lower_bound( maSprites.begin(),
     359             :                                   maSprites.end(),
     360             :                                   aEntry ),
     361           0 :                 aEntry ));
     362             : 
     363           0 :         const std::size_t nNumSprites( maSprites.size() );
     364           0 :         if( nNumSprites > SPRITE_ULLAGE ||
     365           0 :             maSprites.end() - aInsertPos > 1 )
     366             :         {
     367             :             // updateSprites() also updates all sprite prios
     368           0 :             updateSprites();
     369             :         }
     370             :         else
     371             :         {
     372             :             // added sprite to the end, and not too many sprites in
     373             :             // vector - perform optimized update (only need to set
     374             :             // prio). This basically caters for the common case of
     375             :             // iterated character animations, which generate lots of
     376             :             // sprites, all added to the end.
     377           0 :             pSprite->setPriority(
     378           0 :                 getSpritePriority( nNumSprites-1 ));
     379           0 :         }
     380             :     }
     381             : 
     382           0 :     void clear()
     383             :     {
     384           0 :         maSprites.clear();
     385           0 :     }
     386             : };
     387             : 
     388             : 
     389             : // ----------------------------------------------------------------
     390             : 
     391             : 
     392             : /** This class provides layers for a slide view
     393             : 
     394             :     Layers are used to render animations with the correct z order -
     395             :     because sprites are always in front of the static canvas
     396             :     background, shapes that must appear <em<before</em> an animation
     397             :     must also be displayed as a sprite.
     398             : 
     399             :     Each layer has a priority assigned to it (valid range [0,1]), which
     400             :     also affects all sprites created for this specific layer - i.e. if
     401             :     the layer priority changes, the sprites change z order together
     402             :     with their parent.
     403             :  */
     404           0 : class SlideViewLayer : public ViewLayer,
     405             :                        private boost::noncopyable
     406             : {
     407             :     /// Smart container for all sprites issued by this layer
     408             :     mutable LayerSpriteContainer             maSpriteContainer;
     409             : 
     410             :     /// Bounds of this layer in user space coordinates
     411             :     basegfx::B2DRange                        maLayerBounds;
     412             : 
     413             :     /// Bounds of this layer in device pixel
     414             :     mutable basegfx::B2IRange                maLayerBoundsPixel;
     415             : 
     416             :     /// Current clip polygon in user coordinates
     417             :     basegfx::B2DPolyPolygon                  maClip;
     418             : 
     419             :     /// Current size of the view in user coordinates
     420             :     basegfx::B2DSize                         maUserSize;
     421             : 
     422             :     /// Current overall view transformation
     423             :     basegfx::B2DHomMatrix                    maTransformation;
     424             : 
     425             :     /// 'parent' canvas, this viewlayer is associated with
     426             :     const cppcanvas::SpriteCanvasSharedPtr   mpSpriteCanvas;
     427             : 
     428             :     /** output surface (necessarily a sprite, won't otherwise be able
     429             :         to display anything <em>before</em> other sprites)
     430             :     */
     431             :     mutable cppcanvas::CustomSpriteSharedPtr mpSprite;
     432             : 
     433             :     /// actual output canvas retrieved from a sprite
     434             :     mutable cppcanvas::CanvasSharedPtr       mpOutputCanvas;
     435             : 
     436             :     /// ptr back to owning view. needed for isOnView() method
     437             :     View const* const                        mpParentView;
     438             : 
     439             : public:
     440             :     /** Create a new layer
     441             : 
     442             :         @param pCanvas
     443             :         Sprite canvas to create the layer on
     444             : 
     445             :         @param rTransform
     446             :         Initial overall canvas transformation
     447             : 
     448             :         @param rLayerBounds
     449             :         Initial layer bounds, in view coordinate system
     450             :      */
     451           0 :     SlideViewLayer( const cppcanvas::SpriteCanvasSharedPtr& pCanvas,
     452             :                     const basegfx::B2DHomMatrix&            rTransform,
     453             :                     const basegfx::B2DRange&                rLayerBounds,
     454             :                     const basegfx::B2DSize&                 rUserSize,
     455             :                     View const* const                       pParentView) :
     456             :         maSpriteContainer(),
     457             :         maLayerBounds(rLayerBounds),
     458             :         maLayerBoundsPixel(),
     459             :         maClip(),
     460             :         maUserSize(rUserSize),
     461             :         maTransformation(rTransform),
     462             :         mpSpriteCanvas(pCanvas),
     463             :         mpSprite(),
     464             :         mpOutputCanvas(),
     465           0 :         mpParentView(pParentView)
     466             :     {
     467           0 :     }
     468             : 
     469           0 :     void updateView( const basegfx::B2DHomMatrix& rMatrix,
     470             :                      const basegfx::B2DSize&      rUserSize )
     471             :     {
     472           0 :         maTransformation = rMatrix;
     473           0 :         maUserSize = rUserSize;
     474             : 
     475             :         // limit layer bounds to visible screen
     476             :         maLayerBounds.intersect( basegfx::B2DRange(0.0,
     477             :                                                    0.0,
     478             :                                                    maUserSize.getX(),
     479           0 :                                                    maUserSize.getY()) );
     480             : 
     481             :         basegfx::B2IRange const& rNewLayerPixel(
     482             :             getLayerBoundsPixel(maLayerBounds,
     483           0 :                                 maTransformation) );
     484           0 :         if( rNewLayerPixel != maLayerBoundsPixel )
     485             :         {
     486             :             // re-gen sprite with new size
     487           0 :             mpOutputCanvas.reset();
     488           0 :             mpSprite.reset();
     489             :         }
     490           0 :     }
     491             : 
     492             : private:
     493             :     // ViewLayer interface
     494             :     // ----------------------------------------------
     495             : 
     496           0 :     virtual cppcanvas::CustomSpriteSharedPtr createSprite(
     497             :         const ::basegfx::B2DSize& rSpriteSizePixel,
     498             :         double                    nPriority ) const
     499             :     {
     500             :         cppcanvas::CustomSpriteSharedPtr pSprite(
     501           0 :             mpSpriteCanvas->createCustomSprite( rSpriteSizePixel ) );
     502             : 
     503             :         maSpriteContainer.addSprite( pSprite,
     504           0 :                                      nPriority );
     505             : 
     506           0 :         return pSprite;
     507             :     }
     508             : 
     509           0 :     virtual void setPriority( const basegfx::B1DRange& rRange )
     510             :     {
     511             :         OSL_ENSURE( !rRange.isEmpty() &&
     512             :                     rRange.getMinimum() >= 1.0,
     513             :                     "SlideViewLayer::setPriority(): prio MUST be larger than 1.0 (because "
     514             :                     "the background layer already lies there)" );
     515             : 
     516           0 :         maSpriteContainer.setLayerPriority( rRange );
     517             : 
     518           0 :         if( mpSprite )
     519           0 :             mpSprite->setPriority( rRange.getMinimum() );
     520           0 :     }
     521             : 
     522           0 :     virtual basegfx::B2DHomMatrix getTransformation() const
     523             :     {
     524             :         // Offset given transformation by left, top border of given
     525             :         // range (after transformation through given transformation)
     526           0 :         basegfx::B2DRectangle aTmpRect;
     527             :         canvas::tools::calcTransformedRectBounds( aTmpRect,
     528             :                                                   maLayerBounds,
     529           0 :                                                   maTransformation );
     530             : 
     531           0 :         basegfx::B2DHomMatrix aMatrix( maTransformation );
     532             : 
     533             :         // Add translation according to the origin of aTmpRect.  Ignore the
     534             :         // translation when aTmpRect was not properly initialized.
     535           0 :         if ( ! aTmpRect.isEmpty())
     536             :         {
     537           0 :             aMatrix.translate( -basegfx::fround(aTmpRect.getMinX()),
     538           0 :                                -basegfx::fround(aTmpRect.getMinY()) );
     539             :         }
     540             : 
     541           0 :         return aMatrix;
     542             :     }
     543             : 
     544           0 :     virtual basegfx::B2DHomMatrix getSpriteTransformation() const
     545             :     {
     546           0 :         return maTransformation;
     547             :     }
     548             : 
     549           0 :     virtual void clear() const
     550             :     {
     551             :         // grab canvas - that also lazy-initializes maLayerBoundsPixel
     552           0 :         cppcanvas::CanvasSharedPtr pCanvas=getCanvas()->clone();
     553             : 
     554             :         // clear whole canvas
     555           0 :         const basegfx::B2I64Tuple& rSpriteSize(maLayerBoundsPixel.getRange());
     556             :         clearRect(pCanvas,
     557           0 :                   basegfx::B2IRange(0,0,rSpriteSize.getX(),rSpriteSize.getY()));
     558           0 :     }
     559             : 
     560           0 :     virtual void clearAll() const
     561             :     {
     562             :         // grab canvas - that also lazy-initializes maLayerBoundsPixel
     563           0 :         ::cppcanvas::CanvasSharedPtr pCanvas( getCanvas()->clone() );
     564             : 
     565             :         // clear layer clip, to clear whole area
     566           0 :         pCanvas->setClip();
     567             : 
     568             :         // clear whole canvas
     569           0 :         const basegfx::B2I64Tuple& rSpriteSize(maLayerBoundsPixel.getRange());
     570             :         clearRect(pCanvas,
     571           0 :                   basegfx::B2IRange(0,0,rSpriteSize.getX(),rSpriteSize.getY()));
     572           0 :     }
     573             : 
     574           0 :     virtual bool isOnView(boost::shared_ptr<View> const& rView) const
     575             :     {
     576           0 :         return rView.get() == mpParentView;
     577             :     }
     578             : 
     579           0 :     virtual cppcanvas::CanvasSharedPtr getCanvas() const
     580             :     {
     581           0 :         if( !mpOutputCanvas )
     582             :         {
     583           0 :             if( !mpSprite )
     584             :             {
     585             :                 maLayerBoundsPixel = getLayerBoundsPixel(maLayerBounds,
     586           0 :                                                          maTransformation);
     587             : 
     588             :                 // HACK: ensure at least 1x1 pixel size. clients might
     589             :                 // need an actual canvas (e.g. for bound rect
     590             :                 // calculations) without rendering anything. Better
     591             :                 // solution: introduce something like a reference
     592             :                 // canvas for ViewLayers, which is always available.
     593           0 :                 if( maLayerBoundsPixel.isEmpty() )
     594           0 :                     maLayerBoundsPixel = basegfx::B2IRange(0,0,1,1);
     595             : 
     596           0 :                 const basegfx::B2I64Tuple& rSpriteSize(maLayerBoundsPixel.getRange());
     597           0 :                 mpSprite = mpSpriteCanvas->createCustomSprite(
     598           0 :                     basegfx::B2DVector(sal::static_int_cast<sal_Int32>(rSpriteSize.getX()),
     599           0 :                                        sal::static_int_cast<sal_Int32>(rSpriteSize.getY())) );
     600             : 
     601           0 :                 mpSprite->setPriority(
     602           0 :                     maSpriteContainer.getLayerPriority().getMinimum() );
     603             : 
     604             : #if OSL_DEBUG_LEVEL >= 2 && defined(DBG_UTIL)
     605             :                 mpSprite->movePixel(
     606             :                     basegfx::B2DPoint(maLayerBoundsPixel.getMinimum()) +
     607             :                     basegfx::B2DPoint(10,10) );
     608             : 
     609             :                 mpSprite->setAlpha(0.5);
     610             : #else
     611           0 :                 mpSprite->movePixel(
     612           0 :                     basegfx::B2DPoint(maLayerBoundsPixel.getMinimum()) );
     613             : 
     614           0 :                 mpSprite->setAlpha(1.0);
     615             : #endif
     616           0 :                 mpSprite->show();
     617             :             }
     618             : 
     619           0 :             ENSURE_OR_THROW( mpSprite,
     620             :                               "SlideViewLayer::getCanvas(): no layer sprite" );
     621             : 
     622           0 :             mpOutputCanvas = mpSprite->getContentCanvas();
     623             : 
     624           0 :             ENSURE_OR_THROW( mpOutputCanvas,
     625             :                               "SlideViewLayer::getCanvas(): sprite doesn't yield a canvas" );
     626             : 
     627             :             // new canvas retrieved - setup transformation and clip
     628           0 :             mpOutputCanvas->setTransformation( getTransformation() );
     629           0 :             mpOutputCanvas->setClip(
     630             :                 createClipPolygon( maClip,
     631             :                                    mpOutputCanvas,
     632           0 :                                    maUserSize ));
     633             :         }
     634             : 
     635           0 :         return mpOutputCanvas;
     636             :     }
     637             : 
     638           0 :     virtual void setClip( const basegfx::B2DPolyPolygon& rClip )
     639             :     {
     640           0 :         basegfx::B2DPolyPolygon aNewClip = prepareClip( rClip );
     641             : 
     642           0 :         if( aNewClip != maClip )
     643             :         {
     644           0 :             maClip = aNewClip;
     645             : 
     646           0 :             if(mpOutputCanvas )
     647           0 :                 mpOutputCanvas->setClip(
     648             :                     createClipPolygon( maClip,
     649             :                                        mpOutputCanvas,
     650           0 :                                        maUserSize ));
     651           0 :         }
     652           0 :     }
     653             : 
     654           0 :     virtual bool resize( const ::basegfx::B2DRange& rArea )
     655             :     {
     656           0 :         const bool bRet( maLayerBounds != rArea );
     657           0 :         maLayerBounds = rArea;
     658             :         updateView( maTransformation,
     659           0 :                     maUserSize );
     660             : 
     661           0 :         return bRet;
     662             :     }
     663             : };
     664             : 
     665             : 
     666             : // ---------------------------------------------------------
     667             : 
     668             : typedef cppu::WeakComponentImplHelper2<
     669             :     ::com::sun::star::util::XModifyListener,
     670             :       ::com::sun::star::awt::XPaintListener> SlideViewBase;
     671             : 
     672             : /** SlideView class
     673             : 
     674             :     This class implements the View interface, encapsulating
     675             :     <em>one</em> view a slideshow is displayed on.
     676             :  */
     677           0 : class SlideView : private cppu::BaseMutex,
     678             :                   public SlideViewBase,
     679             :                   public UnoView
     680             : {
     681             : public:
     682             :     SlideView( const uno::Reference<presentation::XSlideShowView>& xView,
     683             :                EventQueue&                                         rEventQueue,
     684             :                EventMultiplexer&                                   rEventMultiplexer );
     685             :     void updateCanvas();
     686             : 
     687             : private:
     688             :     // View:
     689             :     virtual ViewLayerSharedPtr createViewLayer( const basegfx::B2DRange& rLayerBounds ) const;
     690             :     virtual bool updateScreen() const;
     691             :     virtual bool paintScreen() const;
     692             :     virtual void setViewSize( const ::basegfx::B2DSize& );
     693             :     virtual void setCursorShape( sal_Int16 nPointerShape );
     694             : 
     695             :     // ViewLayer interface
     696             :     virtual bool isOnView(boost::shared_ptr<View> const& rView) const;
     697             :     virtual void clear() const;
     698             :     virtual void clearAll() const;
     699             :     virtual cppcanvas::CanvasSharedPtr getCanvas() const;
     700             :     virtual cppcanvas::CustomSpriteSharedPtr createSprite( const ::basegfx::B2DSize& rSpriteSizePixel,
     701             :                                                            double                    nPriority ) const;
     702             :     virtual void setPriority( const basegfx::B1DRange& rRange );
     703             :     virtual ::basegfx::B2DHomMatrix getTransformation() const;
     704             :     virtual basegfx::B2DHomMatrix getSpriteTransformation() const;
     705             :     virtual void setClip( const ::basegfx::B2DPolyPolygon& rClip );
     706             :     virtual bool resize( const ::basegfx::B2DRange& rArea );
     707             : 
     708             :     // UnoView:
     709             :     virtual void _dispose();
     710             :     virtual uno::Reference<presentation::XSlideShowView> getUnoView()const;
     711             :     virtual void setIsSoundEnabled (const bool bValue);
     712             :     virtual bool isSoundEnabled (void) const;
     713             : 
     714             :     // XEventListener:
     715             :     virtual void SAL_CALL disposing( lang::EventObject const& evt )
     716             :         throw (uno::RuntimeException);
     717             :     // XModifyListener:
     718             :     virtual void SAL_CALL modified( const lang::EventObject& aEvent )
     719             :         throw (uno::RuntimeException);
     720             :     // XPaintListener:
     721             :     virtual void SAL_CALL windowPaint( const awt::PaintEvent& e )
     722             :         throw (uno::RuntimeException);
     723             : 
     724             :     // WeakComponentImplHelperBase:
     725             :     virtual void SAL_CALL disposing();
     726             : 
     727             :     void updateClip();
     728             : 
     729             : private:
     730             :     typedef std::vector< boost::weak_ptr<SlideViewLayer> > ViewLayerVector;
     731             : 
     732             :     /// Prune viewlayers from deceased ones, optionally update them
     733             :     void pruneLayers( bool bWithViewLayerUpdate=false ) const;
     734             : 
     735             :     /** Max fill level of maViewLayers, before we try to prune it from
     736             :         deceased layers
     737             :     */
     738             :     enum{ LAYER_ULLAGE=8 };
     739             : 
     740             :     uno::Reference<presentation::XSlideShowView>              mxView;
     741             :     cppcanvas::SpriteCanvasSharedPtr                          mpCanvas;
     742             : 
     743             :     EventMultiplexer&                                         mrEventMultiplexer;
     744             :     EventQueue&                                               mrEventQueue;
     745             : 
     746             :     mutable LayerSpriteContainer                              maSprites;
     747             :     mutable ViewLayerVector                                   maViewLayers;
     748             : 
     749             :     basegfx::B2DPolyPolygon                                   maClip;
     750             : 
     751             :     basegfx::B2DHomMatrix                                     maViewTransform;
     752             :     basegfx::B2DSize                                          maUserSize;
     753             :     bool mbIsSoundEnabled;
     754             : };
     755             : 
     756             : 
     757           0 : SlideView::SlideView( const uno::Reference<presentation::XSlideShowView>& xView,
     758             :                       EventQueue&                                         rEventQueue,
     759             :                       EventMultiplexer&                                   rEventMultiplexer ) :
     760             :     SlideViewBase( m_aMutex ),
     761             :     mxView( xView ),
     762             :     mpCanvas(),
     763             :     mrEventMultiplexer( rEventMultiplexer ),
     764             :     mrEventQueue( rEventQueue ),
     765             :     maSprites(),
     766             :     maViewLayers(),
     767             :     maClip(),
     768             :     maViewTransform(),
     769             :     maUserSize( 1.0, 1.0 ), // default size: one-by-one rectangle
     770           0 :     mbIsSoundEnabled(true)
     771             : {
     772             :     // take care not constructing any UNO references to this _inside_
     773             :     // ctor, shift that code to createSlideView()!
     774           0 :     ENSURE_OR_THROW( mxView.is(),
     775             :                       "SlideView::SlideView(): Invalid view" );
     776             : 
     777           0 :     mpCanvas = cppcanvas::VCLFactory::getInstance().createSpriteCanvas(
     778           0 :         xView->getCanvas() );
     779           0 :     ENSURE_OR_THROW( mpCanvas,
     780             :                       "Could not create cppcanvas" );
     781             : 
     782             :     geometry::AffineMatrix2D aViewTransform(
     783           0 :         xView->getTransformation() );
     784             : 
     785           0 :     if( basegfx::fTools::equalZero(
     786             :             basegfx::B2DVector(aViewTransform.m00,
     787           0 :                                aViewTransform.m10).getLength()) ||
     788             :         basegfx::fTools::equalZero(
     789             :             basegfx::B2DVector(aViewTransform.m01,
     790           0 :                                aViewTransform.m11).getLength()) )
     791             :     {
     792             :         OSL_FAIL( "SlideView::SlideView(): Singular matrix!" );
     793             : 
     794           0 :         canvas::tools::setIdentityAffineMatrix2D(aViewTransform);
     795             :     }
     796             : 
     797             :     basegfx::unotools::homMatrixFromAffineMatrix(
     798           0 :         maViewTransform, aViewTransform );
     799             : 
     800             :     // once and forever: set fixed prio to this 'layer' (we're always
     801             :     // the background layer)
     802           0 :     maSprites.setLayerPriority( basegfx::B1DRange(0.0,1.0) );
     803           0 : }
     804             : 
     805           0 : void SlideView::disposing()
     806             : {
     807           0 :     osl::MutexGuard aGuard( m_aMutex );
     808             : 
     809           0 :     maViewLayers.clear();
     810           0 :     maSprites.clear();
     811           0 :     mpCanvas.reset();
     812             : 
     813             :     // additionally, also de-register from XSlideShowView
     814           0 :     if (mxView.is())
     815             :     {
     816           0 :         mxView->removeTransformationChangedListener( this );
     817           0 :         mxView->removePaintListener( this );
     818           0 :         mxView.clear();
     819           0 :     }
     820           0 : }
     821             : 
     822           0 : ViewLayerSharedPtr SlideView::createViewLayer( const basegfx::B2DRange& rLayerBounds ) const
     823             : {
     824           0 :     osl::MutexGuard aGuard( m_aMutex );
     825             : 
     826           0 :     ENSURE_OR_THROW( mpCanvas,
     827             :                       "SlideView::createViewLayer(): Disposed" );
     828             : 
     829           0 :     const std::size_t nNumLayers( maViewLayers.size() );
     830             : 
     831             :     // avoid filling up layer vector with lots of deceased layer weak
     832             :     // ptrs
     833           0 :     if( nNumLayers > LAYER_ULLAGE )
     834           0 :         pruneLayers();
     835             : 
     836             :     boost::shared_ptr<SlideViewLayer> pViewLayer( new SlideViewLayer(mpCanvas,
     837           0 :                                                                      getTransformation(),
     838             :                                                                      rLayerBounds,
     839             :                                                                      maUserSize,
     840           0 :                                                                      this) );
     841           0 :     maViewLayers.push_back( pViewLayer );
     842             : 
     843           0 :     return pViewLayer;
     844             : }
     845             : 
     846           0 : bool SlideView::updateScreen() const
     847             : {
     848           0 :     osl::MutexGuard aGuard( m_aMutex );
     849             : 
     850           0 :     ENSURE_OR_RETURN_FALSE( mpCanvas.get(),
     851             :                        "SlideView::updateScreen(): Disposed" );
     852             : 
     853           0 :     return mpCanvas->updateScreen( false );
     854             : }
     855             : 
     856           0 : bool SlideView::paintScreen() const
     857             : {
     858           0 :     osl::MutexGuard aGuard( m_aMutex );
     859             : 
     860           0 :     ENSURE_OR_RETURN_FALSE( mpCanvas.get(),
     861             :                        "SlideView::paintScreen(): Disposed" );
     862             : 
     863           0 :     return mpCanvas->updateScreen( true );
     864             : }
     865             : 
     866           0 : void SlideView::clear() const
     867             : {
     868           0 :     osl::MutexGuard aGuard( m_aMutex );
     869             : 
     870             :     OSL_ENSURE( mxView.is() && mpCanvas,
     871             :                 "SlideView::clear(): Disposed" );
     872           0 :     if( !mxView.is() || !mpCanvas )
     873           0 :         return;
     874             : 
     875             :     // keep layer clip
     876           0 :     clearRect(getCanvas()->clone(),
     877             :               getLayerBoundsPixel(
     878             :                   basegfx::B2DRange(0,0,
     879             :                                     maUserSize.getX(),
     880             :                                     maUserSize.getY()),
     881           0 :                   getTransformation()));
     882             : }
     883             : 
     884           0 : void SlideView::clearAll() const
     885             : {
     886           0 :     osl::MutexGuard aGuard( m_aMutex );
     887             : 
     888             :     OSL_ENSURE( mxView.is() && mpCanvas,
     889             :                 "SlideView::clear(): Disposed" );
     890           0 :     if( !mxView.is() || !mpCanvas )
     891           0 :         return;
     892             : 
     893             :     // clear whole view
     894           0 :     mxView->clear();
     895             : }
     896             : 
     897           0 : void SlideView::setViewSize( const basegfx::B2DSize& rSize )
     898             : {
     899           0 :     osl::MutexGuard aGuard( m_aMutex );
     900             : 
     901           0 :     maUserSize = rSize;
     902           0 :     updateCanvas();
     903           0 : }
     904             : 
     905           0 : void SlideView::setCursorShape( sal_Int16 nPointerShape )
     906             : {
     907           0 :     osl::MutexGuard const guard( m_aMutex );
     908             : 
     909           0 :     if (mxView.is())
     910           0 :         mxView->setMouseCursor( nPointerShape );
     911           0 : }
     912             : 
     913           0 : bool SlideView::isOnView(boost::shared_ptr<View> const& rView) const
     914             : {
     915           0 :     return rView.get() == this;
     916             : }
     917             : 
     918           0 : cppcanvas::CanvasSharedPtr SlideView::getCanvas() const
     919             : {
     920           0 :     osl::MutexGuard aGuard( m_aMutex );
     921             : 
     922           0 :     ENSURE_OR_THROW( mpCanvas,
     923             :                       "SlideView::getCanvas(): Disposed" );
     924             : 
     925           0 :     return mpCanvas;
     926             : }
     927             : 
     928           0 : cppcanvas::CustomSpriteSharedPtr SlideView::createSprite(
     929             :     const basegfx::B2DSize& rSpriteSizePixel,
     930             :     double                  nPriority ) const
     931             : {
     932           0 :     osl::MutexGuard aGuard( m_aMutex );
     933             : 
     934           0 :     ENSURE_OR_THROW( mpCanvas, "SlideView::createSprite(): Disposed" );
     935             : 
     936             :     cppcanvas::CustomSpriteSharedPtr pSprite(
     937           0 :         mpCanvas->createCustomSprite( rSpriteSizePixel ) );
     938             : 
     939             :     maSprites.addSprite( pSprite,
     940           0 :                          nPriority );
     941             : 
     942           0 :     return pSprite;
     943             : }
     944             : 
     945           0 : void SlideView::setPriority( const basegfx::B1DRange& /*rRange*/ )
     946             : {
     947           0 :     osl::MutexGuard aGuard( m_aMutex );
     948             : 
     949             :     OSL_FAIL( "SlideView::setPriority() is a NOOP for slide view - "
     950           0 :                 "content will always be shown in the background" );
     951           0 : }
     952             : 
     953           0 : basegfx::B2DHomMatrix SlideView::getTransformation() const
     954             : {
     955           0 :     osl::MutexGuard aGuard( m_aMutex );
     956             : 
     957           0 :     basegfx::B2DHomMatrix aMatrix;
     958           0 :     aMatrix.scale( 1.0/maUserSize.getX(), 1.0/maUserSize.getY() );
     959             : 
     960           0 :     return maViewTransform * aMatrix;
     961             : }
     962             : 
     963           0 : basegfx::B2DHomMatrix SlideView::getSpriteTransformation() const
     964             : {
     965           0 :     return getTransformation();
     966             : }
     967             : 
     968           0 : void SlideView::setClip( const basegfx::B2DPolyPolygon& rClip )
     969             : {
     970           0 :     osl::MutexGuard aGuard( m_aMutex );
     971             : 
     972           0 :     basegfx::B2DPolyPolygon aNewClip = prepareClip( rClip );
     973             : 
     974           0 :     if( aNewClip != maClip )
     975             :     {
     976           0 :         maClip = aNewClip;
     977             : 
     978           0 :         updateClip();
     979           0 :     }
     980           0 : }
     981             : 
     982           0 : bool SlideView::resize( const ::basegfx::B2DRange& /*rArea*/ )
     983             : {
     984           0 :     osl::MutexGuard aGuard( m_aMutex );
     985             : 
     986             :     OSL_FAIL( "SlideView::resize(): ignored for the View, can't change size "
     987             :                 "effectively, anyway" );
     988             : 
     989           0 :     return false;
     990             : }
     991             : 
     992           0 : uno::Reference<presentation::XSlideShowView> SlideView::getUnoView() const
     993             : {
     994           0 :     osl::MutexGuard aGuard( m_aMutex );
     995           0 :     return mxView;
     996             : }
     997             : 
     998           0 : void SlideView::setIsSoundEnabled (const bool bValue)
     999             : {
    1000           0 :     mbIsSoundEnabled = bValue;
    1001           0 : }
    1002             : 
    1003           0 : bool SlideView::isSoundEnabled (void) const
    1004             : {
    1005           0 :     return mbIsSoundEnabled;
    1006             : }
    1007             : 
    1008           0 : void SlideView::_dispose()
    1009             : {
    1010           0 :     dispose();
    1011           0 : }
    1012             : 
    1013             : // XEventListener
    1014           0 : void SlideView::disposing( lang::EventObject const& evt )
    1015             :     throw (uno::RuntimeException)
    1016             : {
    1017             :     (void)evt;
    1018             : 
    1019             :     // no deregistration necessary anymore, XView has left:
    1020           0 :     osl::MutexGuard const guard( m_aMutex );
    1021             : 
    1022           0 :     if (mxView.is())
    1023             :     {
    1024             :         OSL_ASSERT( evt.Source == mxView );
    1025           0 :         mxView.clear();
    1026             :     }
    1027             : 
    1028           0 :     dispose();
    1029           0 : }
    1030             : 
    1031             : // XModifyListener
    1032           0 : void SlideView::modified( const lang::EventObject& /*aEvent*/ )
    1033             :     throw (uno::RuntimeException)
    1034             : {
    1035           0 :     osl::MutexGuard const guard( m_aMutex );
    1036             : 
    1037             :     OSL_ENSURE( mxView.is(), "SlideView::modified(): "
    1038             :                 "Disposed, but event received from XSlideShowView?!");
    1039             : 
    1040           0 :     if( !mxView.is() )
    1041             :         return;
    1042             : 
    1043             :     geometry::AffineMatrix2D aViewTransform(
    1044           0 :         mxView->getTransformation() );
    1045             : 
    1046           0 :     if( basegfx::fTools::equalZero(
    1047             :             basegfx::B2DVector(aViewTransform.m00,
    1048           0 :                                aViewTransform.m10).getLength()) ||
    1049             :         basegfx::fTools::equalZero(
    1050             :             basegfx::B2DVector(aViewTransform.m01,
    1051           0 :                                aViewTransform.m11).getLength()) )
    1052             :     {
    1053             :         OSL_FAIL( "SlideView::modified(): Singular matrix!" );
    1054             : 
    1055           0 :         canvas::tools::setIdentityAffineMatrix2D(aViewTransform);
    1056             :     }
    1057             : 
    1058             :     // view transformation really changed?
    1059           0 :     basegfx::B2DHomMatrix aNewTransform;
    1060             :     basegfx::unotools::homMatrixFromAffineMatrix(
    1061             :         aNewTransform,
    1062           0 :         aViewTransform );
    1063             : 
    1064           0 :     if( aNewTransform == maViewTransform )
    1065             :         return; // No change, nothing to do
    1066             : 
    1067           0 :     maViewTransform = aNewTransform;
    1068             : 
    1069           0 :     updateCanvas();
    1070             : 
    1071             :     // notify view change. Don't call EventMultiplexer directly, this
    1072             :     // might not be the main thread!
    1073             :     mrEventQueue.addEvent(
    1074             :         makeEvent( boost::bind( (bool (EventMultiplexer::*)(
    1075             :                                      const uno::Reference<presentation::XSlideShowView>&))
    1076             :                                 &EventMultiplexer::notifyViewChanged,
    1077             :                                 boost::ref(mrEventMultiplexer), mxView ),
    1078           0 :                    "EventMultiplexer::notifyViewChanged"));
    1079             : }
    1080             : 
    1081             : // XPaintListener
    1082           0 : void SlideView::windowPaint( const awt::PaintEvent& /*e*/ )
    1083             :     throw (uno::RuntimeException)
    1084             : {
    1085           0 :     osl::MutexGuard aGuard( m_aMutex );
    1086             : 
    1087             :     OSL_ENSURE( mxView.is() && mpCanvas, "Disposed, but event received?!" );
    1088             : 
    1089             :     // notify view clobbering. Don't call EventMultiplexer directly,
    1090             :     // this might not be the main thread!
    1091             :     mrEventQueue.addEvent(
    1092             :         makeEvent( boost::bind( &EventMultiplexer::notifyViewClobbered,
    1093             :                                 boost::ref(mrEventMultiplexer), mxView ),
    1094           0 :                    "EventMultiplexer::notifyViewClobbered") );
    1095           0 : }
    1096             : 
    1097           0 : void SlideView::updateCanvas()
    1098             : {
    1099             :     OSL_ENSURE( mpCanvas,
    1100             :                 "SlideView::updateCanvasTransform(): Disposed" );
    1101             : 
    1102           0 :     if( !mpCanvas || !mxView.is())
    1103           0 :         return;
    1104             : 
    1105           0 :     mpCanvas->clear(); // this is unnecessary, strictly speaking. but
    1106             :                        // it makes the SlideView behave exactly like a
    1107             :                        // sprite-based SlideViewLayer, because those
    1108             :                        // are created from scratch after a resize
    1109           0 :     clearAll();
    1110           0 :     mpCanvas->setTransformation( getTransformation() );
    1111           0 :     mpCanvas->setClip(
    1112             :         createClipPolygon( maClip,
    1113             :                            mpCanvas,
    1114           0 :                            maUserSize ));
    1115             : 
    1116             :     // forward update to viewlayers
    1117           0 :     pruneLayers( true );
    1118             : }
    1119             : 
    1120           0 : void SlideView::updateClip()
    1121             : {
    1122             :     OSL_ENSURE( mpCanvas,
    1123             :                 "SlideView::updateClip(): Disposed" );
    1124             : 
    1125           0 :     if( !mpCanvas )
    1126           0 :         return;
    1127             : 
    1128           0 :     mpCanvas->setClip(
    1129             :         createClipPolygon( maClip,
    1130             :                            mpCanvas,
    1131           0 :                            maUserSize ));
    1132             : 
    1133           0 :     pruneLayers( false );
    1134             : }
    1135             : 
    1136           0 : void SlideView::pruneLayers( bool bWithViewLayerUpdate ) const
    1137             : {
    1138           0 :     ViewLayerVector aValidLayers;
    1139             : 
    1140             :     const basegfx::B2DHomMatrix& rCurrTransform(
    1141           0 :         getTransformation() );
    1142             : 
    1143             :     // check all layers for validity, and retain only the live ones
    1144           0 :     ViewLayerVector::const_iterator       aCurr( maViewLayers.begin() );
    1145           0 :     const ViewLayerVector::const_iterator aEnd( maViewLayers.end() );
    1146           0 :     while( aCurr != aEnd )
    1147             :     {
    1148           0 :         boost::shared_ptr< SlideViewLayer > pCurrLayer( aCurr->lock() );
    1149             : 
    1150           0 :         if( pCurrLayer )
    1151             :         {
    1152           0 :             aValidLayers.push_back( pCurrLayer );
    1153             : 
    1154           0 :             if( bWithViewLayerUpdate )
    1155             :                 pCurrLayer->updateView( rCurrTransform,
    1156           0 :                                         maUserSize );
    1157             :         }
    1158             : 
    1159           0 :         ++aCurr;
    1160           0 :     }
    1161             : 
    1162             :     // replace layer list with pruned one
    1163           0 :     maViewLayers.swap( aValidLayers );
    1164           0 : }
    1165             : 
    1166             : } // anonymous namespace
    1167             : 
    1168           0 : UnoViewSharedPtr createSlideView( uno::Reference< presentation::XSlideShowView> const& xView,
    1169             :                                   EventQueue&                                          rEventQueue,
    1170             :                                   EventMultiplexer&                                    rEventMultiplexer )
    1171             : {
    1172             :     boost::shared_ptr<SlideView> const that(
    1173             :         comphelper::make_shared_from_UNO(
    1174             :             new SlideView(xView,
    1175             :                           rEventQueue,
    1176           0 :                           rEventMultiplexer)));
    1177             : 
    1178             :     // register listeners with XSlideShowView
    1179           0 :     xView->addTransformationChangedListener( that.get() );
    1180           0 :     xView->addPaintListener( that.get() );
    1181             : 
    1182             :     // set new transformation
    1183           0 :     that->updateCanvas();
    1184             : 
    1185           0 :     return that;
    1186             : }
    1187             : 
    1188             : } // namespace internal
    1189           0 : } // namespace slideshow
    1190             : 
    1191             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10