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

Generated by: LCOV version 1.10