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_drawinglayer.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <drawinglayer/primitive2d/controlprimitive2d.hxx>
32*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
33*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
34*cdf0e10cSrcweir #include <com/sun/star/awt/XWindow2.hpp>
35*cdf0e10cSrcweir #include <drawinglayer/geometry/viewinformation2d.hxx>
36*cdf0e10cSrcweir #include <vcl/virdev.hxx>
37*cdf0e10cSrcweir #include <vcl/svapp.hxx>
38*cdf0e10cSrcweir #include <com/sun/star/awt/PosSize.hpp>
39*cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
40*cdf0e10cSrcweir #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
41*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
42*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
43*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
44*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
45*cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
46*cdf0e10cSrcweir #include <svtools/optionsdrawinglayer.hxx>
47*cdf0e10cSrcweir #include <toolkit/awt/vclxwindow.hxx>
48*cdf0e10cSrcweir #include <vcl/window.hxx>
49*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir using namespace com::sun::star;
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir namespace drawinglayer
58*cdf0e10cSrcweir {
59*cdf0e10cSrcweir 	namespace primitive2d
60*cdf0e10cSrcweir 	{
61*cdf0e10cSrcweir 		void ControlPrimitive2D::createXControl()
62*cdf0e10cSrcweir 		{
63*cdf0e10cSrcweir 			if(!mxXControl.is() && getControlModel().is())
64*cdf0e10cSrcweir 			{
65*cdf0e10cSrcweir 				uno::Reference< beans::XPropertySet > xSet(getControlModel(), uno::UNO_QUERY);
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir 				if(xSet.is())
68*cdf0e10cSrcweir 				{
69*cdf0e10cSrcweir 					uno::Any aValue(xSet->getPropertyValue(rtl::OUString::createFromAscii("DefaultControl")));
70*cdf0e10cSrcweir 					rtl::OUString aUnoControlTypeName;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 					if(aValue >>= aUnoControlTypeName)
73*cdf0e10cSrcweir 					{
74*cdf0e10cSrcweir 						if(aUnoControlTypeName.getLength())
75*cdf0e10cSrcweir 						{
76*cdf0e10cSrcweir 							uno::Reference< lang::XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir 							if(xFactory.is())
79*cdf0e10cSrcweir 							{
80*cdf0e10cSrcweir 								uno::Reference< awt::XControl > xXControl(xFactory->createInstance(aUnoControlTypeName), uno::UNO_QUERY);
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir 								if(xXControl.is())
83*cdf0e10cSrcweir 								{
84*cdf0e10cSrcweir 									xXControl->setModel(getControlModel());
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 									// remember XControl
87*cdf0e10cSrcweir 									mxXControl = xXControl;
88*cdf0e10cSrcweir 								}
89*cdf0e10cSrcweir 							}
90*cdf0e10cSrcweir 						}
91*cdf0e10cSrcweir 					}
92*cdf0e10cSrcweir 				}
93*cdf0e10cSrcweir 			}
94*cdf0e10cSrcweir 		}
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 		Primitive2DReference ControlPrimitive2D::createBitmapDecomposition(const geometry::ViewInformation2D& rViewInformation) const
97*cdf0e10cSrcweir 		{
98*cdf0e10cSrcweir 			Primitive2DReference xRetval;
99*cdf0e10cSrcweir 			const uno::Reference< awt::XControl >& rXControl(getXControl());
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir 			if(rXControl.is())
102*cdf0e10cSrcweir 			{
103*cdf0e10cSrcweir 				uno::Reference< awt::XWindow > xControlWindow(rXControl, uno::UNO_QUERY);
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 				if(xControlWindow.is())
106*cdf0e10cSrcweir 				{
107*cdf0e10cSrcweir 					// get decomposition to get size
108*cdf0e10cSrcweir 					basegfx::B2DVector aScale, aTranslate;
109*cdf0e10cSrcweir 					double fRotate, fShearX;
110*cdf0e10cSrcweir 					getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir 					// get absolute discrete size (no mirror or rotate here)
113*cdf0e10cSrcweir 					aScale = basegfx::absolute(aScale);
114*cdf0e10cSrcweir 					basegfx::B2DVector aDiscreteSize(rViewInformation.getObjectToViewTransformation() * aScale);
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 					// limit to a maximum square size, e.g. 300x150 pixels (45000)
117*cdf0e10cSrcweir                     const SvtOptionsDrawinglayer aDrawinglayerOpt;
118*cdf0e10cSrcweir 					const double fDiscreteMax(aDrawinglayerOpt.GetQuadraticFormControlRenderLimit());
119*cdf0e10cSrcweir 					const double fDiscreteQuadratic(aDiscreteSize.getX() * aDiscreteSize.getY());
120*cdf0e10cSrcweir                     const bool bScaleUsed(fDiscreteQuadratic > fDiscreteMax);
121*cdf0e10cSrcweir                     double fFactor(1.0);
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir 					if(bScaleUsed)
124*cdf0e10cSrcweir 					{
125*cdf0e10cSrcweir                         // get factor and adapt to scaled size
126*cdf0e10cSrcweir 						fFactor = sqrt(fDiscreteMax / fDiscreteQuadratic);
127*cdf0e10cSrcweir 						aDiscreteSize *= fFactor;
128*cdf0e10cSrcweir 					}
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 					// go to integer
131*cdf0e10cSrcweir 					const sal_Int32 nSizeX(basegfx::fround(aDiscreteSize.getX()));
132*cdf0e10cSrcweir 					const sal_Int32 nSizeY(basegfx::fround(aDiscreteSize.getY()));
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir 					if(nSizeX > 0 && nSizeY > 0)
135*cdf0e10cSrcweir 					{
136*cdf0e10cSrcweir 						// prepare VirtualDevice
137*cdf0e10cSrcweir 						VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
138*cdf0e10cSrcweir 						const Size aSizePixel(nSizeX, nSizeY);
139*cdf0e10cSrcweir 						aVirtualDevice.SetOutputSizePixel(aSizePixel);
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir 						// set size at control
142*cdf0e10cSrcweir 						xControlWindow->setPosSize(0, 0, nSizeX, nSizeY, awt::PosSize::POSSIZE);
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 						// get graphics and view
145*cdf0e10cSrcweir 						uno::Reference< awt::XGraphics > xGraphics(aVirtualDevice.CreateUnoGraphics());
146*cdf0e10cSrcweir 						uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY);
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir 						if(xGraphics.is() && xControlView.is())
149*cdf0e10cSrcweir 						{
150*cdf0e10cSrcweir 							// link graphics and view
151*cdf0e10cSrcweir 							xControlView->setGraphics(xGraphics);
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir                             {   // #i93162# For painting the control setting a Zoom (using setZoom() at the xControlView)
154*cdf0e10cSrcweir                                 // is needed to define the font size. Normally this is done in
155*cdf0e10cSrcweir                                 // ViewObjectContactOfUnoControl::createPrimitive2DSequence by using positionControlForPaint().
156*cdf0e10cSrcweir                                 // For some reason the difference between MAP_TWIPS and MAP_100TH_MM still plays
157*cdf0e10cSrcweir                                 // a role there so that for Draw/Impress/Calc (the MAP_100TH_MM users) i need to set a zoom
158*cdf0e10cSrcweir                                 // here, too. The factor includes the needed scale, but is calculated by pure comparisons. It
159*cdf0e10cSrcweir                                 // is somehow related to the twips/100thmm relationship.
160*cdf0e10cSrcweir                                 bool bUserIs100thmm(false);
161*cdf0e10cSrcweir             				    const uno::Reference< awt::XControl > xControl(xControlView, uno::UNO_QUERY);
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir                                 if(xControl.is())
164*cdf0e10cSrcweir                                 {
165*cdf0e10cSrcweir                                     uno::Reference< awt::XWindowPeer > xWindowPeer(xControl->getPeer());
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir                                     if(xWindowPeer.is())
168*cdf0e10cSrcweir                                     {
169*cdf0e10cSrcweir                     			        VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation(xWindowPeer);
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir                                         if(pVCLXWindow)
172*cdf0e10cSrcweir                                         {
173*cdf0e10cSrcweir                                             Window* pWindow = pVCLXWindow->GetWindow();
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir                                             if(pWindow)
176*cdf0e10cSrcweir                                             {
177*cdf0e10cSrcweir                                                 pWindow = pWindow->GetParent();
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir                                                 if(pWindow)
180*cdf0e10cSrcweir                                                 {
181*cdf0e10cSrcweir                                                     if(MAP_100TH_MM == pWindow->GetMapMode().GetMapUnit())
182*cdf0e10cSrcweir                                                     {
183*cdf0e10cSrcweir                                                         bUserIs100thmm = true;
184*cdf0e10cSrcweir                                                     }
185*cdf0e10cSrcweir                                                 }
186*cdf0e10cSrcweir                                             }
187*cdf0e10cSrcweir                                         }
188*cdf0e10cSrcweir                                     }
189*cdf0e10cSrcweir                                 }
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir                                 if(bUserIs100thmm)
192*cdf0e10cSrcweir                                 {
193*cdf0e10cSrcweir 					                // calc screen zoom for text display. fFactor is already added indirectly in aDiscreteSize
194*cdf0e10cSrcweir 					                basegfx::B2DVector aScreenZoom(
195*cdf0e10cSrcweir 						                basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : aDiscreteSize.getX() / aScale.getX(),
196*cdf0e10cSrcweir 						                basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : aDiscreteSize.getY() / aScale.getY());
197*cdf0e10cSrcweir 					                static double fZoomScale(28.0); // do not ask for this constant factor, but it gets the zoom right
198*cdf0e10cSrcweir                                     aScreenZoom *= fZoomScale;
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir                                     // set zoom at control view for text scaling
201*cdf0e10cSrcweir 	    			                xControlView->setZoom((float)aScreenZoom.getX(), (float)aScreenZoom.getY());
202*cdf0e10cSrcweir                                 }
203*cdf0e10cSrcweir                             }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 							try
206*cdf0e10cSrcweir 							{
207*cdf0e10cSrcweir 								// try to paint it to VirtualDevice
208*cdf0e10cSrcweir 								xControlView->draw(0, 0);
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir 								// get bitmap
211*cdf0e10cSrcweir 							    const Bitmap aContent(aVirtualDevice.GetBitmap(Point(), aSizePixel));
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir                                 // to avoid scaling, use the Bitmap pixel size as primitive size
214*cdf0e10cSrcweir                                 const Size aBitmapSize(aContent.GetSizePixel());
215*cdf0e10cSrcweir                                 basegfx::B2DVector aBitmapSizeLogic(
216*cdf0e10cSrcweir                                     rViewInformation.getInverseObjectToViewTransformation() *
217*cdf0e10cSrcweir                                     basegfx::B2DVector(aBitmapSize.getWidth() - 1, aBitmapSize.getHeight() - 1));
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir                                 if(bScaleUsed)
220*cdf0e10cSrcweir                                 {
221*cdf0e10cSrcweir                                     // if scaled adapt to scaled size
222*cdf0e10cSrcweir                                     aBitmapSizeLogic /= fFactor;
223*cdf0e10cSrcweir                                 }
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir                                 // short form for scale and translate transformation
226*cdf0e10cSrcweir 								const basegfx::B2DHomMatrix aBitmapTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(
227*cdf0e10cSrcweir 									aBitmapSizeLogic.getX(), aBitmapSizeLogic.getY(), aTranslate.getX(), aTranslate.getY()));
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir                                 // create primitive
230*cdf0e10cSrcweir 								xRetval = new BitmapPrimitive2D(BitmapEx(aContent), aBitmapTransform);
231*cdf0e10cSrcweir 							}
232*cdf0e10cSrcweir 							catch( const uno::Exception& )
233*cdf0e10cSrcweir 							{
234*cdf0e10cSrcweir 								DBG_UNHANDLED_EXCEPTION();
235*cdf0e10cSrcweir 							}
236*cdf0e10cSrcweir 						}
237*cdf0e10cSrcweir 					}
238*cdf0e10cSrcweir 				}
239*cdf0e10cSrcweir 			}
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir 			return xRetval;
242*cdf0e10cSrcweir 		}
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 		Primitive2DReference ControlPrimitive2D::createPlaceholderDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
245*cdf0e10cSrcweir 		{
246*cdf0e10cSrcweir 			// create a gray placeholder hairline polygon in object size
247*cdf0e10cSrcweir 			basegfx::B2DRange aObjectRange(0.0, 0.0, 1.0, 1.0);
248*cdf0e10cSrcweir 			aObjectRange.transform(getTransform());
249*cdf0e10cSrcweir 			const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aObjectRange));
250*cdf0e10cSrcweir 			const basegfx::BColor aGrayTone(0xc0 / 255.0, 0xc0 / 255.0, 0xc0 / 255.0);
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 			// The replacement object may also get a text like 'empty group' here later
253*cdf0e10cSrcweir 			Primitive2DReference xRetval(new PolygonHairlinePrimitive2D(aOutline, aGrayTone));
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 			return xRetval;
256*cdf0e10cSrcweir 		}
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir 		Primitive2DSequence ControlPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
259*cdf0e10cSrcweir 		{
260*cdf0e10cSrcweir 			// try to create a bitmap decomposition. If that fails for some reason,
261*cdf0e10cSrcweir 			// at least create a replacement decomposition.
262*cdf0e10cSrcweir 			Primitive2DReference xReference(createBitmapDecomposition(rViewInformation));
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 			if(!xReference.is())
265*cdf0e10cSrcweir 			{
266*cdf0e10cSrcweir 				xReference = createPlaceholderDecomposition(rViewInformation);
267*cdf0e10cSrcweir 			}
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 			return Primitive2DSequence(&xReference, 1L);
270*cdf0e10cSrcweir 		}
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir 		ControlPrimitive2D::ControlPrimitive2D(
273*cdf0e10cSrcweir 			const basegfx::B2DHomMatrix& rTransform,
274*cdf0e10cSrcweir 			const uno::Reference< awt::XControlModel >& rxControlModel)
275*cdf0e10cSrcweir 		:	BufferedDecompositionPrimitive2D(),
276*cdf0e10cSrcweir 			maTransform(rTransform),
277*cdf0e10cSrcweir 			mxControlModel(rxControlModel),
278*cdf0e10cSrcweir 			mxXControl(),
279*cdf0e10cSrcweir 			maLastViewScaling()
280*cdf0e10cSrcweir 		{
281*cdf0e10cSrcweir 		}
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir 		ControlPrimitive2D::ControlPrimitive2D(
284*cdf0e10cSrcweir 			const basegfx::B2DHomMatrix& rTransform,
285*cdf0e10cSrcweir 			const uno::Reference< awt::XControlModel >& rxControlModel,
286*cdf0e10cSrcweir 			const uno::Reference< awt::XControl >& rxXControl)
287*cdf0e10cSrcweir 		:	BufferedDecompositionPrimitive2D(),
288*cdf0e10cSrcweir 			maTransform(rTransform),
289*cdf0e10cSrcweir 			mxControlModel(rxControlModel),
290*cdf0e10cSrcweir 			mxXControl(rxXControl),
291*cdf0e10cSrcweir 			maLastViewScaling()
292*cdf0e10cSrcweir 		{
293*cdf0e10cSrcweir 		}
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir 		const uno::Reference< awt::XControl >& ControlPrimitive2D::getXControl() const
296*cdf0e10cSrcweir 		{
297*cdf0e10cSrcweir 			if(!mxXControl.is())
298*cdf0e10cSrcweir 			{
299*cdf0e10cSrcweir 				const_cast< ControlPrimitive2D* >(this)->createXControl();
300*cdf0e10cSrcweir 			}
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir 			return mxXControl;
303*cdf0e10cSrcweir 		}
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir 		bool ControlPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
306*cdf0e10cSrcweir 		{
307*cdf0e10cSrcweir 			// use base class compare operator
308*cdf0e10cSrcweir 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
309*cdf0e10cSrcweir 			{
310*cdf0e10cSrcweir 				const ControlPrimitive2D& rCompare = (ControlPrimitive2D&)rPrimitive;
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir 				if(getTransform() == rCompare.getTransform())
313*cdf0e10cSrcweir 				{
314*cdf0e10cSrcweir                     // check if ControlModel references both are/are not
315*cdf0e10cSrcweir                     bool bRetval(getControlModel().is() == rCompare.getControlModel().is());
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir                     if(bRetval && getControlModel().is())
318*cdf0e10cSrcweir                     {
319*cdf0e10cSrcweir 				        // both exist, check for equality
320*cdf0e10cSrcweir 				        bRetval = (getControlModel() == rCompare.getControlModel());
321*cdf0e10cSrcweir                     }
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir                     if(bRetval)
324*cdf0e10cSrcweir                     {
325*cdf0e10cSrcweir                         // check if XControl references both are/are not
326*cdf0e10cSrcweir                         bRetval = (getXControl().is() == rCompare.getXControl().is());
327*cdf0e10cSrcweir                     }
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir                     if(bRetval && getXControl().is())
330*cdf0e10cSrcweir                     {
331*cdf0e10cSrcweir 				        // both exist, check for equality
332*cdf0e10cSrcweir 				        bRetval = (getXControl() == rCompare.getXControl());
333*cdf0e10cSrcweir                     }
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir                     return bRetval;
336*cdf0e10cSrcweir 				}
337*cdf0e10cSrcweir 			}
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir 			return false;
340*cdf0e10cSrcweir 		}
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir 		basegfx::B2DRange ControlPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
343*cdf0e10cSrcweir 		{
344*cdf0e10cSrcweir 			// simply derivate from unit range
345*cdf0e10cSrcweir 			basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
346*cdf0e10cSrcweir 			aRetval.transform(getTransform());
347*cdf0e10cSrcweir 			return aRetval;
348*cdf0e10cSrcweir 		}
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir 		Primitive2DSequence ControlPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
351*cdf0e10cSrcweir 		{
352*cdf0e10cSrcweir 			// this primitive is view-dependent related to the scaling. If scaling has changed,
353*cdf0e10cSrcweir 			// destroy existing decomposition. To detect change, use size of unit size in view coordinates
354*cdf0e10cSrcweir 			::osl::MutexGuard aGuard( m_aMutex );
355*cdf0e10cSrcweir 			const basegfx::B2DVector aNewScaling(rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir 			if(getBuffered2DDecomposition().hasElements())
358*cdf0e10cSrcweir 			{
359*cdf0e10cSrcweir 				if(!maLastViewScaling.equal(aNewScaling))
360*cdf0e10cSrcweir 				{
361*cdf0e10cSrcweir 					// conditions of last local decomposition have changed, delete
362*cdf0e10cSrcweir 					const_cast< ControlPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
363*cdf0e10cSrcweir 				}
364*cdf0e10cSrcweir 			}
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir 			if(!getBuffered2DDecomposition().hasElements())
367*cdf0e10cSrcweir 			{
368*cdf0e10cSrcweir 				// remember ViewTransformation
369*cdf0e10cSrcweir 				const_cast< ControlPrimitive2D* >(this)->maLastViewScaling = aNewScaling;
370*cdf0e10cSrcweir 			}
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir 			// use parent implementation
373*cdf0e10cSrcweir 			return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
374*cdf0e10cSrcweir 		}
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 		// provide unique ID
377*cdf0e10cSrcweir 		ImplPrimitrive2DIDBlock(ControlPrimitive2D, PRIMITIVE2D_ID_CONTROLPRIMITIVE2D)
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir 	} // end of namespace primitive2d
380*cdf0e10cSrcweir } // end of namespace drawinglayer
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
383*cdf0e10cSrcweir // eof
384