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