LCOV - code coverage report
Current view: top level - slideshow/source/engine/shapes - drawshape.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 450 0.0 %
Date: 2012-08-25 Functions: 0 54 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : // must be first
      31                 :            : #include <canvas/debug.hxx>
      32                 :            : #include <tools/diagnose_ex.h>
      33                 :            : #include <canvas/verbosetrace.hxx>
      34                 :            : 
      35                 :            : #include <rtl/logfile.hxx>
      36                 :            : #include <osl/diagnose.hxx>
      37                 :            : #include <com/sun/star/awt/Rectangle.hpp>
      38                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      39                 :            : #include <com/sun/star/awt/FontWeight.hpp>
      40                 :            : #include <comphelper/anytostring.hxx>
      41                 :            : #include <cppuhelper/exc_hlp.hxx>
      42                 :            : 
      43                 :            : #include <vcl/metaact.hxx>
      44                 :            : #include <vcl/gdimtf.hxx>
      45                 :            : #include <vcl/wrkwin.hxx>
      46                 :            : 
      47                 :            : #include <basegfx/numeric/ftools.hxx>
      48                 :            : 
      49                 :            : #include <rtl/math.hxx>
      50                 :            : 
      51                 :            : #include <com/sun/star/drawing/TextAnimationKind.hpp>
      52                 :            : 
      53                 :            : #include <vcl/svapp.hxx>
      54                 :            : #include <vcl/window.hxx>
      55                 :            : #include <tools/stream.hxx>
      56                 :            : #include <com/sun/star/frame/XModel.hpp>
      57                 :            : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      58                 :            : #include <com/sun/star/datatransfer/XTransferable.hpp>
      59                 :            : 
      60                 :            : #include <comphelper/scopeguard.hxx>
      61                 :            : #include <canvas/canvastools.hxx>
      62                 :            : 
      63                 :            : #include <cmath> // for trigonometry and fabs
      64                 :            : #include <algorithm>
      65                 :            : #include <functional>
      66                 :            : #include <limits>
      67                 :            : 
      68                 :            : #include "drawshapesubsetting.hxx"
      69                 :            : #include "drawshape.hxx"
      70                 :            : #include "eventqueue.hxx"
      71                 :            : #include "wakeupevent.hxx"
      72                 :            : #include "subsettableshapemanager.hxx"
      73                 :            : #include "intrinsicanimationactivity.hxx"
      74                 :            : #include "slideshowexceptions.hxx"
      75                 :            : #include "tools.hxx"
      76                 :            : #include "gdimtftools.hxx"
      77                 :            : #include "drawinglayeranimation.hxx"
      78                 :            : 
      79                 :            : #include <boost/bind.hpp>
      80                 :            : #include <math.h>
      81                 :            : 
      82                 :            : using namespace ::com::sun::star;
      83                 :            : 
      84                 :            : 
      85                 :            : namespace slideshow
      86                 :            : {
      87                 :            :     namespace internal
      88                 :            :     {
      89                 :            :         //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
      90                 :            :         //metafiles are resolution dependent when bitmaps are contained with is the case for 3D scenes for example
      91                 :            :         //in addition a chart has resolution dependent content as it might skip points that are not visible for a given resolution (this is done for performance reasons)
      92                 :          0 :         bool local_getMetafileForChart( const uno::Reference< lang::XComponent >&     xSource,
      93                 :            :                   const uno::Reference< drawing::XDrawPage >&     xContainingPage,
      94                 :            :                   GDIMetaFile&                                    rMtf )
      95                 :            :         {
      96                 :            :             //get the chart model
      97                 :          0 :             uno::Reference< beans::XPropertySet > xPropSet( xSource, uno::UNO_QUERY );
      98                 :          0 :             uno::Reference< frame::XModel > xChartModel;
      99                 :          0 :             getPropertyValue( xChartModel, xPropSet, OUSTR("Model"));
     100                 :          0 :             uno::Reference< lang::XMultiServiceFactory > xFact( xChartModel, uno::UNO_QUERY );
     101                 :            :             OSL_ENSURE( xFact.is(), "Chart cannot be painted pretty!\n" );
     102                 :          0 :             if(!xFact.is())
     103                 :          0 :                 return false;
     104                 :            : 
     105                 :            :             //get the chart view
     106                 :            :             uno::Reference< datatransfer::XTransferable > xChartViewTransferable(
     107                 :          0 :                 xFact->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.ChartView" ) ) ), uno::UNO_QUERY );
     108                 :          0 :             uno::Reference< beans::XPropertySet > xChartViewProp( xChartViewTransferable, uno::UNO_QUERY );
     109                 :            :             OSL_ENSURE( xChartViewProp.is(), "Chart cannot be painted pretty!\n" );
     110                 :          0 :             if( !xChartViewProp.is() )
     111                 :          0 :                 return false;
     112                 :            : 
     113                 :            :             //estimate zoom and resolution (this is only a workaround, correct would be to know and use the exact zoom and resoltion during slideshow display)
     114                 :          0 :             sal_Int32 nScaleXNumerator = 100;//zoom factor -> exact values are important for the quality of the created bitmap especially for 3D charts
     115                 :          0 :             sal_Int32 nScaleYNumerator = 100;
     116                 :          0 :             sal_Int32 nScaleXDenominator = 100;
     117                 :          0 :             sal_Int32 nScaleYDenominator = 100;
     118                 :          0 :             awt::Size aPixelPerChart( 1000, 1000 );//when data points happen to be on the same pixel as their predecessor no shape is created to safe performance
     119                 :            : 
     120                 :          0 :             Window* pActiveTopWindow( Application::GetActiveTopWindow() );
     121                 :          0 :             WorkWindow* pWorkWindow( dynamic_cast<WorkWindow*>(pActiveTopWindow));
     122                 :          0 :             if( pWorkWindow && pWorkWindow->IsPresentationMode() )
     123                 :            :             {
     124                 :          0 :                 Size aPixScreenSize( pActiveTopWindow->GetOutputSizePixel() );
     125                 :          0 :                 aPixelPerChart = awt::Size( aPixScreenSize.getWidth(), aPixScreenSize.getHeight() );//this is still to much (but costs only seldom performance), correct would be pixel per chart object
     126                 :            : 
     127                 :          0 :                 uno::Reference< beans::XPropertySet > xPageProp( xContainingPage, uno::UNO_QUERY );
     128                 :          0 :                 sal_Int32 nLogicPageWidth=1;
     129                 :          0 :                 sal_Int32 nLogicPageHeight=1;
     130                 :          0 :                 if( getPropertyValue( nLogicPageWidth, xPageProp, OUSTR("Width")) &&
     131                 :          0 :                     getPropertyValue( nLogicPageHeight, xPageProp, OUSTR("Height")) )
     132                 :            :                 {
     133                 :          0 :                     Size aLogicScreenSize( pActiveTopWindow->PixelToLogic( aPixScreenSize, MAP_100TH_MM ) );
     134                 :          0 :                     nScaleXNumerator = aLogicScreenSize.getWidth();
     135                 :          0 :                     nScaleYNumerator = aLogicScreenSize.getHeight();
     136                 :          0 :                     nScaleXDenominator = nLogicPageWidth;
     137                 :          0 :                     nScaleYDenominator = nLogicPageHeight;
     138                 :          0 :                 }
     139                 :            :             }
     140                 :            :             else
     141                 :            :             {
     142                 :          0 :                 long nMaxPixWidth = 0;
     143                 :          0 :                 long nMaxPixHeight = 0;
     144                 :          0 :                 unsigned int nScreenCount( Application::GetScreenCount() );
     145                 :          0 :                 for( unsigned int nScreen=0; nScreen<nScreenCount; nScreen++ )
     146                 :            :                 {
     147                 :          0 :                     Rectangle aCurScreenRect( Application::GetScreenPosSizePixel( nScreen ) );
     148                 :          0 :                     if( aCurScreenRect.GetWidth() > nMaxPixWidth )
     149                 :          0 :                         nMaxPixWidth = aCurScreenRect.GetWidth();
     150                 :          0 :                     if( aCurScreenRect.GetHeight() > nMaxPixHeight )
     151                 :          0 :                         nMaxPixHeight = aCurScreenRect.GetHeight();
     152                 :            :                 }
     153                 :          0 :                 if(nMaxPixWidth>1 && nMaxPixHeight>1)
     154                 :          0 :                     aPixelPerChart = awt::Size( nMaxPixWidth, nMaxPixHeight );//this is still to much (but costs only seldom performance), correct would be pixel per chart object
     155                 :            :             }
     156                 :            : 
     157                 :            :             try
     158                 :            :             {
     159                 :          0 :                 uno::Sequence< beans::PropertyValue > aZoomFactors(4);
     160                 :          0 :                 aZoomFactors[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleXNumerator") );
     161                 :          0 :                 aZoomFactors[0].Value = uno::makeAny( nScaleXNumerator );
     162                 :          0 :                 aZoomFactors[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleXDenominator") );
     163                 :          0 :                 aZoomFactors[1].Value = uno::makeAny( nScaleXDenominator );
     164                 :          0 :                 aZoomFactors[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleYNumerator") );
     165                 :          0 :                 aZoomFactors[2].Value = uno::makeAny( nScaleYNumerator );
     166                 :          0 :                 aZoomFactors[3].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ScaleYDenominator") );
     167                 :          0 :                 aZoomFactors[3].Value = uno::makeAny( nScaleYDenominator );
     168                 :            : 
     169                 :          0 :                 xChartViewProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ZoomFactors") ), uno::makeAny( aZoomFactors ));
     170                 :          0 :                 xChartViewProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Resolution") ), uno::makeAny( aPixelPerChart ));
     171                 :            :             }
     172                 :          0 :             catch (uno::Exception &)
     173                 :            :             {
     174                 :            :                 OSL_FAIL( rtl::OUStringToOString(
     175                 :            :                                 comphelper::anyToString(
     176                 :            :                                     cppu::getCaughtException() ),
     177                 :            :                                 RTL_TEXTENCODING_UTF8 ).getStr() );
     178                 :            :             }
     179                 :            : 
     180                 :            :             //get a metafile from the prepared chart view
     181                 :            :             datatransfer::DataFlavor aDataFlavor(
     182                 :            :                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"") ),
     183                 :            :                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GDIMetaFile" ) ),
     184                 :          0 :                     ::getCppuType( (const uno::Sequence< sal_Int8 >*) 0 ) );
     185                 :          0 :             uno::Any aData( xChartViewTransferable->getTransferData( aDataFlavor ) );
     186                 :          0 :             uno::Sequence< sal_Int8 > aSeq;
     187                 :          0 :             if( aData >>= aSeq )
     188                 :            :             {
     189                 :          0 :                 ::std::auto_ptr< SvMemoryStream > pSrcStm( new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC ) );
     190                 :          0 :                 *(pSrcStm.get() ) >> rMtf;
     191                 :          0 :                 return true;
     192                 :            :             }
     193                 :          0 :             return false;
     194                 :            :         }
     195                 :            : 
     196                 :            :         //same as getMetafile with an exception for charts
     197                 :            :         //for charts a metafile with a higher resolution is created, because charts have resolution dependent content
     198                 :          0 :         bool local_getMetaFile_WithSpecialChartHandling( const uno::Reference< lang::XComponent >&    xSource,
     199                 :            :                   const uno::Reference< drawing::XDrawPage >&     xContainingPage,
     200                 :            :                   GDIMetaFile&                                    rMtf,
     201                 :            :                   int                                             mtfLoadFlags,
     202                 :            :                   const uno::Reference< uno::XComponentContext >& rxContext )
     203                 :            :         {
     204                 :          0 :             uno::Reference<beans::XPropertySet> xProp( xSource, uno::UNO_QUERY );
     205                 :          0 :             rtl::OUString sCLSID;
     206                 :          0 :             getPropertyValue( sCLSID, xProp, OUSTR("CLSID"));
     207                 :          0 :             if( sCLSID == "12DCAE26-281F-416F-a234-c3086127382e" && local_getMetafileForChart( xSource, xContainingPage, rMtf ) )
     208                 :          0 :                 return true;
     209                 :          0 :             return getMetaFile( xSource, xContainingPage, rMtf, mtfLoadFlags, rxContext );
     210                 :            :         }
     211                 :            : 
     212                 :            : 
     213                 :            :         //////////////////////////////////////////////////////////////////////
     214                 :            :         //
     215                 :            :         // Private methods
     216                 :            :         //
     217                 :            :         //////////////////////////////////////////////////////////////////////
     218                 :            : 
     219                 :          0 :         GDIMetaFileSharedPtr DrawShape::forceScrollTextMetaFile()
     220                 :            :         {
     221                 :          0 :             if ((mnCurrMtfLoadFlags & MTF_LOAD_SCROLL_TEXT_MTF) != MTF_LOAD_SCROLL_TEXT_MTF)
     222                 :            :             {
     223                 :            :                 // reload with added flags:
     224                 :          0 :                 mpCurrMtf.reset( new GDIMetaFile );
     225                 :          0 :                 mnCurrMtfLoadFlags |= MTF_LOAD_SCROLL_TEXT_MTF;
     226                 :            :                 local_getMetaFile_WithSpecialChartHandling(
     227                 :            :                     uno::Reference<lang::XComponent>(mxShape, uno::UNO_QUERY),
     228                 :          0 :                     mxPage, *mpCurrMtf, mnCurrMtfLoadFlags,
     229                 :          0 :                     mxComponentContext );
     230                 :            : 
     231                 :            :                 // TODO(F1): Currently, the scroll metafile will
     232                 :            :                 // never contain any verbose text comments. Thus,
     233                 :            :                 // can only display the full mtf content, no
     234                 :            :                 // subsets.
     235                 :          0 :                 maSubsetting.reset( mpCurrMtf );
     236                 :            : 
     237                 :            :                 // adapt maBounds. the requested scroll text metafile
     238                 :            :                 // will typically have dimension different from the
     239                 :            :                 // actual shape
     240                 :          0 :                 ::basegfx::B2DRectangle aScrollRect, aPaintRect;
     241                 :          0 :                 ENSURE_OR_THROW( getRectanglesFromScrollMtf( aScrollRect,
     242                 :            :                                                               aPaintRect,
     243                 :            :                                                               mpCurrMtf ),
     244                 :            :                                   "DrawShape::forceScrollTextMetaFile(): Could "
     245                 :            :                                   "not extract scroll anim rectangles from mtf" );
     246                 :            : 
     247                 :            :                 // take the larger one of the two rectangles (that
     248                 :            :                 // should be the bound rect of the retrieved
     249                 :            :                 // metafile)
     250                 :          0 :                 if( aScrollRect.isInside( aPaintRect ) )
     251                 :          0 :                     maBounds = aScrollRect;
     252                 :            :                 else
     253                 :          0 :                     maBounds = aPaintRect;
     254                 :            :             }
     255                 :          0 :             return mpCurrMtf;
     256                 :            :         }
     257                 :            : 
     258                 :          0 :         void DrawShape::updateStateIds() const
     259                 :            :         {
     260                 :            :             // Update the states, we've just redrawn or created a new
     261                 :            :             // attribute layer.
     262                 :          0 :             if( mpAttributeLayer )
     263                 :            :             {
     264                 :          0 :                 mnAttributeTransformationState = mpAttributeLayer->getTransformationState();
     265                 :          0 :                 mnAttributeClipState = mpAttributeLayer->getClipState();
     266                 :          0 :                 mnAttributeAlphaState = mpAttributeLayer->getAlphaState();
     267                 :          0 :                 mnAttributePositionState = mpAttributeLayer->getPositionState();
     268                 :          0 :                 mnAttributeContentState = mpAttributeLayer->getContentState();
     269                 :          0 :                 mnAttributeVisibilityState = mpAttributeLayer->getVisibilityState();
     270                 :            :             }
     271                 :          0 :         }
     272                 :            : 
     273                 :          0 :         ViewShape::RenderArgs DrawShape::getViewRenderArgs() const
     274                 :            :         {
     275                 :            :             return ViewShape::RenderArgs(
     276                 :            :                 maBounds,
     277                 :          0 :                 getUpdateArea(),
     278                 :          0 :                 getBounds(),
     279                 :            :                 getActualUnitShapeBounds(),
     280                 :            :                 mpAttributeLayer,
     281                 :          0 :                 maSubsetting.getActiveSubsets(),
     282                 :          0 :                 mnPriority);
     283                 :            :         }
     284                 :            : 
     285                 :          0 :         bool DrawShape::implRender( int nUpdateFlags ) const
     286                 :            :         {
     287                 :            :             RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::DrawShape::implRender()" );
     288                 :            :             RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::presentation::internal::DrawShape: 0x%X", this );
     289                 :            : 
     290                 :            :             // will perform the update now, clear update-enforcing
     291                 :            :             // flags
     292                 :          0 :             mbForceUpdate = false;
     293                 :          0 :             mbAttributeLayerRevoked = false;
     294                 :            : 
     295                 :          0 :             ENSURE_OR_RETURN_FALSE( !maViewShapes.empty(),
     296                 :            :                                "DrawShape::implRender(): render called on DrawShape without views" );
     297                 :            : 
     298                 :          0 :             if( maBounds.isEmpty() )
     299                 :            :             {
     300                 :            :                 // zero-sized shapes are effectively invisible,
     301                 :            :                 // thus, we save us the rendering...
     302                 :          0 :                 return true;
     303                 :            :             }
     304                 :            : 
     305                 :            :             // redraw all view shapes, by calling their update() method
     306                 :          0 :             if( ::std::count_if( maViewShapes.begin(),
     307                 :            :                                  maViewShapes.end(),
     308                 :            :                                  ::boost::bind<bool>(
     309                 :            :                                      ::boost::mem_fn( &ViewShape::update ), // though _theoretically_,
     310                 :            :                                                                              // bind should eat this even
     311                 :            :                                                                              // with _1 being a shared_ptr,
     312                 :            :                                                                              // it does _not_ for MSVC without
     313                 :            :                                                                              // the extra mem_fn. WTF.
     314                 :            :                                      _1,
     315                 :            :                                      ::boost::cref( mpCurrMtf ),
     316                 :            :                                      ::boost::cref(
     317                 :            :                                          getViewRenderArgs() ),
     318                 :            :                                      nUpdateFlags,
     319                 :          0 :                                      isVisible() ) )
     320                 :          0 :                 != static_cast<ViewShapeVector::difference_type>(maViewShapes.size()) )
     321                 :            :             {
     322                 :            :                 // at least one of the ViewShape::update() calls did return
     323                 :            :                 // false - update failed on at least one ViewLayer
     324                 :          0 :                 return false;
     325                 :            :             }
     326                 :            : 
     327                 :            :             // successfully redrawn - update state IDs to detect next changes
     328                 :          0 :             updateStateIds();
     329                 :            : 
     330                 :          0 :             return true;
     331                 :            :         }
     332                 :            : 
     333                 :          0 :         int DrawShape::getUpdateFlags() const
     334                 :            :         {
     335                 :            :             // default: update nothing, unless ShapeAttributeStack
     336                 :            :             // tells us below, or if the attribute layer was revoked
     337                 :          0 :             int nUpdateFlags(ViewShape::NONE);
     338                 :            : 
     339                 :            :             // possibly the whole shape content changed
     340                 :          0 :             if( mbAttributeLayerRevoked )
     341                 :          0 :                 nUpdateFlags = ViewShape::CONTENT;
     342                 :            : 
     343                 :            : 
     344                 :            :             // determine what has to be updated
     345                 :            :             // --------------------------------
     346                 :            : 
     347                 :            :             // do we have an attribute layer?
     348                 :          0 :             if( mpAttributeLayer )
     349                 :            :             {
     350                 :            :                 // Prevent nUpdateFlags to be modified when the shape is not
     351                 :            :                 // visible, except when it just was hidden.
     352                 :          0 :                 if (mpAttributeLayer->getVisibility()
     353                 :          0 :                     || mpAttributeLayer->getVisibilityState() != mnAttributeVisibilityState )
     354                 :            :                 {
     355                 :          0 :                     if (mpAttributeLayer->getVisibilityState() != mnAttributeVisibilityState )
     356                 :            :                     {
     357                 :            :                         // Change of the visibility state is mapped to
     358                 :            :                         // content change because when the visibility
     359                 :            :                         // changes then usually a sprite is shown or hidden
     360                 :            :                         // and the background under has to be painted once.
     361                 :          0 :                         nUpdateFlags |= ViewShape::CONTENT;
     362                 :            :                     }
     363                 :            : 
     364                 :            :                     // TODO(P1): This can be done without conditional branching.
     365                 :            :                     // See HAKMEM.
     366                 :          0 :                     if( mpAttributeLayer->getPositionState() != mnAttributePositionState )
     367                 :            :                     {
     368                 :          0 :                         nUpdateFlags |= ViewShape::POSITION;
     369                 :            :                     }
     370                 :          0 :                     if( mpAttributeLayer->getAlphaState() != mnAttributeAlphaState )
     371                 :            :                     {
     372                 :          0 :                         nUpdateFlags |= ViewShape::ALPHA;
     373                 :            :                     }
     374                 :          0 :                     if( mpAttributeLayer->getClipState() != mnAttributeClipState )
     375                 :            :                     {
     376                 :          0 :                         nUpdateFlags |= ViewShape::CLIP;
     377                 :            :                     }
     378                 :          0 :                     if( mpAttributeLayer->getTransformationState() != mnAttributeTransformationState )
     379                 :            :                     {
     380                 :          0 :                         nUpdateFlags |= ViewShape::TRANSFORMATION;
     381                 :            :                     }
     382                 :          0 :                     if( mpAttributeLayer->getContentState() != mnAttributeContentState )
     383                 :            :                     {
     384                 :          0 :                         nUpdateFlags |= ViewShape::CONTENT;
     385                 :            :                     }
     386                 :            :                 }
     387                 :            :             }
     388                 :            : 
     389                 :          0 :             return nUpdateFlags;
     390                 :            :         }
     391                 :            : 
     392                 :          0 :         ::basegfx::B2DRectangle DrawShape::getActualUnitShapeBounds() const
     393                 :            :         {
     394                 :          0 :             ENSURE_OR_THROW( !maViewShapes.empty(),
     395                 :            :                               "DrawShape::getActualUnitShapeBounds(): called on DrawShape without views" );
     396                 :            : 
     397                 :            :             const VectorOfDocTreeNodes& rSubsets(
     398                 :          0 :                 maSubsetting.getActiveSubsets() );
     399                 :            : 
     400                 :          0 :             const ::basegfx::B2DRectangle aDefaultBounds( 0.0,0.0,1.0,1.0 );
     401                 :            : 
     402                 :            :             // perform the cheapest check first
     403                 :          0 :             if( rSubsets.empty() )
     404                 :            :             {
     405                 :            :                 // if subset contains the whole shape, no need to call
     406                 :            :                 // the somewhat expensive bound calculation, since as
     407                 :            :                 // long as the subset is empty, this branch will be
     408                 :            :                 // taken.
     409                 :          0 :                 return aDefaultBounds;
     410                 :            :             }
     411                 :            :             else
     412                 :            :             {
     413                 :            :                 OSL_ENSURE( rSubsets.size() != 1 ||
     414                 :            :                             !rSubsets.front().isEmpty(),
     415                 :            :                             "DrawShape::getActualUnitShapeBounds() expects a "
     416                 :            :                             "_non-empty_ subset vector for a subsetted shape!" );
     417                 :            : 
     418                 :            :                 // are the cached bounds still valid?
     419                 :          0 :                 if( !maCurrentShapeUnitBounds )
     420                 :            :                 {
     421                 :            :                     // no, (re)generate them
     422                 :            :                     // =====================
     423                 :            : 
     424                 :            :                     // setup cached values to defaults (might fail to
     425                 :            :                     // retrieve true bounds below)
     426                 :          0 :                     maCurrentShapeUnitBounds.reset( aDefaultBounds );
     427                 :            : 
     428                 :            :                     // TODO(P2): the subset of the master shape (that from
     429                 :            :                     // which the subsets are subtracted) changes
     430                 :            :                     // relatively often (every time a subset shape is
     431                 :            :                     // added or removed). Maybe we should exclude it here,
     432                 :            :                     // always assuming full bounds?
     433                 :            : 
     434                 :            :                     ::cppcanvas::CanvasSharedPtr pDestinationCanvas(
     435                 :          0 :                         maViewShapes.front()->getViewLayer()->getCanvas() );
     436                 :            : 
     437                 :            :                     // TODO(Q2): Although this _is_ currently
     438                 :            :                     // view-agnostic, it might not stay like
     439                 :            :                     // that. Maybe this method should again be moved
     440                 :            :                     // to the ViewShape
     441                 :            :                     ::cppcanvas::RendererSharedPtr pRenderer(
     442                 :          0 :                         maViewShapes.front()->getRenderer(
     443                 :          0 :                             pDestinationCanvas, mpCurrMtf, mpAttributeLayer ) );
     444                 :            : 
     445                 :            :                     // If we cannot not prefetch, be defensive and assume
     446                 :            :                     // full shape size
     447                 :          0 :                     if( pRenderer )
     448                 :            :                     {
     449                 :            :                         // temporarily, switch total transformation to identity
     450                 :            :                         // (need the bounds in the [0,1]x[0,1] unit coordinate
     451                 :            :                         // system.
     452                 :          0 :                         ::basegfx::B2DHomMatrix      aEmptyTransformation;
     453                 :            : 
     454                 :          0 :                         ::basegfx::B2DHomMatrix      aOldTransform( pDestinationCanvas->getTransformation() );
     455                 :          0 :                         pDestinationCanvas->setTransformation( aEmptyTransformation );
     456                 :          0 :                         pRenderer->setTransformation( aEmptyTransformation );
     457                 :            : 
     458                 :            :                         // restore old transformation when leaving the scope
     459                 :            :                         const ::comphelper::ScopeGuard aGuard(
     460                 :            :                             boost::bind( &::cppcanvas::Canvas::setTransformation,
     461                 :          0 :                                          pDestinationCanvas, aOldTransform ) );
     462                 :            : 
     463                 :            : 
     464                 :            :                         // retrieve bounds for subset of whole metafile
     465                 :            :                         // --------------------------------------------
     466                 :            : 
     467                 :          0 :                         ::basegfx::B2DRange aTotalBounds;
     468                 :            : 
     469                 :            :                         // cannot use ::boost::bind, ::basegfx::B2DRange::expand()
     470                 :            :                         // is overloaded.
     471                 :          0 :                         VectorOfDocTreeNodes::const_iterator        aCurr( rSubsets.begin() );
     472                 :          0 :                         const VectorOfDocTreeNodes::const_iterator  aEnd( rSubsets.end() );
     473                 :          0 :                         while( aCurr != aEnd )
     474                 :            :                         {
     475                 :          0 :                             aTotalBounds.expand( pRenderer->getSubsetArea(
     476                 :            :                                                      aCurr->getStartIndex(),
     477                 :          0 :                                                      aCurr->getEndIndex() )  );
     478                 :          0 :                             ++aCurr;
     479                 :            :                         }
     480                 :            : 
     481                 :            :                         OSL_ENSURE( aTotalBounds.getMinX() >= -0.1 &&
     482                 :            :                                     aTotalBounds.getMinY() >= -0.1 &&
     483                 :            :                                     aTotalBounds.getMaxX() <= 1.1 &&
     484                 :            :                                     aTotalBounds.getMaxY() <= 1.1,
     485                 :            :                                     "DrawShape::getActualUnitShapeBounds(): bounds noticeably larger than original shape - clipping!" );
     486                 :            : 
     487                 :            :                         // really make sure no shape appears larger than its
     488                 :            :                         // original bounds (there _are_ some pathologic cases,
     489                 :            :                         // especially when imported from PPT, that have
     490                 :            :                         // e.g. obscenely large polygon bounds)
     491                 :            :                         aTotalBounds.intersect(
     492                 :            :                             ::basegfx::B2DRange( 0.0, 0.0,
     493                 :          0 :                                                  1.0, 1.0 ));
     494                 :            : 
     495                 :          0 :                         maCurrentShapeUnitBounds.reset( aTotalBounds );
     496                 :          0 :                     }
     497                 :            :                 }
     498                 :            : 
     499                 :          0 :                 return *maCurrentShapeUnitBounds;
     500                 :            :             }
     501                 :            :         }
     502                 :            : 
     503                 :          0 :         DrawShape::DrawShape( const uno::Reference< drawing::XShape >&      xShape,
     504                 :            :                               const uno::Reference< drawing::XDrawPage >&   xContainingPage,
     505                 :            :                               double                                        nPrio,
     506                 :            :                               bool                                          bForeignSource,
     507                 :            :                               const SlideShowContext&                       rContext ) :
     508                 :            :             mxShape( xShape ),
     509                 :            :             mxPage( xContainingPage ),
     510                 :            :             maAnimationFrames(), // empty, we don't have no intrinsic animation
     511                 :            :             mnCurrFrame(0),
     512                 :            :             mpCurrMtf(),
     513                 :            :             mnCurrMtfLoadFlags( bForeignSource
     514                 :            :                                 ? MTF_LOAD_FOREIGN_SOURCE : MTF_LOAD_NONE ),
     515                 :            :             maCurrentShapeUnitBounds(),
     516                 :            :             mnPriority( nPrio ), // TODO(F1): When ZOrder someday becomes usable: make this ( getAPIShapePrio( xShape ) ),
     517                 :            :             maBounds( getAPIShapeBounds( xShape ) ),
     518                 :            :             mpAttributeLayer(),
     519                 :            :             mpIntrinsicAnimationActivity(),
     520                 :            :             mnAttributeTransformationState(0),
     521                 :            :             mnAttributeClipState(0),
     522                 :            :             mnAttributeAlphaState(0),
     523                 :            :             mnAttributePositionState(0),
     524                 :            :             mnAttributeContentState(0),
     525                 :            :             mnAttributeVisibilityState(0),
     526                 :            :             maViewShapes(),
     527                 :            :             mxComponentContext( rContext.mxComponentContext ),
     528                 :            :             maHyperlinkIndices(),
     529                 :            :             maHyperlinkRegions(),
     530                 :            :             maSubsetting(),
     531                 :            :             mnIsAnimatedCount(0),
     532                 :            :             mnAnimationLoopCount(0),
     533                 :            :             meCycleMode(CYCLE_LOOP),
     534                 :            :             mbIsVisible( true ),
     535                 :            :             mbForceUpdate( false ),
     536                 :            :             mbAttributeLayerRevoked( false ),
     537                 :          0 :             mbDrawingLayerAnim( false )
     538                 :            :         {
     539                 :          0 :             ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
     540                 :          0 :             ENSURE_OR_THROW( mxPage.is(), "DrawShape::DrawShape(): Invalid containing page" );
     541                 :            : 
     542                 :            :             // check for drawing layer animations:
     543                 :          0 :             drawing::TextAnimationKind eKind = drawing::TextAnimationKind_NONE;
     544                 :            :             uno::Reference<beans::XPropertySet> xPropSet( mxShape,
     545                 :          0 :                                                           uno::UNO_QUERY );
     546                 :          0 :             if( xPropSet.is() )
     547                 :            :                 getPropertyValue( eKind, xPropSet,
     548                 :          0 :                                   OUSTR("TextAnimationKind") );
     549                 :          0 :             mbDrawingLayerAnim = (eKind != drawing::TextAnimationKind_NONE);
     550                 :            : 
     551                 :            :             // must NOT be called from within initializer list, uses
     552                 :            :             // state from mnCurrMtfLoadFlags!
     553                 :          0 :             mpCurrMtf.reset( new GDIMetaFile );
     554                 :            :             local_getMetaFile_WithSpecialChartHandling(
     555                 :            :                 uno::Reference<lang::XComponent>(xShape, uno::UNO_QUERY),
     556                 :          0 :                 xContainingPage, *mpCurrMtf, mnCurrMtfLoadFlags,
     557                 :          0 :                 mxComponentContext );
     558                 :          0 :             ENSURE_OR_THROW( mpCurrMtf,
     559                 :            :                               "DrawShape::DrawShape(): Invalid metafile" );
     560                 :          0 :             maSubsetting.reset( mpCurrMtf );
     561                 :            : 
     562                 :          0 :             prepareHyperlinkIndices();
     563                 :          0 :         }
     564                 :            : 
     565                 :          0 :         DrawShape::DrawShape( const uno::Reference< drawing::XShape >&      xShape,
     566                 :            :                               const uno::Reference< drawing::XDrawPage >&   xContainingPage,
     567                 :            :                               double                                        nPrio,
     568                 :            :                               const Graphic&                                rGraphic,
     569                 :            :                               const SlideShowContext&                       rContext ) :
     570                 :            :             mxShape( xShape ),
     571                 :            :             mxPage( xContainingPage ),
     572                 :            :             maAnimationFrames(),
     573                 :            :             mnCurrFrame(0),
     574                 :            :             mpCurrMtf(),
     575                 :            :             mnCurrMtfLoadFlags( MTF_LOAD_NONE ),
     576                 :            :             maCurrentShapeUnitBounds(),
     577                 :            :             mnPriority( nPrio ), // TODO(F1): When ZOrder someday becomes usable: make this ( getAPIShapePrio( xShape ) ),
     578                 :            :             maBounds( getAPIShapeBounds( xShape ) ),
     579                 :            :             mpAttributeLayer(),
     580                 :            :             mpIntrinsicAnimationActivity(),
     581                 :            :             mnAttributeTransformationState(0),
     582                 :            :             mnAttributeClipState(0),
     583                 :            :             mnAttributeAlphaState(0),
     584                 :            :             mnAttributePositionState(0),
     585                 :            :             mnAttributeContentState(0),
     586                 :            :             mnAttributeVisibilityState(0),
     587                 :            :             maViewShapes(),
     588                 :            :             mxComponentContext( rContext.mxComponentContext ),
     589                 :            :             maHyperlinkIndices(),
     590                 :            :             maHyperlinkRegions(),
     591                 :            :             maSubsetting(),
     592                 :            :             mnIsAnimatedCount(0),
     593                 :            :             mnAnimationLoopCount(0),
     594                 :            :             meCycleMode(CYCLE_LOOP),
     595                 :            :             mbIsVisible( true ),
     596                 :            :             mbForceUpdate( false ),
     597                 :            :             mbAttributeLayerRevoked( false ),
     598                 :          0 :             mbDrawingLayerAnim( false )
     599                 :            :         {
     600                 :          0 :             ENSURE_OR_THROW( rGraphic.IsAnimated(),
     601                 :            :                               "DrawShape::DrawShape(): Graphic is no animation" );
     602                 :            : 
     603                 :            :             getAnimationFromGraphic( maAnimationFrames,
     604                 :            :                                      mnAnimationLoopCount,
     605                 :            :                                      meCycleMode,
     606                 :          0 :                                      rGraphic );
     607                 :            : 
     608                 :          0 :             ENSURE_OR_THROW( !maAnimationFrames.empty() &&
     609                 :            :                               maAnimationFrames.front().mpMtf,
     610                 :            :                               "DrawShape::DrawShape(): " );
     611                 :          0 :             mpCurrMtf = maAnimationFrames.front().mpMtf;
     612                 :            : 
     613                 :          0 :             ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
     614                 :          0 :             ENSURE_OR_THROW( mxPage.is(), "DrawShape::DrawShape(): Invalid containing page" );
     615                 :          0 :             ENSURE_OR_THROW( mpCurrMtf, "DrawShape::DrawShape(): Invalid metafile" );
     616                 :          0 :         }
     617                 :            : 
     618                 :          0 :         DrawShape::DrawShape( const DrawShape&      rSrc,
     619                 :            :                               const DocTreeNode&    rTreeNode,
     620                 :            :                               double                nPrio ) :
     621                 :            :             mxShape( rSrc.mxShape ),
     622                 :            :             mxPage( rSrc.mxPage ),
     623                 :            :             maAnimationFrames(), // don't copy animations for subsets,
     624                 :            :                                  // only the current frame!
     625                 :            :             mnCurrFrame(0),
     626                 :            :             mpCurrMtf( rSrc.mpCurrMtf ),
     627                 :            :             mnCurrMtfLoadFlags( rSrc.mnCurrMtfLoadFlags ),
     628                 :            :             maCurrentShapeUnitBounds(),
     629                 :            :             mnPriority( nPrio ),
     630                 :            :             maBounds( rSrc.maBounds ),
     631                 :            :             mpAttributeLayer(),
     632                 :            :             mpIntrinsicAnimationActivity(),
     633                 :            :             mnAttributeTransformationState(0),
     634                 :            :             mnAttributeClipState(0),
     635                 :            :             mnAttributeAlphaState(0),
     636                 :            :             mnAttributePositionState(0),
     637                 :            :             mnAttributeContentState(0),
     638                 :            :             mnAttributeVisibilityState(0),
     639                 :            :             maViewShapes(),
     640                 :            :             mxComponentContext( rSrc.mxComponentContext ),
     641                 :            :             maHyperlinkIndices(),
     642                 :            :             maHyperlinkRegions(),
     643                 :            :             maSubsetting( rTreeNode, mpCurrMtf ),
     644                 :            :             mnIsAnimatedCount(0),
     645                 :            :             mnAnimationLoopCount(0),
     646                 :            :             meCycleMode(CYCLE_LOOP),
     647                 :            :             mbIsVisible( rSrc.mbIsVisible ),
     648                 :            :             mbForceUpdate( false ),
     649                 :            :             mbAttributeLayerRevoked( false ),
     650                 :          0 :             mbDrawingLayerAnim( false )
     651                 :            :         {
     652                 :          0 :             ENSURE_OR_THROW( mxShape.is(), "DrawShape::DrawShape(): Invalid XShape" );
     653                 :          0 :             ENSURE_OR_THROW( mpCurrMtf, "DrawShape::DrawShape(): Invalid metafile" );
     654                 :            : 
     655                 :            :             // xxx todo: currently not implemented for subsetted shapes;
     656                 :            :             //           would mean modifying set of hyperlink regions when
     657                 :            :             //           subsetting text portions. N.B.: there's already an
     658                 :            :             //           issue for this #i72828#
     659                 :          0 :         }
     660                 :            : 
     661                 :            :         //////////////////////////////////////////////////////////////////////
     662                 :            :         //
     663                 :            :         // Public methods
     664                 :            :         //
     665                 :            :         //////////////////////////////////////////////////////////////////////
     666                 :            : 
     667                 :          0 :         DrawShapeSharedPtr DrawShape::create(
     668                 :            :             const uno::Reference< drawing::XShape >&    xShape,
     669                 :            :             const uno::Reference< drawing::XDrawPage >& xContainingPage,
     670                 :            :             double                                      nPrio,
     671                 :            :             bool                                        bForeignSource,
     672                 :            :             const SlideShowContext&                     rContext )
     673                 :            :         {
     674                 :            :             DrawShapeSharedPtr pShape( new DrawShape(xShape,
     675                 :            :                                                      xContainingPage,
     676                 :            :                                                      nPrio,
     677                 :            :                                                      bForeignSource,
     678                 :          0 :                                                      rContext) );
     679                 :            : 
     680                 :          0 :             if( pShape->hasIntrinsicAnimation() )
     681                 :            :             {
     682                 :            :                 OSL_ASSERT( pShape->maAnimationFrames.empty() );
     683                 :          0 :                 if( pShape->getNumberOfTreeNodes(
     684                 :          0 :                         DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH) > 0 )
     685                 :            :                 {
     686                 :          0 :                     pShape->mpIntrinsicAnimationActivity =
     687                 :            :                         createDrawingLayerAnimActivity(
     688                 :            :                             rContext,
     689                 :          0 :                             pShape);
     690                 :            :                 }
     691                 :            :             }
     692                 :            : 
     693                 :          0 :             if( pShape->hasHyperlinks() )
     694                 :          0 :                 rContext.mpSubsettableShapeManager->addHyperlinkArea( pShape );
     695                 :            : 
     696                 :          0 :             return pShape;
     697                 :            :         }
     698                 :            : 
     699                 :          0 :         DrawShapeSharedPtr DrawShape::create(
     700                 :            :             const uno::Reference< drawing::XShape >&    xShape,
     701                 :            :             const uno::Reference< drawing::XDrawPage >& xContainingPage,
     702                 :            :             double                                      nPrio,
     703                 :            :             const Graphic&                              rGraphic,
     704                 :            :             const SlideShowContext&                     rContext )
     705                 :            :         {
     706                 :            :             DrawShapeSharedPtr pShape( new DrawShape(xShape,
     707                 :            :                                                      xContainingPage,
     708                 :            :                                                      nPrio,
     709                 :            :                                                      rGraphic,
     710                 :          0 :                                                      rContext) );
     711                 :            : 
     712                 :          0 :             if( pShape->hasIntrinsicAnimation() )
     713                 :            :             {
     714                 :            :                 OSL_ASSERT( !pShape->maAnimationFrames.empty() );
     715                 :            : 
     716                 :          0 :                 std::vector<double> aTimeout;
     717                 :            :                 std::transform(
     718                 :          0 :                     pShape->maAnimationFrames.begin(),
     719                 :          0 :                     pShape->maAnimationFrames.end(),
     720                 :            :                     std::back_insert_iterator< std::vector<double> >( aTimeout ),
     721                 :          0 :                     boost::mem_fn(&MtfAnimationFrame::getDuration) );
     722                 :            : 
     723                 :            :                 WakeupEventSharedPtr pWakeupEvent(
     724                 :          0 :                     new WakeupEvent( rContext.mrEventQueue.getTimer(),
     725                 :          0 :                                      rContext.mrActivitiesQueue ) );
     726                 :            : 
     727                 :            :                 ActivitySharedPtr pActivity =
     728                 :            :                     createIntrinsicAnimationActivity(
     729                 :            :                         rContext,
     730                 :            :                         pShape,
     731                 :            :                         pWakeupEvent,
     732                 :            :                         aTimeout,
     733                 :          0 :                         pShape->mnAnimationLoopCount,
     734                 :          0 :                         pShape->meCycleMode);
     735                 :            : 
     736                 :          0 :                 pWakeupEvent->setActivity( pActivity );
     737                 :          0 :                 pShape->mpIntrinsicAnimationActivity = pActivity;
     738                 :            :             }
     739                 :            : 
     740                 :            :             OSL_ENSURE( !pShape->hasHyperlinks(),
     741                 :            :                         "DrawShape::create(): graphic-only shapes must not have hyperlinks!" );
     742                 :            : 
     743                 :          0 :             return pShape;
     744                 :            :         }
     745                 :            : 
     746                 :          0 :         DrawShape::~DrawShape()
     747                 :            :         {
     748                 :            :             try
     749                 :            :             {
     750                 :            :                 // dispose intrinsic animation activity, else, it will
     751                 :            :                 // linger forever
     752                 :          0 :                 ActivitySharedPtr pActivity( mpIntrinsicAnimationActivity.lock() );
     753                 :          0 :                 if( pActivity )
     754                 :          0 :                     pActivity->dispose();
     755                 :            :             }
     756                 :          0 :             catch (uno::Exception &)
     757                 :            :             {
     758                 :            :                 OSL_FAIL( rtl::OUStringToOString(
     759                 :            :                                 comphelper::anyToString(
     760                 :            :                                     cppu::getCaughtException() ),
     761                 :            :                                 RTL_TEXTENCODING_UTF8 ).getStr() );
     762                 :            :             }
     763                 :          0 :         }
     764                 :            : 
     765                 :          0 :         uno::Reference< drawing::XShape > DrawShape::getXShape() const
     766                 :            :         {
     767                 :          0 :             return mxShape;
     768                 :            :         }
     769                 :            : 
     770                 :          0 :         void DrawShape::addViewLayer( const ViewLayerSharedPtr& rNewLayer,
     771                 :            :                                       bool                      bRedrawLayer )
     772                 :            :         {
     773                 :          0 :             ViewShapeVector::iterator aEnd( maViewShapes.end() );
     774                 :            : 
     775                 :            :             // already added?
     776                 :          0 :             if( ::std::find_if( maViewShapes.begin(),
     777                 :            :                                 aEnd,
     778                 :            :                                 ::boost::bind<bool>(
     779                 :            :                                     ::std::equal_to< ViewLayerSharedPtr >(),
     780                 :            :                                     ::boost::bind( &ViewShape::getViewLayer,
     781                 :            :                                                    _1 ),
     782                 :          0 :                                     ::boost::cref( rNewLayer ) ) ) != aEnd )
     783                 :            :             {
     784                 :            :                 // yes, nothing to do
     785                 :          0 :                 return;
     786                 :            :             }
     787                 :            : 
     788                 :          0 :             ViewShapeSharedPtr pNewShape( new ViewShape( rNewLayer ) );
     789                 :            : 
     790                 :          0 :             maViewShapes.push_back( pNewShape );
     791                 :            : 
     792                 :            :             // pass on animation state
     793                 :          0 :             if( mnIsAnimatedCount )
     794                 :            :             {
     795                 :          0 :                 for( int i=0; i<mnIsAnimatedCount; ++i )
     796                 :          0 :                     pNewShape->enterAnimationMode();
     797                 :            :             }
     798                 :            : 
     799                 :            :             // render the Shape on the newly added ViewLayer
     800                 :          0 :             if( bRedrawLayer )
     801                 :            :             {
     802                 :            :                 pNewShape->update( mpCurrMtf,
     803                 :            :                                    getViewRenderArgs(),
     804                 :            :                                    ViewShape::FORCE,
     805                 :          0 :                                    isVisible() );
     806                 :          0 :             }
     807                 :            :         }
     808                 :            : 
     809                 :          0 :         bool DrawShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
     810                 :            :         {
     811                 :          0 :             const ViewShapeVector::iterator aEnd( maViewShapes.end() );
     812                 :            : 
     813                 :            :             OSL_ENSURE( ::std::count_if(maViewShapes.begin(),
     814                 :            :                                         aEnd,
     815                 :            :                                         ::boost::bind<bool>(
     816                 :            :                                             ::std::equal_to< ViewLayerSharedPtr >(),
     817                 :            :                                             ::boost::bind( &ViewShape::getViewLayer,
     818                 :            :                                                            _1 ),
     819                 :            :                                             ::boost::cref( rLayer ) ) ) < 2,
     820                 :            :                         "DrawShape::removeViewLayer(): Duplicate ViewLayer entries!" );
     821                 :            : 
     822                 :          0 :             ViewShapeVector::iterator aIter;
     823                 :            : 
     824                 :          0 :             if( (aIter=::std::remove_if( maViewShapes.begin(),
     825                 :            :                                          aEnd,
     826                 :            :                                          ::boost::bind<bool>(
     827                 :            :                                              ::std::equal_to< ViewLayerSharedPtr >(),
     828                 :            :                                              ::boost::bind( &ViewShape::getViewLayer,
     829                 :            :                                                             _1 ),
     830                 :          0 :                                              ::boost::cref( rLayer ) ) )) == aEnd )
     831                 :            :             {
     832                 :            :                 // view layer seemingly was not added, failed
     833                 :          0 :                 return false;
     834                 :            :             }
     835                 :            : 
     836                 :            :             // actually erase from container
     837                 :          0 :             maViewShapes.erase( aIter, aEnd );
     838                 :            : 
     839                 :          0 :             return true;
     840                 :            :         }
     841                 :            : 
     842                 :          0 :         bool DrawShape::clearAllViewLayers()
     843                 :            :         {
     844                 :          0 :             maViewShapes.clear();
     845                 :          0 :             return true;
     846                 :            :         }
     847                 :            : 
     848                 :          0 :         bool DrawShape::update() const
     849                 :            :         {
     850                 :          0 :             if( mbForceUpdate )
     851                 :            :             {
     852                 :          0 :                 return render();
     853                 :            :             }
     854                 :            :             else
     855                 :            :             {
     856                 :          0 :                 return implRender( getUpdateFlags() );
     857                 :            :             }
     858                 :            :         }
     859                 :            : 
     860                 :          0 :         bool DrawShape::render() const
     861                 :            :         {
     862                 :            :             // force redraw. Have to also pass on the update flags,
     863                 :            :             // because e.g. content update (regeneration of the
     864                 :            :             // metafile renderer) is normally not performed. A simple
     865                 :            :             // ViewShape::FORCE would only paint the metafile in its
     866                 :            :             // old state.
     867                 :          0 :             return implRender( ViewShape::FORCE | getUpdateFlags() );
     868                 :            :         }
     869                 :            : 
     870                 :          0 :         bool DrawShape::isContentChanged() const
     871                 :            :         {
     872                 :            :             return mbForceUpdate ?
     873                 :            :                 true :
     874                 :          0 :                 getUpdateFlags() != ViewShape::NONE;
     875                 :            :         }
     876                 :            : 
     877                 :            : 
     878                 :          0 :         ::basegfx::B2DRectangle DrawShape::getBounds() const
     879                 :            :         {
     880                 :            :             // little optimization: for non-modified shapes, we don't
     881                 :            :             // create an ShapeAttributeStack, and therefore also don't
     882                 :            :             // have to check it.
     883                 :            :             return getShapePosSize( maBounds,
     884                 :          0 :                                     mpAttributeLayer );
     885                 :            :         }
     886                 :            : 
     887                 :          0 :         ::basegfx::B2DRectangle DrawShape::getDomBounds() const
     888                 :            :         {
     889                 :          0 :             return maBounds;
     890                 :            :         }
     891                 :            : 
     892                 :            :         namespace
     893                 :            :         {
     894                 :            :             /** Functor expanding AA border for each passed ViewShape
     895                 :            : 
     896                 :            :                 Could not use ::boost::bind here, since
     897                 :            :                 B2DRange::expand is overloaded (which yields one or
     898                 :            :                 the other template type deduction ambiguous)
     899                 :            :              */
     900                 :            :             class Expander
     901                 :            :             {
     902                 :            :             public:
     903                 :          0 :                 Expander( ::basegfx::B2DSize& rBounds ) :
     904                 :          0 :                     mrBounds( rBounds )
     905                 :            :                 {
     906                 :          0 :                 }
     907                 :            : 
     908                 :          0 :                 void operator()( const ViewShapeSharedPtr& rShape ) const
     909                 :            :                 {
     910                 :          0 :                     const ::basegfx::B2DSize& rShapeBorder( rShape->getAntialiasingBorder() );
     911                 :            : 
     912                 :            :                     mrBounds.setX(
     913                 :            :                         ::std::max(
     914                 :          0 :                             rShapeBorder.getX(),
     915                 :          0 :                             mrBounds.getX() ) );
     916                 :            :                     mrBounds.setY(
     917                 :            :                         ::std::max(
     918                 :          0 :                             rShapeBorder.getY(),
     919                 :          0 :                             mrBounds.getY() ) );
     920                 :          0 :                 }
     921                 :            : 
     922                 :            :             private:
     923                 :            :                 ::basegfx::B2DSize& mrBounds;
     924                 :            :             };
     925                 :            :         }
     926                 :            : 
     927                 :          0 :         ::basegfx::B2DRectangle DrawShape::getUpdateArea() const
     928                 :            :         {
     929                 :          0 :             ::basegfx::B2DRectangle aBounds;
     930                 :            : 
     931                 :            :             // an already empty shape bound need no further
     932                 :            :             // treatment. In fact, any changes applied below would
     933                 :            :             // actually remove the special empty state, thus, don't
     934                 :            :             // change!
     935                 :          0 :             if( !maBounds.isEmpty() )
     936                 :            :             {
     937                 :          0 :                 basegfx::B2DRectangle aUnitBounds(0.0,0.0,1.0,1.0);
     938                 :            : 
     939                 :          0 :                 if( !maViewShapes.empty() )
     940                 :          0 :                     aUnitBounds = getActualUnitShapeBounds();
     941                 :            : 
     942                 :          0 :                 if( !aUnitBounds.isEmpty() )
     943                 :            :                 {
     944                 :          0 :                     if( mpAttributeLayer )
     945                 :            :                     {
     946                 :            :                         // calc actual shape area (in user coordinate
     947                 :            :                         // space) from the transformation as given by the
     948                 :            :                         // shape attribute layer
     949                 :            :                         aBounds = getShapeUpdateArea( aUnitBounds,
     950                 :          0 :                                                       getShapeTransformation( getBounds(),
     951                 :            :                                                                               mpAttributeLayer ),
     952                 :          0 :                                                       mpAttributeLayer );
     953                 :            :                     }
     954                 :            :                     else
     955                 :            :                     {
     956                 :            :                         // no attribute layer, thus, the true shape bounds
     957                 :            :                         // can be directly derived from the XShape bound
     958                 :            :                         // attribute
     959                 :            :                         aBounds = getShapeUpdateArea( aUnitBounds,
     960                 :          0 :                                                       maBounds );
     961                 :            :                     }
     962                 :            : 
     963                 :          0 :                     if( !maViewShapes.empty() )
     964                 :            :                     {
     965                 :            :                         // determine border needed for antialiasing the shape
     966                 :          0 :                         ::basegfx::B2DSize aAABorder(0.0,0.0);
     967                 :            : 
     968                 :            :                         // for every view, get AA border and 'expand' aAABorder
     969                 :            :                         // appropriately.
     970                 :            :                         ::std::for_each( maViewShapes.begin(),
     971                 :            :                                          maViewShapes.end(),
     972                 :          0 :                                          Expander( aAABorder ) );
     973                 :            : 
     974                 :            :                         // add calculated AA border to aBounds
     975                 :          0 :                         aBounds = ::basegfx::B2DRectangle( aBounds.getMinX() - aAABorder.getX(),
     976                 :          0 :                                                            aBounds.getMinY() - aAABorder.getY(),
     977                 :          0 :                                                            aBounds.getMaxX() + aAABorder.getX(),
     978                 :          0 :                                                            aBounds.getMaxY() + aAABorder.getY() );
     979                 :            :                     }
     980                 :            :                 }
     981                 :            :             }
     982                 :            : 
     983                 :          0 :             return aBounds;
     984                 :            :         }
     985                 :            : 
     986                 :          0 :         bool DrawShape::isVisible() const
     987                 :            :         {
     988                 :          0 :             bool bIsVisible( mbIsVisible );
     989                 :            : 
     990                 :          0 :             if( mpAttributeLayer )
     991                 :            :             {
     992                 :            :                 // check whether visibility and alpha are not default
     993                 :            :                 // (mpAttributeLayer->isVisibilityValid() returns true
     994                 :            :                 // then): bVisible becomes true, if shape visibility
     995                 :            :                 // is on and alpha is not 0.0 (fully transparent)
     996                 :          0 :                 if( mpAttributeLayer->isVisibilityValid() )
     997                 :          0 :                     bIsVisible = mpAttributeLayer->getVisibility();
     998                 :            : 
     999                 :            :                 // only touch bIsVisible, if the shape is still
    1000                 :            :                 // visible - if getVisibility already made us
    1001                 :            :                 // invisible, no alpha value will make us appear
    1002                 :            :                 // again.
    1003                 :          0 :                 if( bIsVisible && mpAttributeLayer->isAlphaValid() )
    1004                 :          0 :                     bIsVisible = !::basegfx::fTools::equalZero( mpAttributeLayer->getAlpha() );
    1005                 :            :             }
    1006                 :            : 
    1007                 :          0 :             return bIsVisible;
    1008                 :            :         }
    1009                 :            : 
    1010                 :          0 :         double DrawShape::getPriority() const
    1011                 :            :         {
    1012                 :          0 :             return mnPriority;
    1013                 :            :         }
    1014                 :            : 
    1015                 :          0 :         bool DrawShape::isBackgroundDetached() const
    1016                 :            :         {
    1017                 :          0 :             return mnIsAnimatedCount > 0;
    1018                 :            :         }
    1019                 :            : 
    1020                 :          0 :         bool DrawShape::hasIntrinsicAnimation() const
    1021                 :            :         {
    1022                 :          0 :             return (!maAnimationFrames.empty() || mbDrawingLayerAnim);
    1023                 :            :         }
    1024                 :            : 
    1025                 :          0 :         bool DrawShape::setIntrinsicAnimationFrame( ::std::size_t nCurrFrame )
    1026                 :            :         {
    1027                 :          0 :             ENSURE_OR_RETURN_FALSE( nCurrFrame < maAnimationFrames.size(),
    1028                 :            :                                "DrawShape::setIntrinsicAnimationFrame(): frame index out of bounds" );
    1029                 :            : 
    1030                 :          0 :             if( mnCurrFrame != nCurrFrame )
    1031                 :            :             {
    1032                 :          0 :                 mnCurrFrame   = nCurrFrame;
    1033                 :          0 :                 mpCurrMtf     = maAnimationFrames[ mnCurrFrame ].mpMtf;
    1034                 :          0 :                 mbForceUpdate = true;
    1035                 :            :             }
    1036                 :            : 
    1037                 :          0 :             return true;
    1038                 :            :         }
    1039                 :            : 
    1040                 :            :         // hyperlink support
    1041                 :          0 :         void DrawShape::prepareHyperlinkIndices() const
    1042                 :            :         {
    1043                 :          0 :             if ( !maHyperlinkIndices.empty())
    1044                 :            :             {
    1045                 :          0 :                 maHyperlinkIndices.clear();
    1046                 :          0 :                 maHyperlinkRegions.clear();
    1047                 :            :             }
    1048                 :            : 
    1049                 :          0 :             sal_Int32 nIndex = 0;
    1050                 :          0 :             for ( MetaAction * pCurrAct = mpCurrMtf->FirstAction();
    1051                 :          0 :                   pCurrAct != 0; pCurrAct = mpCurrMtf->NextAction() )
    1052                 :            :             {
    1053                 :          0 :                 if (pCurrAct->GetType() == META_COMMENT_ACTION) {
    1054                 :            :                     MetaCommentAction * pAct =
    1055                 :          0 :                         static_cast<MetaCommentAction *>(pCurrAct);
    1056                 :            :                     // skip comment if not a special XTEXT comment
    1057                 :          0 :                     if (pAct->GetComment().equalsIgnoreAsciiCaseL(
    1058                 :          0 :                             RTL_CONSTASCII_STRINGPARAM("FIELD_SEQ_BEGIN") ) &&
    1059                 :            :                         // e.g. date field doesn't have data!
    1060                 :            :                         // currently assuming that only url field, this is
    1061                 :            :                         // somehow fragile! xxx todo if possible
    1062                 :          0 :                         pAct->GetData() != 0 &&
    1063                 :          0 :                         pAct->GetDataSize() > 0)
    1064                 :            :                     {
    1065                 :          0 :                         if (!maHyperlinkIndices.empty() &&
    1066                 :          0 :                             maHyperlinkIndices.back().second == -1) {
    1067                 :            :                             OSL_FAIL( "### pending FIELD_SEQ_END!" );
    1068                 :          0 :                             maHyperlinkIndices.pop_back();
    1069                 :          0 :                             maHyperlinkRegions.pop_back();
    1070                 :            :                         }
    1071                 :            :                         maHyperlinkIndices.push_back(
    1072                 :            :                             HyperlinkIndexPair( nIndex + 1,
    1073                 :          0 :                                                 -1 /* to be filled below */ ) );
    1074                 :            :                         maHyperlinkRegions.push_back(
    1075                 :            :                             HyperlinkRegion(
    1076                 :            :                                 basegfx::B2DRectangle(),
    1077                 :            :                                 rtl::OUString(
    1078                 :            :                                     reinterpret_cast<sal_Unicode const*>(
    1079                 :          0 :                                         pAct->GetData()),
    1080                 :          0 :                                     pAct->GetDataSize() / sizeof(sal_Unicode) )
    1081                 :          0 :                                 ) );
    1082                 :            :                     }
    1083                 :          0 :                     else if (pAct->GetComment().equalsIgnoreAsciiCaseL(
    1084                 :          0 :                                  RTL_CONSTASCII_STRINGPARAM("FIELD_SEQ_END")) &&
    1085                 :            :                              // pending end is expected:
    1086                 :          0 :                              !maHyperlinkIndices.empty() &&
    1087                 :          0 :                              maHyperlinkIndices.back().second == -1)
    1088                 :            :                     {
    1089                 :          0 :                         maHyperlinkIndices.back().second = nIndex;
    1090                 :            :                     }
    1091                 :          0 :                     ++nIndex;
    1092                 :            :                 }
    1093                 :            :                 else
    1094                 :          0 :                     nIndex += getNextActionOffset(pCurrAct);
    1095                 :            :             }
    1096                 :          0 :             if (!maHyperlinkIndices.empty() &&
    1097                 :          0 :                 maHyperlinkIndices.back().second == -1) {
    1098                 :            :                 OSL_FAIL( "### pending FIELD_SEQ_END!" );
    1099                 :          0 :                 maHyperlinkIndices.pop_back();
    1100                 :          0 :                 maHyperlinkRegions.pop_back();
    1101                 :            :             }
    1102                 :            :             OSL_ASSERT( maHyperlinkIndices.size() == maHyperlinkRegions.size());
    1103                 :          0 :         }
    1104                 :            : 
    1105                 :          0 :         bool DrawShape::hasHyperlinks() const
    1106                 :            :         {
    1107                 :          0 :             return ! maHyperlinkRegions.empty();
    1108                 :            :         }
    1109                 :            : 
    1110                 :          0 :         HyperlinkArea::HyperlinkRegions DrawShape::getHyperlinkRegions() const
    1111                 :            :         {
    1112                 :            :             OSL_ASSERT( !maViewShapes.empty() );
    1113                 :            : 
    1114                 :          0 :             if( !isVisible() )
    1115                 :          0 :                 return HyperlinkArea::HyperlinkRegions();
    1116                 :            : 
    1117                 :            :             // late init, determine regions:
    1118                 :          0 :             if( !maHyperlinkRegions.empty() &&
    1119                 :          0 :                 !maViewShapes.empty() &&
    1120                 :            :                 // region already inited?
    1121                 :          0 :                 maHyperlinkRegions.front().first.getWidth() == 0 &&
    1122                 :          0 :                 maHyperlinkRegions.front().first.getHeight() == 0 &&
    1123                 :          0 :                 maHyperlinkRegions.size() == maHyperlinkIndices.size() )
    1124                 :            :             {
    1125                 :            :                 // TODO(Q2): Although this _is_ currently
    1126                 :            :                 // view-agnostic, it might not stay like that.
    1127                 :          0 :                 ViewShapeSharedPtr const& pViewShape = maViewShapes.front();
    1128                 :            :                 cppcanvas::CanvasSharedPtr const pCanvas(
    1129                 :          0 :                     pViewShape->getViewLayer()->getCanvas() );
    1130                 :            : 
    1131                 :            :                 // reuse Renderer of first view shape:
    1132                 :            :                 cppcanvas::RendererSharedPtr const pRenderer(
    1133                 :            :                     pViewShape->getRenderer(
    1134                 :          0 :                         pCanvas, mpCurrMtf, mpAttributeLayer ) );
    1135                 :            : 
    1136                 :            :                 OSL_ASSERT( pRenderer );
    1137                 :            : 
    1138                 :          0 :                 if (pRenderer)
    1139                 :            :                 {
    1140                 :            :                     basegfx::B2DHomMatrix const aOldTransform(
    1141                 :          0 :                         pCanvas->getTransformation() );
    1142                 :          0 :                     basegfx::B2DHomMatrix aTransform;
    1143                 :          0 :                     pCanvas->setTransformation( aTransform /* empty */ );
    1144                 :            : 
    1145                 :            :                     comphelper::ScopeGuard const resetOldTransformation(
    1146                 :            :                         boost::bind( &cppcanvas::Canvas::setTransformation,
    1147                 :            :                                      pCanvas.get(),
    1148                 :          0 :                                      boost::cref(aOldTransform) ));
    1149                 :            : 
    1150                 :            :                     aTransform.scale( maBounds.getWidth(),
    1151                 :          0 :                                       maBounds.getHeight() );
    1152                 :          0 :                     pRenderer->setTransformation( aTransform );
    1153                 :          0 :                     pRenderer->setClip();
    1154                 :            : 
    1155                 :          0 :                     for( std::size_t pos = maHyperlinkRegions.size(); pos--; )
    1156                 :            :                     {
    1157                 :            :                         // get region:
    1158                 :          0 :                         HyperlinkIndexPair const& rIndices = maHyperlinkIndices[pos];
    1159                 :            :                         basegfx::B2DRectangle const region(
    1160                 :          0 :                             pRenderer->getSubsetArea( rIndices.first,
    1161                 :          0 :                                                       rIndices.second ));
    1162                 :          0 :                         maHyperlinkRegions[pos].first = region;
    1163                 :          0 :                     }
    1164                 :          0 :                 }
    1165                 :            :             }
    1166                 :            : 
    1167                 :            :             // shift shape-relative hyperlink regions to
    1168                 :            :             // slide-absolute position
    1169                 :            : 
    1170                 :          0 :             HyperlinkRegions aTranslatedRegions;
    1171                 :          0 :             const basegfx::B2DPoint& rOffset(getBounds().getMinimum());
    1172                 :          0 :             HyperlinkRegions::const_iterator       aIter( maHyperlinkRegions.begin() );
    1173                 :          0 :             HyperlinkRegions::const_iterator const aEnd ( maHyperlinkRegions.end() );
    1174                 :          0 :             while( aIter != aEnd )
    1175                 :            :             {
    1176                 :          0 :                 basegfx::B2DRange const& relRegion( aIter->first );
    1177                 :            :                 aTranslatedRegions.push_back(
    1178                 :            :                     std::make_pair(
    1179                 :            :                         basegfx::B2DRange(
    1180                 :            :                             relRegion.getMinimum() + rOffset,
    1181                 :            :                             relRegion.getMaximum() + rOffset),
    1182                 :          0 :                         aIter->second) );
    1183                 :          0 :                 ++aIter;
    1184                 :            :             }
    1185                 :            : 
    1186                 :          0 :             return aTranslatedRegions;
    1187                 :            :         }
    1188                 :            : 
    1189                 :          0 :         double DrawShape::getHyperlinkPriority() const
    1190                 :            :         {
    1191                 :          0 :             return getPriority();
    1192                 :            :         }
    1193                 :            : 
    1194                 :            : 
    1195                 :            :         // AnimatableShape methods
    1196                 :            :         // ======================================================
    1197                 :            : 
    1198                 :          0 :         void DrawShape::enterAnimationMode()
    1199                 :            :         {
    1200                 :            :             OSL_ENSURE( !maViewShapes.empty(),
    1201                 :            :                         "DrawShape::enterAnimationMode(): called on DrawShape without views" );
    1202                 :            : 
    1203                 :          0 :             if( mnIsAnimatedCount == 0 )
    1204                 :            :             {
    1205                 :            :                 // notify all ViewShapes, by calling their enterAnimationMode method.
    1206                 :            :                 // We're now entering animation mode
    1207                 :            :                 ::std::for_each( maViewShapes.begin(),
    1208                 :            :                                  maViewShapes.end(),
    1209                 :          0 :                                  ::boost::mem_fn( &ViewShape::enterAnimationMode ) );
    1210                 :            :             }
    1211                 :            : 
    1212                 :          0 :             ++mnIsAnimatedCount;
    1213                 :          0 :         }
    1214                 :            : 
    1215                 :          0 :         void DrawShape::leaveAnimationMode()
    1216                 :            :         {
    1217                 :            :             OSL_ENSURE( !maViewShapes.empty(),
    1218                 :            :                         "DrawShape::leaveAnimationMode(): called on DrawShape without views" );
    1219                 :            : 
    1220                 :          0 :             --mnIsAnimatedCount;
    1221                 :            : 
    1222                 :          0 :             if( mnIsAnimatedCount == 0 )
    1223                 :            :             {
    1224                 :            :                 // notify all ViewShapes, by calling their leaveAnimationMode method.
    1225                 :            :                 // we're now leaving animation mode
    1226                 :            :                 ::std::for_each( maViewShapes.begin(),
    1227                 :            :                                  maViewShapes.end(),
    1228                 :          0 :                                  ::boost::mem_fn( &ViewShape::leaveAnimationMode ) );
    1229                 :            :             }
    1230                 :          0 :         }
    1231                 :            : 
    1232                 :            : 
    1233                 :            :         // AttributableShape methods
    1234                 :            :         // ======================================================
    1235                 :            : 
    1236                 :          0 :         ShapeAttributeLayerSharedPtr DrawShape::createAttributeLayer()
    1237                 :            :         {
    1238                 :            :             // create new layer, with last as its new child
    1239                 :          0 :             mpAttributeLayer.reset( new ShapeAttributeLayer( mpAttributeLayer ) );
    1240                 :            : 
    1241                 :            :             // Update the local state ids to reflect those of the new layer.
    1242                 :          0 :             updateStateIds();
    1243                 :            : 
    1244                 :          0 :             return mpAttributeLayer;
    1245                 :            :         }
    1246                 :            : 
    1247                 :          0 :         bool DrawShape::revokeAttributeLayer( const ShapeAttributeLayerSharedPtr& rLayer )
    1248                 :            :         {
    1249                 :          0 :             if( !mpAttributeLayer )
    1250                 :          0 :                 return false; // no layers
    1251                 :            : 
    1252                 :          0 :             if( mpAttributeLayer == rLayer )
    1253                 :            :             {
    1254                 :            :                 // it's the toplevel layer
    1255                 :          0 :                 mpAttributeLayer = mpAttributeLayer->getChildLayer();
    1256                 :            : 
    1257                 :            :                 // force content redraw, all state variables have
    1258                 :            :                 // possibly changed
    1259                 :          0 :                 mbAttributeLayerRevoked = true;
    1260                 :            : 
    1261                 :          0 :                 return true;
    1262                 :            :             }
    1263                 :            :             else
    1264                 :            :             {
    1265                 :            :                 // pass on to the layer, to try its children
    1266                 :          0 :                 return mpAttributeLayer->revokeChildLayer( rLayer );
    1267                 :            :             }
    1268                 :            :         }
    1269                 :            : 
    1270                 :          0 :         ShapeAttributeLayerSharedPtr DrawShape::getTopmostAttributeLayer() const
    1271                 :            :         {
    1272                 :          0 :             return mpAttributeLayer;
    1273                 :            :         }
    1274                 :            : 
    1275                 :          0 :         void DrawShape::setVisibility( bool bVisible )
    1276                 :            :         {
    1277                 :          0 :             if( mbIsVisible != bVisible )
    1278                 :            :             {
    1279                 :          0 :                 mbIsVisible = bVisible;
    1280                 :          0 :                 mbForceUpdate = true;
    1281                 :            :             }
    1282                 :          0 :         }
    1283                 :            : 
    1284                 :          0 :         const DocTreeNodeSupplier& DrawShape::getTreeNodeSupplier() const
    1285                 :            :         {
    1286                 :          0 :             return *this;
    1287                 :            :         }
    1288                 :            : 
    1289                 :          0 :         DocTreeNodeSupplier& DrawShape::getTreeNodeSupplier()
    1290                 :            :         {
    1291                 :          0 :             return *this;
    1292                 :            :         }
    1293                 :            : 
    1294                 :          0 :         DocTreeNode DrawShape::getSubsetNode() const
    1295                 :            :         {
    1296                 :            :             // forward to delegate
    1297                 :          0 :             return maSubsetting.getSubsetNode();
    1298                 :            :         }
    1299                 :            : 
    1300                 :          0 :         AttributableShapeSharedPtr DrawShape::getSubset( const DocTreeNode& rTreeNode ) const
    1301                 :            :         {
    1302                 :            :             // forward to delegate
    1303                 :          0 :             return maSubsetting.getSubsetShape( rTreeNode );
    1304                 :            :         }
    1305                 :            : 
    1306                 :          0 :         bool DrawShape::createSubset( AttributableShapeSharedPtr&   o_rSubset,
    1307                 :            :                                       const DocTreeNode&            rTreeNode )
    1308                 :            :         {
    1309                 :            :             // subset shape already created for this DocTreeNode?
    1310                 :          0 :             AttributableShapeSharedPtr pSubset( maSubsetting.getSubsetShape( rTreeNode ) );
    1311                 :            : 
    1312                 :            :             // when true, this method has created a new subset
    1313                 :            :             // DrawShape
    1314                 :          0 :             bool bNewlyCreated( false );
    1315                 :            : 
    1316                 :          0 :             if( pSubset )
    1317                 :            :             {
    1318                 :          0 :                 o_rSubset = pSubset;
    1319                 :            : 
    1320                 :            :                 // reusing existing subset
    1321                 :            :             }
    1322                 :            :             else
    1323                 :            :             {
    1324                 :            :                 // not yet created, init entry
    1325                 :            :                 o_rSubset.reset( new DrawShape( *this,
    1326                 :            :                                                 rTreeNode,
    1327                 :            :                                                 // TODO(Q3): That's a
    1328                 :            :                                                 // hack. We assume
    1329                 :            :                                                 // that start and end
    1330                 :            :                                                 // index will always
    1331                 :            :                                                 // be less than 65535
    1332                 :            :                                                 mnPriority +
    1333                 :          0 :                                                 rTreeNode.getStartIndex()/double(SAL_MAX_INT16) ));
    1334                 :            : 
    1335                 :          0 :                 bNewlyCreated = true; // subset newly created
    1336                 :            :             }
    1337                 :            : 
    1338                 :            :             // always register shape at DrawShapeSubsetting, to keep
    1339                 :            :             // refcount up-to-date
    1340                 :          0 :             maSubsetting.addSubsetShape( o_rSubset );
    1341                 :            : 
    1342                 :            :             // flush bounds cache
    1343                 :          0 :             maCurrentShapeUnitBounds.reset();
    1344                 :            : 
    1345                 :          0 :             return bNewlyCreated;
    1346                 :            :         }
    1347                 :            : 
    1348                 :          0 :         bool DrawShape::revokeSubset( const AttributableShapeSharedPtr& rShape )
    1349                 :            :         {
    1350                 :            :             // flush bounds cache
    1351                 :          0 :             maCurrentShapeUnitBounds.reset();
    1352                 :            : 
    1353                 :            :             // forward to delegate
    1354                 :          0 :             if( maSubsetting.revokeSubsetShape( rShape ) )
    1355                 :            :             {
    1356                 :            :                 // force redraw, our content has possibly changed (as
    1357                 :            :                 // one of the subsets now display within our shape
    1358                 :            :                 // again).
    1359                 :          0 :                 mbForceUpdate = true;
    1360                 :            : 
    1361                 :            :                 // #i47428# TEMP FIX: synchronize visibility of subset
    1362                 :            :                 // with parent.
    1363                 :            : 
    1364                 :            :                 // TODO(F3): Remove here, and implement
    1365                 :            :                 // TEXT_ONLY/BACKGROUND_ONLY with the proverbial
    1366                 :            :                 // additional level of indirection: create a
    1367                 :            :                 // persistent subset, containing all text/only the
    1368                 :            :                 // background respectively. From _that_ object,
    1369                 :            :                 // generate the temporary character subset shapes.
    1370                 :            :                 const ShapeAttributeLayerSharedPtr& rAttrLayer(
    1371                 :          0 :                     rShape->getTopmostAttributeLayer() );
    1372                 :          0 :                 if( rAttrLayer &&
    1373                 :          0 :                     rAttrLayer->isVisibilityValid() &&
    1374                 :          0 :                     rAttrLayer->getVisibility() != isVisible() )
    1375                 :            :                 {
    1376                 :          0 :                     const bool bVisibility( rAttrLayer->getVisibility() );
    1377                 :            : 
    1378                 :            :                     // visibilities differ - adjust ours, then
    1379                 :          0 :                     if( mpAttributeLayer )
    1380                 :          0 :                         mpAttributeLayer->setVisibility( bVisibility );
    1381                 :            :                     else
    1382                 :          0 :                         mbIsVisible = bVisibility;
    1383                 :            :                 }
    1384                 :            : 
    1385                 :            :                 // END TEMP FIX
    1386                 :            : 
    1387                 :          0 :                 return true;
    1388                 :            :             }
    1389                 :            : 
    1390                 :          0 :             return false;
    1391                 :            :         }
    1392                 :            : 
    1393                 :          0 :         sal_Int32 DrawShape::getNumberOfTreeNodes( DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
    1394                 :            :         {
    1395                 :          0 :             return maSubsetting.getNumberOfTreeNodes( eNodeType );
    1396                 :            :         }
    1397                 :            : 
    1398                 :          0 :         DocTreeNode DrawShape::getTreeNode( sal_Int32               nNodeIndex,
    1399                 :            :                                             DocTreeNode::NodeType   eNodeType ) const // throw ShapeLoadFailedException
    1400                 :            :         {
    1401                 :          0 :             if ( hasHyperlinks())
    1402                 :            :             {
    1403                 :          0 :                 prepareHyperlinkIndices();
    1404                 :            :             }
    1405                 :            : 
    1406                 :          0 :             return maSubsetting.getTreeNode( nNodeIndex, eNodeType );
    1407                 :            :         }
    1408                 :            : 
    1409                 :          0 :         sal_Int32 DrawShape::getNumberOfSubsetTreeNodes ( const DocTreeNode&    rParentNode,
    1410                 :            :                                                           DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
    1411                 :            :         {
    1412                 :          0 :             return maSubsetting.getNumberOfSubsetTreeNodes( rParentNode, eNodeType );
    1413                 :            :         }
    1414                 :            : 
    1415                 :          0 :         DocTreeNode DrawShape::getSubsetTreeNode( const DocTreeNode&    rParentNode,
    1416                 :            :                                                   sal_Int32             nNodeIndex,
    1417                 :            :                                                   DocTreeNode::NodeType eNodeType ) const // throw ShapeLoadFailedException
    1418                 :            :         {
    1419                 :          0 :             return maSubsetting.getSubsetTreeNode( rParentNode, nNodeIndex, eNodeType );
    1420                 :            :         }
    1421                 :            :     }
    1422                 :          0 : }
    1423                 :            : 
    1424                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10