xref: /AOO41X/main/drawinglayer/source/primitive2d/graphicprimitive2d.cxx (revision 464702f4578bd67db020a330afd07883930c5e07)
1*464702f4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*464702f4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*464702f4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*464702f4SAndrew Rist  * distributed with this work for additional information
6*464702f4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*464702f4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*464702f4SAndrew Rist  * "License"); you may not use this file except in compliance
9*464702f4SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*464702f4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*464702f4SAndrew Rist  * software distributed under the License is distributed on an
15*464702f4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*464702f4SAndrew Rist  * KIND, either express or implied.  See the License for the
17*464702f4SAndrew Rist  * specific language governing permissions and limitations
18*464702f4SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*464702f4SAndrew Rist  *************************************************************/
21*464702f4SAndrew Rist 
22*464702f4SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
28cdf0e10cSrcweir #include <drawinglayer/animation/animationtiming.hxx>
29cdf0e10cSrcweir #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
30cdf0e10cSrcweir #include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
31cdf0e10cSrcweir #include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
32cdf0e10cSrcweir #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
33cdf0e10cSrcweir #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
34cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
35cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
36cdf0e10cSrcweir #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
37cdf0e10cSrcweir #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
40cdf0e10cSrcweir // helper class for animated graphics
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <vcl/animate.hxx>
43cdf0e10cSrcweir #include <vcl/graph.hxx>
44cdf0e10cSrcweir #include <vcl/virdev.hxx>
45cdf0e10cSrcweir #include <vcl/svapp.hxx>
46cdf0e10cSrcweir #include <vcl/metaact.hxx>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
49cdf0e10cSrcweir // includes for testing MetafilePrimitive2D::create2DDecomposition
50cdf0e10cSrcweir 
51cdf0e10cSrcweir // this switch defines if the test code is included or not
52cdf0e10cSrcweir #undef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
53cdf0e10cSrcweir 
54cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
55cdf0e10cSrcweir #include <vcl/gradient.hxx>
56cdf0e10cSrcweir #include <vcl/pngread.hxx>
57cdf0e10cSrcweir #include <vcl/lineinfo.hxx>
58cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
59cdf0e10cSrcweir 
60cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
61cdf0e10cSrcweir 
62cdf0e10cSrcweir namespace
63cdf0e10cSrcweir {
64cdf0e10cSrcweir 	struct animationStep
65cdf0e10cSrcweir 	{
66cdf0e10cSrcweir 		BitmapEx								maBitmapEx;
67cdf0e10cSrcweir 		sal_uInt32								mnTime;
68cdf0e10cSrcweir 	};
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 	class animatedBitmapExPreparator
71cdf0e10cSrcweir 	{
72cdf0e10cSrcweir 		::Animation								maAnimation;
73cdf0e10cSrcweir 		::std::vector< animationStep >			maSteps;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 		sal_uInt32 generateStepTime(sal_uInt32 nIndex) const;
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 	public:
78cdf0e10cSrcweir 		animatedBitmapExPreparator(const Graphic& rGraphic);
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 		sal_uInt32 count() const { return maSteps.size(); }
81cdf0e10cSrcweir 		sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); }
82cdf0e10cSrcweir 		sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; }
83cdf0e10cSrcweir 		const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; }
84cdf0e10cSrcweir 	};
85cdf0e10cSrcweir 
86cdf0e10cSrcweir 	sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const
87cdf0e10cSrcweir 	{
88cdf0e10cSrcweir 		const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex));
89cdf0e10cSrcweir 		sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10);
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 		// #115934#
92cdf0e10cSrcweir 		// Take care of special value for MultiPage TIFFs. ATM these shall just
93cdf0e10cSrcweir 		// show their first page. Later we will offer some switching when object
94cdf0e10cSrcweir 		// is selected.
95cdf0e10cSrcweir 		if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait)
96cdf0e10cSrcweir 		{
97cdf0e10cSrcweir 			// ATM the huge value would block the timer, so
98cdf0e10cSrcweir 			// use a long time to show first page (whole day)
99cdf0e10cSrcweir 			nWaitTime = 100 * 60 * 60 * 24;
100cdf0e10cSrcweir 		}
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 		// Bad trap: There are animated gifs with no set WaitTime (!).
103cdf0e10cSrcweir 		// In that case use a default value.
104cdf0e10cSrcweir 		if(0L == nWaitTime)
105cdf0e10cSrcweir 		{
106cdf0e10cSrcweir 			nWaitTime = 100L;
107cdf0e10cSrcweir 		}
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 		return nWaitTime;
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 	animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic)
113cdf0e10cSrcweir 	:	maAnimation(rGraphic.GetAnimation())
114cdf0e10cSrcweir 	{
115cdf0e10cSrcweir 		OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)");
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 		// #128539# secure access to Animation, looks like there exist animated GIFs out there
118cdf0e10cSrcweir 		// with a step count of zero
119cdf0e10cSrcweir 		if(maAnimation.Count())
120cdf0e10cSrcweir 		{
121cdf0e10cSrcweir 			VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
122cdf0e10cSrcweir 			VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L);
123cdf0e10cSrcweir 
124cdf0e10cSrcweir 			// Prepare VirtualDevices and their states
125cdf0e10cSrcweir 			aVirtualDevice.EnableMapMode(sal_False);
126cdf0e10cSrcweir 			aVirtualDeviceMask.EnableMapMode(sal_False);
127cdf0e10cSrcweir 			aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
128cdf0e10cSrcweir 			aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
129cdf0e10cSrcweir 			aVirtualDevice.Erase();
130cdf0e10cSrcweir 			aVirtualDeviceMask.Erase();
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 			for(sal_uInt16 a(0L); a < maAnimation.Count(); a++)
133cdf0e10cSrcweir 			{
134cdf0e10cSrcweir 				animationStep aNextStep;
135cdf0e10cSrcweir 				aNextStep.mnTime = generateStepTime(a);
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 				// prepare step
138cdf0e10cSrcweir 				const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a));
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 				switch(rAnimBitmap.eDisposal)
141cdf0e10cSrcweir 				{
142cdf0e10cSrcweir 					case DISPOSE_NOT:
143cdf0e10cSrcweir 					{
144cdf0e10cSrcweir 						aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
145cdf0e10cSrcweir 						Bitmap aMask = rAnimBitmap.aBmpEx.GetMask();
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 						if(aMask.IsEmpty())
148cdf0e10cSrcweir 						{
149cdf0e10cSrcweir 							const Point aEmpty;
150cdf0e10cSrcweir 							const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel());
151cdf0e10cSrcweir 							const Wallpaper aWallpaper(COL_BLACK);
152cdf0e10cSrcweir 							aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper);
153cdf0e10cSrcweir 						}
154cdf0e10cSrcweir 						else
155cdf0e10cSrcweir 						{
156cdf0e10cSrcweir 							BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask);
157cdf0e10cSrcweir 							aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask);
158cdf0e10cSrcweir 						}
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 						break;
161cdf0e10cSrcweir 					}
162cdf0e10cSrcweir 					case DISPOSE_BACK:
163cdf0e10cSrcweir 					{
164cdf0e10cSrcweir 						// #i70772# react on no mask, for primitives, too.
165cdf0e10cSrcweir 						const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask());
166cdf0e10cSrcweir 						const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap());
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 						aVirtualDeviceMask.Erase();
169cdf0e10cSrcweir 						aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent);
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 						if(aMask.IsEmpty())
172cdf0e10cSrcweir 						{
173cdf0e10cSrcweir 							const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel());
174cdf0e10cSrcweir 							aVirtualDeviceMask.SetFillColor(COL_BLACK);
175cdf0e10cSrcweir 							aVirtualDeviceMask.SetLineColor();
176cdf0e10cSrcweir 							aVirtualDeviceMask.DrawRect(aRect);
177cdf0e10cSrcweir 						}
178cdf0e10cSrcweir 						else
179cdf0e10cSrcweir 						{
180cdf0e10cSrcweir 							aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask);
181cdf0e10cSrcweir 						}
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 						break;
184cdf0e10cSrcweir 					}
185cdf0e10cSrcweir 					case DISPOSE_FULL:
186cdf0e10cSrcweir 					{
187cdf0e10cSrcweir 						aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
188cdf0e10cSrcweir 						break;
189cdf0e10cSrcweir 					}
190cdf0e10cSrcweir 					case DISPOSE_PREVIOUS :
191cdf0e10cSrcweir 					{
192cdf0e10cSrcweir 						aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
193cdf0e10cSrcweir 						aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask());
194cdf0e10cSrcweir 						break;
195cdf0e10cSrcweir 					}
196cdf0e10cSrcweir 				}
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 				// create BitmapEx
199cdf0e10cSrcweir 				Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel());
200cdf0e10cSrcweir 				Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel());
201cdf0e10cSrcweir 				aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap);
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 				// add to vector
204cdf0e10cSrcweir 				maSteps.push_back(aNextStep);
205cdf0e10cSrcweir 			}
206cdf0e10cSrcweir 		}
207cdf0e10cSrcweir 	}
208cdf0e10cSrcweir } // end of anonymous namespace
209cdf0e10cSrcweir 
210cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
211cdf0e10cSrcweir 
212cdf0e10cSrcweir namespace drawinglayer
213cdf0e10cSrcweir {
214cdf0e10cSrcweir 	namespace primitive2d
215cdf0e10cSrcweir 	{
216cdf0e10cSrcweir 		Primitive2DSequence GraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D&
217cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
218cdf0e10cSrcweir             rViewInformation
219cdf0e10cSrcweir #else
220cdf0e10cSrcweir             /*rViewInformation*/
221cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
222cdf0e10cSrcweir             ) const
223cdf0e10cSrcweir 		{
224cdf0e10cSrcweir 			Primitive2DSequence aRetval;
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 			if(255L != getGraphicAttr().GetTransparency())
227cdf0e10cSrcweir 			{
228cdf0e10cSrcweir 				Primitive2DReference xPrimitive;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir                 // do not apply mirroring from GraphicAttr to the Metafile by calling
231cdf0e10cSrcweir                 // GetTransformedGraphic, this will try to mirror the Metafile using Scale()
232cdf0e10cSrcweir                 // at the Metafile. This again calls Scale at the single MetaFile actions,
233cdf0e10cSrcweir                 // but this implementation never worked. I reworked that implementations,
234cdf0e10cSrcweir                 // but for security reasons i will try not to use it.
235cdf0e10cSrcweir                 basegfx::B2DHomMatrix aTransform(getTransform());
236cdf0e10cSrcweir 
237cdf0e10cSrcweir                 if(getGraphicAttr().IsMirrored())
238cdf0e10cSrcweir                 {
239cdf0e10cSrcweir                     // content needs mirroring
240cdf0e10cSrcweir                     const bool bHMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_HORZ);
241cdf0e10cSrcweir                     const bool bVMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_VERT);
242cdf0e10cSrcweir 
243cdf0e10cSrcweir                     // mirror by applying negative scale to the unit primitive and
244cdf0e10cSrcweir                     // applying the object transformation on it.
245cdf0e10cSrcweir                     aTransform = basegfx::tools::createScaleB2DHomMatrix(
246cdf0e10cSrcweir                         bHMirr ? -1.0 : 1.0,
247cdf0e10cSrcweir                         bVMirr ? -1.0 : 1.0);
248cdf0e10cSrcweir                     aTransform.translate(
249cdf0e10cSrcweir                         bHMirr ? 1.0 : 0.0,
250cdf0e10cSrcweir                         bVMirr ? 1.0 : 0.0);
251cdf0e10cSrcweir                     aTransform = getTransform() * aTransform;
252cdf0e10cSrcweir                 }
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 		        // Get transformed graphic. Suppress rotation and cropping, only filtering is needed
255cdf0e10cSrcweir 		        // here (and may be replaced later on). Cropping is handled below as mask primitive (if set).
256cdf0e10cSrcweir                 // Also need to suppress mirroring, it is part of the transformation now (see above).
257cdf0e10cSrcweir 		        GraphicAttr aSuppressGraphicAttr(getGraphicAttr());
258cdf0e10cSrcweir 		        aSuppressGraphicAttr.SetCrop(0, 0, 0, 0);
259cdf0e10cSrcweir 		        aSuppressGraphicAttr.SetRotation(0);
260cdf0e10cSrcweir 		        aSuppressGraphicAttr.SetMirrorFlags(0);
261cdf0e10cSrcweir 
262cdf0e10cSrcweir                 const GraphicObject&    rGraphicObject = getGraphicObject();
263cdf0e10cSrcweir                 const Graphic           aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr));
264cdf0e10cSrcweir 
265cdf0e10cSrcweir                 switch(aTransformedGraphic.GetType())
266cdf0e10cSrcweir 				{
267cdf0e10cSrcweir 					case GRAPHIC_BITMAP :
268cdf0e10cSrcweir 					{
269cdf0e10cSrcweir                         if(aTransformedGraphic.IsAnimated())
270cdf0e10cSrcweir 						{
271cdf0e10cSrcweir 							// prepare animation data
272cdf0e10cSrcweir 							animatedBitmapExPreparator aData(aTransformedGraphic);
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 							if(aData.count())
275cdf0e10cSrcweir 							{
276cdf0e10cSrcweir 								// create sub-primitives for animated bitmap and the needed animation loop
277cdf0e10cSrcweir 								animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff);
278cdf0e10cSrcweir 								Primitive2DSequence aBitmapPrimitives(aData.count());
279cdf0e10cSrcweir 
280cdf0e10cSrcweir 								for(sal_uInt32 a(0L); a < aData.count(); a++)
281cdf0e10cSrcweir 								{
282cdf0e10cSrcweir                                     animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count());
283cdf0e10cSrcweir 									aAnimationLoop.append(aTime);
284cdf0e10cSrcweir 									const Primitive2DReference xRef(new BitmapPrimitive2D(aData.stepBitmapEx(a), aTransform));
285cdf0e10cSrcweir 									aBitmapPrimitives[a] = xRef;
286cdf0e10cSrcweir 								}
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 								// prepare animation list
289cdf0e10cSrcweir 								animation::AnimationEntryList aAnimationList;
290cdf0e10cSrcweir 								aAnimationList.append(aAnimationLoop);
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 								// create and add animated switch primitive
293cdf0e10cSrcweir 								xPrimitive = Primitive2DReference(new AnimatedSwitchPrimitive2D(aAnimationList, aBitmapPrimitives, false));
294cdf0e10cSrcweir 							}
295cdf0e10cSrcweir 						}
296cdf0e10cSrcweir 						else
297cdf0e10cSrcweir 						{
298cdf0e10cSrcweir 							xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), aTransform));
299cdf0e10cSrcweir 						}
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 						break;
302cdf0e10cSrcweir 					}
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 					case GRAPHIC_GDIMETAFILE :
305cdf0e10cSrcweir 					{
306cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
307cdf0e10cSrcweir                         static bool bDoTest(false);
308cdf0e10cSrcweir 
309cdf0e10cSrcweir                         if(bDoTest)
310cdf0e10cSrcweir                         {
311cdf0e10cSrcweir 							// All this is/was test code for testing MetafilePrimitive2D::create2DDecomposition
312cdf0e10cSrcweir 							// extensively. It may be needed again when diverse actions need debugging, so i leave
313cdf0e10cSrcweir 							// it in here, but take it out using USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE.
314cdf0e10cSrcweir 							// Use it by compiling with the code, insert any DrawObject, convert to Metafile. The
315cdf0e10cSrcweir 							// debugger will then stop here (when breakpoint set, of course). You may enter single
316cdf0e10cSrcweir 							// parts of actions and/or change to true what You want to check.
317cdf0e10cSrcweir                             GDIMetaFile aMtf;
318cdf0e10cSrcweir 			                VirtualDevice aOut;
319cdf0e10cSrcweir         		            const basegfx::B2DRange aRange(getB2DRange(rViewInformation));
320cdf0e10cSrcweir                             const Rectangle aRectangle(
321cdf0e10cSrcweir                                 basegfx::fround(aRange.getMinX()), basegfx::fround(aRange.getMinY()),
322cdf0e10cSrcweir                                 basegfx::fround(aRange.getMaxX()), basegfx::fround(aRange.getMaxY()));
323cdf0e10cSrcweir                             const Point aOrigin(aRectangle.TopLeft());
324cdf0e10cSrcweir                             const Fraction aScaleX(aRectangle.getWidth());
325cdf0e10cSrcweir                             const Fraction aScaleY(aRectangle.getHeight());
326cdf0e10cSrcweir                             MapMode aMapMode(MAP_100TH_MM, aOrigin, aScaleX, aScaleY);
327cdf0e10cSrcweir 
328cdf0e10cSrcweir                             Size aDummySize(2, 2);
329cdf0e10cSrcweir                             aOut.SetOutputSizePixel(aDummySize);
330cdf0e10cSrcweir 			                aOut.EnableOutput(FALSE);
331cdf0e10cSrcweir 			                aOut.SetMapMode(aMapMode);
332cdf0e10cSrcweir 
333cdf0e10cSrcweir                             aMtf.Clear();
334cdf0e10cSrcweir 			                aMtf.Record(&aOut);
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 			                const Fraction aNeutralFraction(1, 1);
337cdf0e10cSrcweir 			                const MapMode aRelativeMapMode(
338cdf0e10cSrcweir                                 MAP_RELATIVE,
339cdf0e10cSrcweir                                 Point(-aRectangle.Left(), -aRectangle.Top()),
340cdf0e10cSrcweir                                 aNeutralFraction, aNeutralFraction);
341cdf0e10cSrcweir 			                aOut.SetMapMode(aRelativeMapMode);
342cdf0e10cSrcweir 
343cdf0e10cSrcweir                             if(false)
344cdf0e10cSrcweir                             {
345cdf0e10cSrcweir                                 const sal_Int32 nHor(aRectangle.getWidth() / 4);
346cdf0e10cSrcweir                                 const sal_Int32 nVer(aRectangle.getHeight() / 4);
347cdf0e10cSrcweir                                 const Rectangle aCenteredRectangle(
348cdf0e10cSrcweir                                     aRectangle.Left() + nHor, aRectangle.Top() + nVer,
349cdf0e10cSrcweir                                     aRectangle.Right() - nHor, aRectangle.Bottom() - nVer);
350cdf0e10cSrcweir                                 aOut.SetClipRegion(aCenteredRectangle);
351cdf0e10cSrcweir                             }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir                             if(false)
354cdf0e10cSrcweir                             {
355cdf0e10cSrcweir                                 const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight());
356cdf0e10cSrcweir                                 aOut.IntersectClipRegion(aRightRectangle);
357cdf0e10cSrcweir                             }
358cdf0e10cSrcweir 
359cdf0e10cSrcweir                             if(false)
360cdf0e10cSrcweir                             {
361cdf0e10cSrcweir                                 const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight());
362cdf0e10cSrcweir                                 const Rectangle aBottomRectangle(aRectangle.LeftCenter(), aRectangle.BottomRight());
363cdf0e10cSrcweir                                 Region aRegion(aRightRectangle);
364cdf0e10cSrcweir                                 aRegion.Intersect(aBottomRectangle);
365cdf0e10cSrcweir                                 aOut.IntersectClipRegion(aRegion);
366cdf0e10cSrcweir                             }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir                             if(false)
369cdf0e10cSrcweir                             {
370cdf0e10cSrcweir                                 const sal_Int32 nHor(aRectangle.getWidth() / 10);
371cdf0e10cSrcweir                                 const sal_Int32 nVer(aRectangle.getHeight() / 10);
372cdf0e10cSrcweir                                 aOut.MoveClipRegion(nHor, nVer);
373cdf0e10cSrcweir                             }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir                             if(false)
376cdf0e10cSrcweir                             {
377cdf0e10cSrcweir                                 Wallpaper aWallpaper(Color(COL_BLACK));
378cdf0e10cSrcweir                                 aOut.DrawWallpaper(aRectangle, aWallpaper);
379cdf0e10cSrcweir                             }
380cdf0e10cSrcweir 
381cdf0e10cSrcweir                             if(false)
382cdf0e10cSrcweir                             {
383cdf0e10cSrcweir                                 Wallpaper aWallpaper(Gradient(GRADIENT_LINEAR, Color(COL_RED), Color(COL_GREEN)));
384cdf0e10cSrcweir                                 aOut.DrawWallpaper(aRectangle, aWallpaper);
385cdf0e10cSrcweir                             }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir                             if(false)
388cdf0e10cSrcweir                             {
389cdf0e10cSrcweir             					SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
390cdf0e10cSrcweir                                 vcl::PNGReader aPNGReader(aRead);
391cdf0e10cSrcweir 		                        BitmapEx aBitmapEx(aPNGReader.Read());
392cdf0e10cSrcweir                                 Wallpaper aWallpaper(aBitmapEx);
393cdf0e10cSrcweir                                 aOut.DrawWallpaper(aRectangle, aWallpaper);
394cdf0e10cSrcweir                             }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir                             if(false)
397cdf0e10cSrcweir                             {
398cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
399cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
400cdf0e10cSrcweir 								Color aColor(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0));
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 								for(sal_uInt32 a(0); a < 5000; a++)
403cdf0e10cSrcweir 								{
404cdf0e10cSrcweir 									const Point aPoint(
405cdf0e10cSrcweir 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
406cdf0e10cSrcweir 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 									if(!(a % 3))
409cdf0e10cSrcweir 									{
410cdf0e10cSrcweir 										aColor = Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0));
411cdf0e10cSrcweir 									}
412cdf0e10cSrcweir 
413cdf0e10cSrcweir 									aOut.DrawPixel(aPoint, aColor);
414cdf0e10cSrcweir 								}
415cdf0e10cSrcweir 							}
416cdf0e10cSrcweir 
417cdf0e10cSrcweir                             if(false)
418cdf0e10cSrcweir                             {
419cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
420cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
421cdf0e10cSrcweir 
422cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
423cdf0e10cSrcweir 								aOut.SetFillColor();
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 								for(sal_uInt32 a(0); a < 5000; a++)
426cdf0e10cSrcweir 								{
427cdf0e10cSrcweir 									const Point aPoint(
428cdf0e10cSrcweir 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
429cdf0e10cSrcweir 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
430cdf0e10cSrcweir 									aOut.DrawPixel(aPoint);
431cdf0e10cSrcweir 								}
432cdf0e10cSrcweir 							}
433cdf0e10cSrcweir 
434cdf0e10cSrcweir                             if(false)
435cdf0e10cSrcweir                             {
436cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
437cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
440cdf0e10cSrcweir 								aOut.SetFillColor();
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 								Point aStart(
443cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
444cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
445cdf0e10cSrcweir 								Point aStop(
446cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
447cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
448cdf0e10cSrcweir 
449cdf0e10cSrcweir 								LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0));
450cdf0e10cSrcweir 								bool bUseLineInfo(false);
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 								for(sal_uInt32 a(0); a < 20; a++)
453cdf0e10cSrcweir 								{
454cdf0e10cSrcweir 									if(!(a%6))
455cdf0e10cSrcweir 									{
456cdf0e10cSrcweir 										bUseLineInfo = !bUseLineInfo;
457cdf0e10cSrcweir 									}
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 									if(!(a%4))
460cdf0e10cSrcweir 									{
461cdf0e10cSrcweir 										aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
462cdf0e10cSrcweir 									}
463cdf0e10cSrcweir 
464cdf0e10cSrcweir 									if(a%3)
465cdf0e10cSrcweir 									{
466cdf0e10cSrcweir 										aStart = aStop;
467cdf0e10cSrcweir 										aStop = Point(
468cdf0e10cSrcweir 											aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
469cdf0e10cSrcweir 											aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
470cdf0e10cSrcweir 									}
471cdf0e10cSrcweir 									else
472cdf0e10cSrcweir 									{
473cdf0e10cSrcweir 										aStart = Point(
474cdf0e10cSrcweir 											aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
475cdf0e10cSrcweir 											aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
476cdf0e10cSrcweir 										aStop = Point(
477cdf0e10cSrcweir 											aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
478cdf0e10cSrcweir 											aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
479cdf0e10cSrcweir 									}
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 									if(bUseLineInfo)
482cdf0e10cSrcweir 									{
483cdf0e10cSrcweir 										aOut.DrawLine(aStart, aStop, aLineInfo);
484cdf0e10cSrcweir 									}
485cdf0e10cSrcweir 									else
486cdf0e10cSrcweir 									{
487cdf0e10cSrcweir 										aOut.DrawLine(aStart, aStop);
488cdf0e10cSrcweir 									}
489cdf0e10cSrcweir 								}
490cdf0e10cSrcweir 							}
491cdf0e10cSrcweir 
492cdf0e10cSrcweir                             if(false)
493cdf0e10cSrcweir                             {
494cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
495cdf0e10cSrcweir 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
496cdf0e10cSrcweir 								aOut.DrawRect(aRectangle);
497cdf0e10cSrcweir 							}
498cdf0e10cSrcweir 
499cdf0e10cSrcweir                             if(false)
500cdf0e10cSrcweir                             {
501cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
502cdf0e10cSrcweir 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
503cdf0e10cSrcweir                                 const sal_uInt32 nHor(aRectangle.getWidth() / 10);
504cdf0e10cSrcweir                                 const sal_uInt32 nVer(aRectangle.getHeight() / 10);
505cdf0e10cSrcweir 								aOut.DrawRect(aRectangle, nHor, nVer);
506cdf0e10cSrcweir 							}
507cdf0e10cSrcweir 
508cdf0e10cSrcweir                             if(false)
509cdf0e10cSrcweir                             {
510cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
511cdf0e10cSrcweir 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
512cdf0e10cSrcweir 								aOut.DrawEllipse(aRectangle);
513cdf0e10cSrcweir 							}
514cdf0e10cSrcweir 
515cdf0e10cSrcweir                             if(false)
516cdf0e10cSrcweir                             {
517cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
518cdf0e10cSrcweir 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
519cdf0e10cSrcweir 								aOut.DrawArc(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter());
520cdf0e10cSrcweir 							}
521cdf0e10cSrcweir 
522cdf0e10cSrcweir                             if(false)
523cdf0e10cSrcweir                             {
524cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
525cdf0e10cSrcweir 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
526cdf0e10cSrcweir 								aOut.DrawPie(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter());
527cdf0e10cSrcweir 							}
528cdf0e10cSrcweir 
529cdf0e10cSrcweir                             if(false)
530cdf0e10cSrcweir                             {
531cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
532cdf0e10cSrcweir 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
533cdf0e10cSrcweir 								aOut.DrawChord(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter());
534cdf0e10cSrcweir 							}
535cdf0e10cSrcweir 
536cdf0e10cSrcweir                             if(false)
537cdf0e10cSrcweir                             {
538cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
539cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
540cdf0e10cSrcweir 
541cdf0e10cSrcweir 								for(sal_uInt32 b(0); b < 5; b++)
542cdf0e10cSrcweir 								{
543cdf0e10cSrcweir 									const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0)));
544cdf0e10cSrcweir 									const bool bClose(basegfx::fround(rand() / 32767.0));
545cdf0e10cSrcweir 									Polygon aPolygon(nCount + (bClose ? 1 : 0));
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 									for(sal_uInt32 a(0); a < nCount; a++)
548cdf0e10cSrcweir 									{
549cdf0e10cSrcweir 										const Point aPoint(
550cdf0e10cSrcweir 											aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
551cdf0e10cSrcweir 											aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
552cdf0e10cSrcweir 										aPolygon[a] = aPoint;
553cdf0e10cSrcweir 									}
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 									if(bClose)
556cdf0e10cSrcweir 									{
557cdf0e10cSrcweir 										aPolygon[aPolygon.GetSize() - 1] = aPolygon[0];
558cdf0e10cSrcweir 									}
559cdf0e10cSrcweir 
560cdf0e10cSrcweir 									aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
561cdf0e10cSrcweir 									aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
562cdf0e10cSrcweir 
563cdf0e10cSrcweir 									if(!(b%2))
564cdf0e10cSrcweir 									{
565cdf0e10cSrcweir 										const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0));
566cdf0e10cSrcweir 										aOut.DrawPolyLine(aPolygon, aLineInfo);
567cdf0e10cSrcweir 									}
568cdf0e10cSrcweir 									else
569cdf0e10cSrcweir 									{
570cdf0e10cSrcweir 										aOut.DrawPolyLine(aPolygon);
571cdf0e10cSrcweir 									}
572cdf0e10cSrcweir 								}
573cdf0e10cSrcweir 							}
574cdf0e10cSrcweir 
575cdf0e10cSrcweir                             if(false)
576cdf0e10cSrcweir                             {
577cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
578cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
579cdf0e10cSrcweir 
580cdf0e10cSrcweir 								for(sal_uInt32 b(0); b < 5; b++)
581cdf0e10cSrcweir 								{
582cdf0e10cSrcweir 									const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0)));
583cdf0e10cSrcweir 									const bool bClose(basegfx::fround(rand() / 32767.0));
584cdf0e10cSrcweir 									Polygon aPolygon(nCount + (bClose ? 1 : 0));
585cdf0e10cSrcweir 
586cdf0e10cSrcweir 									for(sal_uInt32 a(0); a < nCount; a++)
587cdf0e10cSrcweir 									{
588cdf0e10cSrcweir 										const Point aPoint(
589cdf0e10cSrcweir 											aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
590cdf0e10cSrcweir 											aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
591cdf0e10cSrcweir 										aPolygon[a] = aPoint;
592cdf0e10cSrcweir 									}
593cdf0e10cSrcweir 
594cdf0e10cSrcweir 									if(bClose)
595cdf0e10cSrcweir 									{
596cdf0e10cSrcweir 										aPolygon[aPolygon.GetSize() - 1] = aPolygon[0];
597cdf0e10cSrcweir 									}
598cdf0e10cSrcweir 
599cdf0e10cSrcweir 									aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
600cdf0e10cSrcweir 									aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
601cdf0e10cSrcweir 									aOut.DrawPolygon(aPolygon);
602cdf0e10cSrcweir 								}
603cdf0e10cSrcweir 							}
604cdf0e10cSrcweir 
605cdf0e10cSrcweir                             if(false)
606cdf0e10cSrcweir                             {
607cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
608cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
609cdf0e10cSrcweir 								PolyPolygon aPolyPolygon;
610cdf0e10cSrcweir 
611cdf0e10cSrcweir 								for(sal_uInt32 b(0); b < 3; b++)
612cdf0e10cSrcweir 								{
613cdf0e10cSrcweir 									const sal_uInt32 nCount(basegfx::fround(rand() * (6 / 32767.0)));
614cdf0e10cSrcweir 									const bool bClose(basegfx::fround(rand() / 32767.0));
615cdf0e10cSrcweir 									Polygon aPolygon(nCount + (bClose ? 1 : 0));
616cdf0e10cSrcweir 
617cdf0e10cSrcweir 									for(sal_uInt32 a(0); a < nCount; a++)
618cdf0e10cSrcweir 									{
619cdf0e10cSrcweir 										const Point aPoint(
620cdf0e10cSrcweir 											aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
621cdf0e10cSrcweir 											aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
622cdf0e10cSrcweir 										aPolygon[a] = aPoint;
623cdf0e10cSrcweir 									}
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 									if(bClose)
626cdf0e10cSrcweir 									{
627cdf0e10cSrcweir 										aPolygon[aPolygon.GetSize() - 1] = aPolygon[0];
628cdf0e10cSrcweir 									}
629cdf0e10cSrcweir 
630cdf0e10cSrcweir 									aPolyPolygon.Insert(aPolygon);
631cdf0e10cSrcweir 								}
632cdf0e10cSrcweir 
633cdf0e10cSrcweir 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
634cdf0e10cSrcweir 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
635cdf0e10cSrcweir 								aOut.DrawPolyPolygon(aPolyPolygon);
636cdf0e10cSrcweir 							}
637cdf0e10cSrcweir 
638cdf0e10cSrcweir                             if(false)
639cdf0e10cSrcweir                             {
640cdf0e10cSrcweir             					SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
641cdf0e10cSrcweir                                 vcl::PNGReader aPNGReader(aRead);
642cdf0e10cSrcweir 		                        BitmapEx aBitmapEx(aPNGReader.Read());
643cdf0e10cSrcweir 								aOut.DrawBitmapEx(aRectangle.TopLeft(), aBitmapEx);
644cdf0e10cSrcweir 							}
645cdf0e10cSrcweir 
646cdf0e10cSrcweir                             if(false)
647cdf0e10cSrcweir                             {
648cdf0e10cSrcweir             					SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
649cdf0e10cSrcweir                                 vcl::PNGReader aPNGReader(aRead);
650cdf0e10cSrcweir 		                        BitmapEx aBitmapEx(aPNGReader.Read());
651cdf0e10cSrcweir 								aOut.DrawBitmapEx(aRectangle.TopLeft(), aRectangle.GetSize(), aBitmapEx);
652cdf0e10cSrcweir 							}
653cdf0e10cSrcweir 
654cdf0e10cSrcweir                             if(false)
655cdf0e10cSrcweir                             {
656cdf0e10cSrcweir             					SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
657cdf0e10cSrcweir                                 vcl::PNGReader aPNGReader(aRead);
658cdf0e10cSrcweir 		                        BitmapEx aBitmapEx(aPNGReader.Read());
659cdf0e10cSrcweir 								const Size aSizePixel(aBitmapEx.GetSizePixel());
660cdf0e10cSrcweir 								aOut.DrawBitmapEx(
661cdf0e10cSrcweir 									aRectangle.TopLeft(),
662cdf0e10cSrcweir 									aRectangle.GetSize(),
663cdf0e10cSrcweir 									Point(0, 0),
664cdf0e10cSrcweir 									Size(aSizePixel.Width() /2, aSizePixel.Height() / 2),
665cdf0e10cSrcweir 									aBitmapEx);
666cdf0e10cSrcweir 							}
667cdf0e10cSrcweir 
668cdf0e10cSrcweir                             if(false)
669cdf0e10cSrcweir                             {
670cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
671cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
672cdf0e10cSrcweir 								const Point aPointA(
673cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(fHor * 0.2),
674cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(fVer * 0.3));
675cdf0e10cSrcweir 								const Point aPointB(
676cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(fHor * 0.2),
677cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(fVer * 0.5));
678cdf0e10cSrcweir 								const Point aPointC(
679cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(fHor * 0.2),
680cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(fVer * 0.7));
681cdf0e10cSrcweir                                 const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8);
682cdf0e10cSrcweir 
683cdf0e10cSrcweir                                 const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8);
684cdf0e10cSrcweir                                 Font aFont(aFontName, Size(0, 1000));
685cdf0e10cSrcweir                                 aFont.SetAlign(ALIGN_BASELINE);
686cdf0e10cSrcweir                                 aFont.SetColor(COL_RED);
687cdf0e10cSrcweir                                 //sal_Int32* pDXArray = new sal_Int32[aText.Len()];
688cdf0e10cSrcweir 
689cdf0e10cSrcweir                                 aFont.SetOutline(true);
690cdf0e10cSrcweir                                 aOut.SetFont(aFont);
691cdf0e10cSrcweir                                 aOut.DrawText(aPointA, aText, 0, aText.Len());
692cdf0e10cSrcweir 
693cdf0e10cSrcweir                                 aFont.SetShadow(true);
694cdf0e10cSrcweir                                 aOut.SetFont(aFont);
695cdf0e10cSrcweir                                 aOut.DrawText(aPointB, aText, 0, aText.Len());
696cdf0e10cSrcweir 
697cdf0e10cSrcweir                                 aFont.SetRelief(RELIEF_EMBOSSED);
698cdf0e10cSrcweir                                 aOut.SetFont(aFont);
699cdf0e10cSrcweir                                 aOut.DrawText(aPointC, aText, 0, aText.Len());
700cdf0e10cSrcweir 
701cdf0e10cSrcweir                                 //delete pDXArray;
702cdf0e10cSrcweir                             }
703cdf0e10cSrcweir 
704cdf0e10cSrcweir                             if(false)
705cdf0e10cSrcweir                             {
706cdf0e10cSrcweir                                 const double fHor(aRectangle.getWidth());
707cdf0e10cSrcweir                                 const double fVer(aRectangle.getHeight());
708cdf0e10cSrcweir 								const Point aPointA(
709cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(fHor * 0.2),
710cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(fVer * 0.3));
711cdf0e10cSrcweir 								const Point aPointB(
712cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(fHor * 0.2),
713cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(fVer * 0.5));
714cdf0e10cSrcweir 								const Point aPointC(
715cdf0e10cSrcweir 									aRectangle.Left() + basegfx::fround(fHor * 0.2),
716cdf0e10cSrcweir 									aRectangle.Top() + basegfx::fround(fVer * 0.7));
717cdf0e10cSrcweir                                 const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8);
718cdf0e10cSrcweir 
719cdf0e10cSrcweir                                 const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8);
720cdf0e10cSrcweir                                 Font aFont(aFontName, Size(0, 1000));
721cdf0e10cSrcweir                                 aFont.SetAlign(ALIGN_BASELINE);
722cdf0e10cSrcweir                                 aFont.SetColor(COL_RED);
723cdf0e10cSrcweir 
724cdf0e10cSrcweir                                 aOut.SetFont(aFont);
725cdf0e10cSrcweir 								const sal_Int32 nWidth(aOut.GetTextWidth(aText, 0, aText.Len()));
726cdf0e10cSrcweir                                 aOut.DrawText(aPointA, aText, 0, aText.Len());
727cdf0e10cSrcweir                                 aOut.DrawTextLine(aPointA, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE);
728cdf0e10cSrcweir                                 aOut.DrawTextLine(aPointB, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE);
729cdf0e10cSrcweir                                 aOut.DrawTextLine(aPointC, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE);
730cdf0e10cSrcweir                             }
731cdf0e10cSrcweir 
732cdf0e10cSrcweir                             aMtf.Stop();
733cdf0e10cSrcweir 			                aMtf.WindStart();
734cdf0e10cSrcweir 		                    aMtf.SetPrefMapMode(MapMode(MAP_100TH_MM));
735cdf0e10cSrcweir 			                aMtf.SetPrefSize(Size(aRectangle.getWidth(), aRectangle.getHeight()));
736cdf0e10cSrcweir 
737cdf0e10cSrcweir                             xPrimitive = Primitive2DReference(
738cdf0e10cSrcweir                                 new MetafilePrimitive2D(
739cdf0e10cSrcweir                                     aTransform,
740cdf0e10cSrcweir                                     aMtf));
741cdf0e10cSrcweir                         }
742cdf0e10cSrcweir                         else
743cdf0e10cSrcweir                         {
744cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
745cdf0e10cSrcweir 	                        // create MetafilePrimitive2D
746cdf0e10cSrcweir                             const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile();
747cdf0e10cSrcweir 
748cdf0e10cSrcweir                             if( aTransformedGraphic.IsRenderGraphic() )
749cdf0e10cSrcweir                             {
750cdf0e10cSrcweir                                 xPrimitive = Primitive2DReference(
751cdf0e10cSrcweir                                     new RenderGraphicPrimitive2D(
752cdf0e10cSrcweir                                         static_cast< MetaRenderGraphicAction* >(rMetafile.GetAction(0))->GetRenderGraphic(),
753cdf0e10cSrcweir                                         aTransform));
754cdf0e10cSrcweir                             }
755cdf0e10cSrcweir                             else
756cdf0e10cSrcweir                             {
757cdf0e10cSrcweir                                 xPrimitive = Primitive2DReference(
758cdf0e10cSrcweir                                     new MetafilePrimitive2D(
759cdf0e10cSrcweir                                         aTransform,
760cdf0e10cSrcweir                                         rMetafile));
761cdf0e10cSrcweir 
762cdf0e10cSrcweir                                 // #i100357# find out if clipping is needed for this primitive. Unfortunately,
763cdf0e10cSrcweir                                 // there exist Metafiles who's content is bigger than the proposed PrefSize set
764cdf0e10cSrcweir                                 // at them. This is an error, but we need to work around this
765cdf0e10cSrcweir                                 const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
766cdf0e10cSrcweir                                 const Size aMetaFileRealSize(
767cdf0e10cSrcweir                                     const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
768cdf0e10cSrcweir                                         *Application::GetDefaultDevice()).GetSize());
769cdf0e10cSrcweir 
770cdf0e10cSrcweir                                 if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
771cdf0e10cSrcweir                                     || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
772cdf0e10cSrcweir                                 {
773cdf0e10cSrcweir                                     // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
774cdf0e10cSrcweir                                     const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
775cdf0e10cSrcweir                                     basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
776cdf0e10cSrcweir                                     aMaskPolygon.transform(aTransform);
777cdf0e10cSrcweir 
778cdf0e10cSrcweir                                     xPrimitive = Primitive2DReference(
779cdf0e10cSrcweir                                         new MaskPrimitive2D(
780cdf0e10cSrcweir                                             basegfx::B2DPolyPolygon(aMaskPolygon),
781cdf0e10cSrcweir                                             aChildContent));
782cdf0e10cSrcweir                                 }
783cdf0e10cSrcweir                             }
784cdf0e10cSrcweir #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
785cdf0e10cSrcweir                         }
786cdf0e10cSrcweir #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
787cdf0e10cSrcweir 
788cdf0e10cSrcweir 						break;
789cdf0e10cSrcweir 					}
790cdf0e10cSrcweir 
791cdf0e10cSrcweir 					default:
792cdf0e10cSrcweir 					{
793cdf0e10cSrcweir 						// nothing to create
794cdf0e10cSrcweir 						break;
795cdf0e10cSrcweir 					}
796cdf0e10cSrcweir 				}
797cdf0e10cSrcweir 
798cdf0e10cSrcweir 				if(xPrimitive.is())
799cdf0e10cSrcweir 				{
800cdf0e10cSrcweir 					// check for cropping
801cdf0e10cSrcweir 					if(getGraphicAttr().IsCropped())
802cdf0e10cSrcweir 					{
803cdf0e10cSrcweir 						// decompose to get current pos and size
804cdf0e10cSrcweir 						basegfx::B2DVector aScale, aTranslate;
805cdf0e10cSrcweir 						double fRotate, fShearX;
806cdf0e10cSrcweir 						getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
807cdf0e10cSrcweir 
808cdf0e10cSrcweir 						// create ranges. The current object range is just scale and translate
809cdf0e10cSrcweir 						const basegfx::B2DRange aCurrent(
810cdf0e10cSrcweir 							aTranslate.getX(), aTranslate.getY(),
811cdf0e10cSrcweir 							aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
812cdf0e10cSrcweir 
813cdf0e10cSrcweir 						// calculate scalings between real image size and logic object size. This
814cdf0e10cSrcweir 						// is necessary since the crop values are relative to original bitmap size
815cdf0e10cSrcweir 						double fFactorX(1.0);
816cdf0e10cSrcweir 						double fFactorY(1.0);
817cdf0e10cSrcweir 
818cdf0e10cSrcweir 						{
819cdf0e10cSrcweir 							const MapMode aMapMode100thmm(MAP_100TH_MM);
820cdf0e10cSrcweir 							Size aBitmapSize(rGraphicObject.GetPrefSize());
821cdf0e10cSrcweir 
822cdf0e10cSrcweir 							// #i95968# better support PrefMapMode; special for MAP_PIXEL was missing
823cdf0e10cSrcweir 							if(MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit())
824cdf0e10cSrcweir 							{
825cdf0e10cSrcweir 								aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm);
826cdf0e10cSrcweir 							}
827cdf0e10cSrcweir 							else
828cdf0e10cSrcweir 							{
829cdf0e10cSrcweir 								aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
830cdf0e10cSrcweir 							}
831cdf0e10cSrcweir 
832cdf0e10cSrcweir 							const double fDivX(aBitmapSize.Width() - getGraphicAttr().GetLeftCrop() - getGraphicAttr().GetRightCrop());
833cdf0e10cSrcweir 							const double fDivY(aBitmapSize.Height() - getGraphicAttr().GetTopCrop() - getGraphicAttr().GetBottomCrop());
834cdf0e10cSrcweir 
835cdf0e10cSrcweir 							if(!basegfx::fTools::equalZero(fDivX))
836cdf0e10cSrcweir 							{
837cdf0e10cSrcweir 								fFactorX = aScale.getX() / fDivX;
838cdf0e10cSrcweir 							}
839cdf0e10cSrcweir 
840cdf0e10cSrcweir 							if(!basegfx::fTools::equalZero(fDivY))
841cdf0e10cSrcweir 							{
842cdf0e10cSrcweir 								fFactorY = aScale.getY() / fDivY;
843cdf0e10cSrcweir 							}
844cdf0e10cSrcweir 						}
845cdf0e10cSrcweir 
846cdf0e10cSrcweir 						// Create cropped range, describes the bounds of the original graphic
847cdf0e10cSrcweir 						basegfx::B2DRange aCropped;
848cdf0e10cSrcweir 						aCropped.expand(aCurrent.getMinimum() - basegfx::B2DPoint(getGraphicAttr().GetLeftCrop() * fFactorX, getGraphicAttr().GetTopCrop() * fFactorY));
849cdf0e10cSrcweir 						aCropped.expand(aCurrent.getMaximum() + basegfx::B2DPoint(getGraphicAttr().GetRightCrop() * fFactorX, getGraphicAttr().GetBottomCrop() * fFactorY));
850cdf0e10cSrcweir 
851cdf0e10cSrcweir 						if(aCropped.isEmpty())
852cdf0e10cSrcweir 						{
853cdf0e10cSrcweir 							// nothing to add since cropped bitmap is completely empty
854cdf0e10cSrcweir 							// xPrimitive will not be used
855cdf0e10cSrcweir 						}
856cdf0e10cSrcweir 						else
857cdf0e10cSrcweir 						{
858cdf0e10cSrcweir 							// build new object transformation for transform primitive which contains xPrimitive
859cdf0e10cSrcweir 							basegfx::B2DHomMatrix aNewObjectTransform(getTransform());
860cdf0e10cSrcweir 							aNewObjectTransform.invert();
861cdf0e10cSrcweir 							aNewObjectTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
862cdf0e10cSrcweir 								aCropped.getWidth(), aCropped.getHeight(),
863cdf0e10cSrcweir 								aCropped.getMinX() - aCurrent.getMinX(), aCropped.getMinY() - aCurrent.getMinY())
864cdf0e10cSrcweir 								* aNewObjectTransform;
865cdf0e10cSrcweir 
866cdf0e10cSrcweir 							// add shear, rotate and translate using combined matrix to speedup
867cdf0e10cSrcweir 							const basegfx::B2DHomMatrix aCombinedMatrix(basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
868cdf0e10cSrcweir 								fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
869cdf0e10cSrcweir 							aNewObjectTransform = aCombinedMatrix * aNewObjectTransform;
870cdf0e10cSrcweir 
871cdf0e10cSrcweir 							// prepare TransformPrimitive2D with xPrimitive
872cdf0e10cSrcweir 							const Primitive2DReference xTransformPrimitive(new TransformPrimitive2D(aNewObjectTransform, Primitive2DSequence(&xPrimitive, 1L)));
873cdf0e10cSrcweir 
874cdf0e10cSrcweir 							if(aCurrent.isInside(aCropped))
875cdf0e10cSrcweir 							{
876cdf0e10cSrcweir 								// cropped just got smaller, no need to really use a mask. Add to destination directly
877cdf0e10cSrcweir 								appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xTransformPrimitive);
878cdf0e10cSrcweir 							}
879cdf0e10cSrcweir 							else
880cdf0e10cSrcweir 							{
881cdf0e10cSrcweir 								// cropped got bigger, mask it with original object's bounds
882cdf0e10cSrcweir 								basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon());
883cdf0e10cSrcweir 								aMaskPolyPolygon.transform(getTransform());
884cdf0e10cSrcweir 
885cdf0e10cSrcweir 								// create maskPrimitive with aMaskPolyPolygon and aMaskContentVector
886cdf0e10cSrcweir 								const Primitive2DReference xRefB(new MaskPrimitive2D(aMaskPolyPolygon, Primitive2DSequence(&xTransformPrimitive, 1L)));
887cdf0e10cSrcweir 								appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRefB);
888cdf0e10cSrcweir 							}
889cdf0e10cSrcweir 						}
890cdf0e10cSrcweir 					}
891cdf0e10cSrcweir 					else
892cdf0e10cSrcweir 					{
893cdf0e10cSrcweir 						// add to decomposition
894cdf0e10cSrcweir 						appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xPrimitive);
895cdf0e10cSrcweir 					}
896cdf0e10cSrcweir 				}
897cdf0e10cSrcweir 			}
898cdf0e10cSrcweir 
899cdf0e10cSrcweir 			return aRetval;
900cdf0e10cSrcweir 		}
901cdf0e10cSrcweir 
902cdf0e10cSrcweir 		GraphicPrimitive2D::GraphicPrimitive2D(
903cdf0e10cSrcweir 			const basegfx::B2DHomMatrix& rTransform,
904cdf0e10cSrcweir 			const GraphicObject& rGraphicObject,
905cdf0e10cSrcweir 			const GraphicAttr& rGraphicAttr)
906cdf0e10cSrcweir 		:	BufferedDecompositionPrimitive2D(),
907cdf0e10cSrcweir 			maTransform(rTransform),
908cdf0e10cSrcweir 			maGraphicObject(rGraphicObject),
909cdf0e10cSrcweir 			maGraphicAttr(rGraphicAttr)
910cdf0e10cSrcweir 		{
911cdf0e10cSrcweir 		}
912cdf0e10cSrcweir 
913cdf0e10cSrcweir 		GraphicPrimitive2D::GraphicPrimitive2D(
914cdf0e10cSrcweir 			const basegfx::B2DHomMatrix& rTransform,
915cdf0e10cSrcweir 			const GraphicObject& rGraphicObject)
916cdf0e10cSrcweir 		:	BufferedDecompositionPrimitive2D(),
917cdf0e10cSrcweir 			maTransform(rTransform),
918cdf0e10cSrcweir 			maGraphicObject(rGraphicObject),
919cdf0e10cSrcweir 			maGraphicAttr()
920cdf0e10cSrcweir 		{
921cdf0e10cSrcweir 		}
922cdf0e10cSrcweir 
923cdf0e10cSrcweir 		bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
924cdf0e10cSrcweir 		{
925cdf0e10cSrcweir 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
926cdf0e10cSrcweir 			{
927cdf0e10cSrcweir 				const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive;
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 				return (getTransform() == rCompare.getTransform()
930cdf0e10cSrcweir 					&& getGraphicObject() == rCompare.getGraphicObject()
931cdf0e10cSrcweir 					&& getGraphicAttr() == rCompare.getGraphicAttr());
932cdf0e10cSrcweir 			}
933cdf0e10cSrcweir 
934cdf0e10cSrcweir 			return false;
935cdf0e10cSrcweir 		}
936cdf0e10cSrcweir 
937cdf0e10cSrcweir 		basegfx::B2DRange GraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
938cdf0e10cSrcweir 		{
939cdf0e10cSrcweir 			basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
940cdf0e10cSrcweir 			aRetval.transform(getTransform());
941cdf0e10cSrcweir 			return aRetval;
942cdf0e10cSrcweir 		}
943cdf0e10cSrcweir 
944cdf0e10cSrcweir 		// provide unique ID
945cdf0e10cSrcweir 		ImplPrimitrive2DIDBlock(GraphicPrimitive2D, PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D)
946cdf0e10cSrcweir 
947cdf0e10cSrcweir 	} // end of namespace primitive2d
948cdf0e10cSrcweir } // end of namespace drawinglayer
949cdf0e10cSrcweir 
950cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
951cdf0e10cSrcweir // eof
952