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