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

Generated by: LCOV version 1.10