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

Generated by: LCOV version 1.11