1035a2f44SArmin Le Grand /**************************************************************
2035a2f44SArmin Le Grand  *
3035a2f44SArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
4035a2f44SArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
5035a2f44SArmin Le Grand  * distributed with this work for additional information
6035a2f44SArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
7035a2f44SArmin Le Grand  * to you under the Apache License, Version 2.0 (the
8035a2f44SArmin Le Grand  * "License"); you may not use this file except in compliance
9035a2f44SArmin Le Grand  * with the License.  You may obtain a copy of the License at
10035a2f44SArmin Le Grand  *
11035a2f44SArmin Le Grand  *   http://www.apache.org/licenses/LICENSE-2.0
12035a2f44SArmin Le Grand  *
13035a2f44SArmin Le Grand  * Unless required by applicable law or agreed to in writing,
14035a2f44SArmin Le Grand  * software distributed under the License is distributed on an
15035a2f44SArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16035a2f44SArmin Le Grand  * KIND, either express or implied.  See the License for the
17035a2f44SArmin Le Grand  * specific language governing permissions and limitations
18035a2f44SArmin Le Grand  * under the License.
19035a2f44SArmin Le Grand  *
20035a2f44SArmin Le Grand  *************************************************************/
21035a2f44SArmin Le Grand 
22035a2f44SArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
23035a2f44SArmin Le Grand #include "precompiled_drawinglayer.hxx"
24035a2f44SArmin Le Grand 
25035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx>
26035a2f44SArmin Le Grand #include <drawinglayer/animation/animationtiming.hxx>
27035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
28035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
29035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
30035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
31035a2f44SArmin Le Grand #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
3249c58f9bSArmin Le Grand #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
33035a2f44SArmin Le Grand #include <basegfx/polygon/b2dpolygon.hxx>
34035a2f44SArmin Le Grand #include <basegfx/polygon/b2dpolygontools.hxx>
3549c58f9bSArmin Le Grand #include <basegfx/numeric/ftools.hxx>
36035a2f44SArmin Le Grand 
37035a2f44SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
38035a2f44SArmin Le Grand // helper class for animated graphics
39035a2f44SArmin Le Grand 
40035a2f44SArmin Le Grand #include <vcl/animate.hxx>
41035a2f44SArmin Le Grand #include <vcl/graph.hxx>
42035a2f44SArmin Le Grand #include <vcl/virdev.hxx>
43035a2f44SArmin Le Grand #include <vcl/svapp.hxx>
44035a2f44SArmin Le Grand #include <vcl/metaact.hxx>
45035a2f44SArmin Le Grand 
46035a2f44SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
47035a2f44SArmin Le Grand // includes for testing MetafilePrimitive2D::create2DDecomposition
48035a2f44SArmin Le Grand 
49035a2f44SArmin Le Grand // this switch defines if the test code is included or not
50035a2f44SArmin Le Grand #undef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
51035a2f44SArmin Le Grand 
52035a2f44SArmin Le Grand #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
53035a2f44SArmin Le Grand #include <vcl/gradient.hxx>
54035a2f44SArmin Le Grand #include <vcl/pngread.hxx>
55035a2f44SArmin Le Grand #include <vcl/lineinfo.hxx>
56035a2f44SArmin Le Grand #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
57035a2f44SArmin Le Grand 
58035a2f44SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
59035a2f44SArmin Le Grand 
60035a2f44SArmin Le Grand namespace
61035a2f44SArmin Le Grand {
62035a2f44SArmin Le Grand 	struct animationStep
63035a2f44SArmin Le Grand 	{
64035a2f44SArmin Le Grand 		BitmapEx								maBitmapEx;
65035a2f44SArmin Le Grand 		sal_uInt32								mnTime;
66035a2f44SArmin Le Grand 	};
67035a2f44SArmin Le Grand 
68035a2f44SArmin Le Grand 	class animatedBitmapExPreparator
69035a2f44SArmin Le Grand 	{
70035a2f44SArmin Le Grand 		::Animation								maAnimation;
71035a2f44SArmin Le Grand 		::std::vector< animationStep >			maSteps;
72035a2f44SArmin Le Grand 
73035a2f44SArmin Le Grand 		sal_uInt32 generateStepTime(sal_uInt32 nIndex) const;
74035a2f44SArmin Le Grand 
75035a2f44SArmin Le Grand 	public:
76035a2f44SArmin Le Grand 		animatedBitmapExPreparator(const Graphic& rGraphic);
77035a2f44SArmin Le Grand 
78035a2f44SArmin Le Grand 		sal_uInt32 count() const { return maSteps.size(); }
79035a2f44SArmin Le Grand 		sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); }
80035a2f44SArmin Le Grand 		sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; }
81035a2f44SArmin Le Grand 		const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; }
82035a2f44SArmin Le Grand 	};
83035a2f44SArmin Le Grand 
84035a2f44SArmin Le Grand 	sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const
85035a2f44SArmin Le Grand 	{
86035a2f44SArmin Le Grand 		const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex));
87035a2f44SArmin Le Grand 		sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10);
88035a2f44SArmin Le Grand 
89035a2f44SArmin Le Grand 		// #115934#
90035a2f44SArmin Le Grand 		// Take care of special value for MultiPage TIFFs. ATM these shall just
91035a2f44SArmin Le Grand 		// show their first page. Later we will offer some switching when object
92035a2f44SArmin Le Grand 		// is selected.
93035a2f44SArmin Le Grand 		if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait)
94035a2f44SArmin Le Grand 		{
95035a2f44SArmin Le Grand 			// ATM the huge value would block the timer, so
96035a2f44SArmin Le Grand 			// use a long time to show first page (whole day)
97035a2f44SArmin Le Grand 			nWaitTime = 100 * 60 * 60 * 24;
98035a2f44SArmin Le Grand 		}
99035a2f44SArmin Le Grand 
100035a2f44SArmin Le Grand 		// Bad trap: There are animated gifs with no set WaitTime (!).
101035a2f44SArmin Le Grand 		// In that case use a default value.
102035a2f44SArmin Le Grand 		if(0L == nWaitTime)
103035a2f44SArmin Le Grand 		{
104035a2f44SArmin Le Grand 			nWaitTime = 100L;
105035a2f44SArmin Le Grand 		}
106035a2f44SArmin Le Grand 
107035a2f44SArmin Le Grand 		return nWaitTime;
108035a2f44SArmin Le Grand 	}
109035a2f44SArmin Le Grand 
110035a2f44SArmin Le Grand 	animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic)
111035a2f44SArmin Le Grand 	:	maAnimation(rGraphic.GetAnimation())
112035a2f44SArmin Le Grand 	{
113035a2f44SArmin Le Grand 		OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)");
114035a2f44SArmin Le Grand 
115035a2f44SArmin Le Grand 		// #128539# secure access to Animation, looks like there exist animated GIFs out there
116035a2f44SArmin Le Grand 		// with a step count of zero
117035a2f44SArmin Le Grand 		if(maAnimation.Count())
118035a2f44SArmin Le Grand 		{
119035a2f44SArmin Le Grand 			VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
120035a2f44SArmin Le Grand 			VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L);
121035a2f44SArmin Le Grand 
122035a2f44SArmin Le Grand 			// Prepare VirtualDevices and their states
123035a2f44SArmin Le Grand 			aVirtualDevice.EnableMapMode(sal_False);
124035a2f44SArmin Le Grand 			aVirtualDeviceMask.EnableMapMode(sal_False);
125035a2f44SArmin Le Grand 			aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
126035a2f44SArmin Le Grand 			aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
127035a2f44SArmin Le Grand 			aVirtualDevice.Erase();
128035a2f44SArmin Le Grand 			aVirtualDeviceMask.Erase();
129035a2f44SArmin Le Grand 
130035a2f44SArmin Le Grand 			for(sal_uInt16 a(0L); a < maAnimation.Count(); a++)
131035a2f44SArmin Le Grand 			{
132035a2f44SArmin Le Grand 				animationStep aNextStep;
133035a2f44SArmin Le Grand 				aNextStep.mnTime = generateStepTime(a);
134035a2f44SArmin Le Grand 
135035a2f44SArmin Le Grand 				// prepare step
136035a2f44SArmin Le Grand 				const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a));
137035a2f44SArmin Le Grand 
138035a2f44SArmin Le Grand 				switch(rAnimBitmap.eDisposal)
139035a2f44SArmin Le Grand 				{
140035a2f44SArmin Le Grand 					case DISPOSE_NOT:
141035a2f44SArmin Le Grand 					{
142035a2f44SArmin Le Grand 						aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
143035a2f44SArmin Le Grand 						Bitmap aMask = rAnimBitmap.aBmpEx.GetMask();
144035a2f44SArmin Le Grand 
145035a2f44SArmin Le Grand 						if(aMask.IsEmpty())
146035a2f44SArmin Le Grand 						{
147035a2f44SArmin Le Grand 							const Point aEmpty;
148035a2f44SArmin Le Grand 							const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel());
149035a2f44SArmin Le Grand 							const Wallpaper aWallpaper(COL_BLACK);
150035a2f44SArmin Le Grand 							aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper);
151035a2f44SArmin Le Grand 						}
152035a2f44SArmin Le Grand 						else
153035a2f44SArmin Le Grand 						{
154035a2f44SArmin Le Grand 							BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask);
155035a2f44SArmin Le Grand 							aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask);
156035a2f44SArmin Le Grand 						}
157035a2f44SArmin Le Grand 
158035a2f44SArmin Le Grand 						break;
159035a2f44SArmin Le Grand 					}
160035a2f44SArmin Le Grand 					case DISPOSE_BACK:
161035a2f44SArmin Le Grand 					{
162035a2f44SArmin Le Grand 						// #i70772# react on no mask, for primitives, too.
163035a2f44SArmin Le Grand 						const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask());
164035a2f44SArmin Le Grand 						const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap());
165035a2f44SArmin Le Grand 
166035a2f44SArmin Le Grand 						aVirtualDeviceMask.Erase();
167035a2f44SArmin Le Grand 						aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent);
168035a2f44SArmin Le Grand 
169035a2f44SArmin Le Grand 						if(aMask.IsEmpty())
170035a2f44SArmin Le Grand 						{
171035a2f44SArmin Le Grand 							const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel());
172035a2f44SArmin Le Grand 							aVirtualDeviceMask.SetFillColor(COL_BLACK);
173035a2f44SArmin Le Grand 							aVirtualDeviceMask.SetLineColor();
174035a2f44SArmin Le Grand 							aVirtualDeviceMask.DrawRect(aRect);
175035a2f44SArmin Le Grand 						}
176035a2f44SArmin Le Grand 						else
177035a2f44SArmin Le Grand 						{
178035a2f44SArmin Le Grand 							aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask);
179035a2f44SArmin Le Grand 						}
180035a2f44SArmin Le Grand 
181035a2f44SArmin Le Grand 						break;
182035a2f44SArmin Le Grand 					}
183035a2f44SArmin Le Grand 					case DISPOSE_FULL:
184035a2f44SArmin Le Grand 					{
185035a2f44SArmin Le Grand 						aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
186035a2f44SArmin Le Grand 						break;
187035a2f44SArmin Le Grand 					}
188035a2f44SArmin Le Grand 					case DISPOSE_PREVIOUS :
189035a2f44SArmin Le Grand 					{
190035a2f44SArmin Le Grand 						aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
191035a2f44SArmin Le Grand 						aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask());
192035a2f44SArmin Le Grand 						break;
193035a2f44SArmin Le Grand 					}
194035a2f44SArmin Le Grand 				}
195035a2f44SArmin Le Grand 
196035a2f44SArmin Le Grand 				// create BitmapEx
197035a2f44SArmin Le Grand 				Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel());
198e4172a75SHerbert Dürr #if defined(MACOSX)
199e4172a75SHerbert Dürr 				AlphaMask aMaskBitmap( aVirtualDeviceMask.GetBitmap( Point(), aVirtualDeviceMask.GetOutputSizePixel()));
200e4172a75SHerbert Dürr #else
201e4172a75SHerbert Dürr 				Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap( Point(), aVirtualDeviceMask.GetOutputSizePixel());
202e4172a75SHerbert Dürr #endif
203035a2f44SArmin Le Grand 				aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap);
204035a2f44SArmin Le Grand 
205035a2f44SArmin Le Grand 				// add to vector
206035a2f44SArmin Le Grand 				maSteps.push_back(aNextStep);
207035a2f44SArmin Le Grand 			}
208035a2f44SArmin Le Grand 		}
209035a2f44SArmin Le Grand 	}
210035a2f44SArmin Le Grand } // end of anonymous namespace
211035a2f44SArmin Le Grand 
212035a2f44SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
213035a2f44SArmin Le Grand 
214035a2f44SArmin Le Grand namespace drawinglayer
215035a2f44SArmin Le Grand {
216035a2f44SArmin Le Grand 	namespace primitive2d
217035a2f44SArmin Le Grand 	{
218035a2f44SArmin Le Grand 		Primitive2DSequence create2DDecompositionOfGraphic(
219035a2f44SArmin Le Grand             const Graphic& rGraphic,
220035a2f44SArmin Le Grand             const basegfx::B2DHomMatrix& rTransform)
221035a2f44SArmin Le Grand 		{
222035a2f44SArmin Le Grand 			Primitive2DSequence aRetval;
223035a2f44SArmin Le Grand 
224035a2f44SArmin Le Grand             switch(rGraphic.GetType())
225035a2f44SArmin Le Grand 			{
226035a2f44SArmin Le Grand 				case GRAPHIC_BITMAP :
227035a2f44SArmin Le Grand 				{
228035a2f44SArmin Le Grand                     if(rGraphic.IsAnimated())
229035a2f44SArmin Le Grand 					{
230035a2f44SArmin Le Grand 						// prepare animation data
231035a2f44SArmin Le Grand 						animatedBitmapExPreparator aData(rGraphic);
232035a2f44SArmin Le Grand 
233035a2f44SArmin Le Grand 						if(aData.count())
234035a2f44SArmin Le Grand 						{
235035a2f44SArmin Le Grand 							// create sub-primitives for animated bitmap and the needed animation loop
236035a2f44SArmin Le Grand 							animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff);
237035a2f44SArmin Le Grand 							Primitive2DSequence aBitmapPrimitives(aData.count());
238035a2f44SArmin Le Grand 
239035a2f44SArmin Le Grand 							for(sal_uInt32 a(0); a < aData.count(); a++)
240035a2f44SArmin Le Grand 							{
241035a2f44SArmin Le Grand                                 animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count());
242035a2f44SArmin Le Grand 								aAnimationLoop.append(aTime);
243035a2f44SArmin Le Grand 								aBitmapPrimitives[a] = new BitmapPrimitive2D(
244035a2f44SArmin Le Grand                                     aData.stepBitmapEx(a),
245035a2f44SArmin Le Grand                                     rTransform);
246035a2f44SArmin Le Grand 							}
247035a2f44SArmin Le Grand 
248035a2f44SArmin Le Grand 							// prepare animation list
249035a2f44SArmin Le Grand 							animation::AnimationEntryList aAnimationList;
250035a2f44SArmin Le Grand 							aAnimationList.append(aAnimationLoop);
251035a2f44SArmin Le Grand 
252035a2f44SArmin Le Grand 							// create and add animated switch primitive
253035a2f44SArmin Le Grand                             aRetval.realloc(1);
254035a2f44SArmin Le Grand 							aRetval[0] = new AnimatedSwitchPrimitive2D(
255035a2f44SArmin Le Grand                                 aAnimationList,
256035a2f44SArmin Le Grand                                 aBitmapPrimitives,
257035a2f44SArmin Le Grand                                 false);
258035a2f44SArmin Le Grand 						}
259035a2f44SArmin Le Grand 					}
260035a2f44SArmin Le Grand                     else if(rGraphic.getSvgData().get())
261035a2f44SArmin Le Grand                     {
262035a2f44SArmin Le Grand                         // embedded Svg fill, create embed transform
263035a2f44SArmin Le Grand                         const basegfx::B2DRange& rSvgRange(rGraphic.getSvgData()->getRange());
264035a2f44SArmin Le Grand 
265035a2f44SArmin Le Grand                         if(basegfx::fTools::more(rSvgRange.getWidth(), 0.0) && basegfx::fTools::more(rSvgRange.getHeight(), 0.0))
266035a2f44SArmin Le Grand                         {
267035a2f44SArmin Le Grand                             // translate back to origin, scale to unit coordinates
268035a2f44SArmin Le Grand                             basegfx::B2DHomMatrix aEmbedSvg(
269035a2f44SArmin Le Grand                                 basegfx::tools::createTranslateB2DHomMatrix(
270035a2f44SArmin Le Grand                                     -rSvgRange.getMinX(),
271035a2f44SArmin Le Grand                                     -rSvgRange.getMinY()));
272035a2f44SArmin Le Grand 
273035a2f44SArmin Le Grand                             aEmbedSvg.scale(
274035a2f44SArmin Le Grand                                 1.0 / rSvgRange.getWidth(),
275035a2f44SArmin Le Grand                                 1.0 / rSvgRange.getHeight());
276035a2f44SArmin Le Grand 
277035a2f44SArmin Le Grand                             // apply created object transformation
278035a2f44SArmin Le Grand                             aEmbedSvg = rTransform * aEmbedSvg;
279035a2f44SArmin Le Grand 
280035a2f44SArmin Le Grand                             // add Svg primitives embedded
281035a2f44SArmin Le Grand                             aRetval.realloc(1);
282035a2f44SArmin Le Grand                             aRetval[0] = new TransformPrimitive2D(
283035a2f44SArmin Le Grand                                 aEmbedSvg,
284035a2f44SArmin Le Grand                                 rGraphic.getSvgData()->getPrimitive2DSequence());
285035a2f44SArmin Le Grand                         }
286035a2f44SArmin Le Grand                     }
287035a2f44SArmin Le Grand 					else
288035a2f44SArmin Le Grand 					{
289035a2f44SArmin Le Grand                         aRetval.realloc(1);
290035a2f44SArmin Le Grand 						aRetval[0] = new BitmapPrimitive2D(
291035a2f44SArmin Le Grand                             rGraphic.GetBitmapEx(),
292035a2f44SArmin Le Grand                             rTransform);
293035a2f44SArmin Le Grand 					}
294035a2f44SArmin Le Grand 
295035a2f44SArmin Le Grand 					break;
296035a2f44SArmin Le Grand 				}
297035a2f44SArmin Le Grand 
298035a2f44SArmin Le Grand 				case GRAPHIC_GDIMETAFILE :
299035a2f44SArmin Le Grand 				{
300035a2f44SArmin Le Grand #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
301035a2f44SArmin Le Grand                     static bool bDoTest(false);
302035a2f44SArmin Le Grand 
303035a2f44SArmin Le Grand                     if(bDoTest)
304035a2f44SArmin Le Grand                     {
305035a2f44SArmin Le Grand 						// All this is/was test code for testing MetafilePrimitive2D::create2DDecomposition
306035a2f44SArmin Le Grand 						// extensively. It may be needed again when diverse actions need debugging, so i leave
307035a2f44SArmin Le Grand 						// it in here, but take it out using USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE.
308035a2f44SArmin Le Grand 						// Use it by compiling with the code, insert any DrawObject, convert to Metafile. The
309035a2f44SArmin Le Grand 						// debugger will then stop here (when breakpoint set, of course). You may enter single
310035a2f44SArmin Le Grand 						// parts of actions and/or change to true what You want to check.
311035a2f44SArmin Le Grand                         GDIMetaFile aMtf;
312035a2f44SArmin Le Grand 			            VirtualDevice aOut;
313035a2f44SArmin Le Grand         		        const basegfx::B2DRange aRange(getB2DRange(rViewInformation));
314035a2f44SArmin Le Grand                         const Rectangle aRectangle(
315035a2f44SArmin Le Grand                             basegfx::fround(aRange.getMinX()), basegfx::fround(aRange.getMinY()),
316035a2f44SArmin Le Grand                             basegfx::fround(aRange.getMaxX()), basegfx::fround(aRange.getMaxY()));
317035a2f44SArmin Le Grand                         const Point aOrigin(aRectangle.TopLeft());
318035a2f44SArmin Le Grand                         const Fraction aScaleX(aRectangle.getWidth());
319035a2f44SArmin Le Grand                         const Fraction aScaleY(aRectangle.getHeight());
320035a2f44SArmin Le Grand                         MapMode aMapMode(MAP_100TH_MM, aOrigin, aScaleX, aScaleY);
321035a2f44SArmin Le Grand 
322035a2f44SArmin Le Grand                         Size aDummySize(2, 2);
323035a2f44SArmin Le Grand                         aOut.SetOutputSizePixel(aDummySize);
324035a2f44SArmin Le Grand 			            aOut.EnableOutput(FALSE);
325035a2f44SArmin Le Grand 			            aOut.SetMapMode(aMapMode);
326035a2f44SArmin Le Grand 
327035a2f44SArmin Le Grand                         aMtf.Clear();
328035a2f44SArmin Le Grand 			            aMtf.Record(&aOut);
329035a2f44SArmin Le Grand 
330035a2f44SArmin Le Grand 			            const Fraction aNeutralFraction(1, 1);
331035a2f44SArmin Le Grand 			            const MapMode aRelativeMapMode(
332035a2f44SArmin Le Grand                             MAP_RELATIVE,
333035a2f44SArmin Le Grand                             Point(-aRectangle.Left(), -aRectangle.Top()),
334035a2f44SArmin Le Grand                             aNeutralFraction, aNeutralFraction);
335035a2f44SArmin Le Grand 			            aOut.SetMapMode(aRelativeMapMode);
336035a2f44SArmin Le Grand 
337035a2f44SArmin Le Grand                         if(false)
338035a2f44SArmin Le Grand                         {
339035a2f44SArmin Le Grand                             const sal_Int32 nHor(aRectangle.getWidth() / 4);
340035a2f44SArmin Le Grand                             const sal_Int32 nVer(aRectangle.getHeight() / 4);
341035a2f44SArmin Le Grand                             const Rectangle aCenteredRectangle(
342035a2f44SArmin Le Grand                                 aRectangle.Left() + nHor, aRectangle.Top() + nVer,
343035a2f44SArmin Le Grand                                 aRectangle.Right() - nHor, aRectangle.Bottom() - nVer);
344035a2f44SArmin Le Grand                             aOut.SetClipRegion(aCenteredRectangle);
345035a2f44SArmin Le Grand                         }
346035a2f44SArmin Le Grand 
347035a2f44SArmin Le Grand                         if(false)
348035a2f44SArmin Le Grand                         {
349035a2f44SArmin Le Grand                             const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight());
350035a2f44SArmin Le Grand                             aOut.IntersectClipRegion(aRightRectangle);
351035a2f44SArmin Le Grand                         }
352035a2f44SArmin Le Grand 
353035a2f44SArmin Le Grand                         if(false)
354035a2f44SArmin Le Grand                         {
355035a2f44SArmin Le Grand                             const Rectangle aRightRectangle(aRectangle.TopCenter(), aRectangle.BottomRight());
356035a2f44SArmin Le Grand                             const Rectangle aBottomRectangle(aRectangle.LeftCenter(), aRectangle.BottomRight());
357035a2f44SArmin Le Grand                             Region aRegion(aRightRectangle);
358035a2f44SArmin Le Grand                             aRegion.Intersect(aBottomRectangle);
359035a2f44SArmin Le Grand                             aOut.IntersectClipRegion(aRegion);
360035a2f44SArmin Le Grand                         }
361035a2f44SArmin Le Grand 
362035a2f44SArmin Le Grand                         if(false)
363035a2f44SArmin Le Grand                         {
364035a2f44SArmin Le Grand                             const sal_Int32 nHor(aRectangle.getWidth() / 10);
365035a2f44SArmin Le Grand                             const sal_Int32 nVer(aRectangle.getHeight() / 10);
366035a2f44SArmin Le Grand                             aOut.MoveClipRegion(nHor, nVer);
367035a2f44SArmin Le Grand                         }
368035a2f44SArmin Le Grand 
369035a2f44SArmin Le Grand                         if(false)
370035a2f44SArmin Le Grand                         {
371035a2f44SArmin Le Grand                             Wallpaper aWallpaper(Color(COL_BLACK));
372035a2f44SArmin Le Grand                             aOut.DrawWallpaper(aRectangle, aWallpaper);
373035a2f44SArmin Le Grand                         }
374035a2f44SArmin Le Grand 
375035a2f44SArmin Le Grand                         if(false)
376035a2f44SArmin Le Grand                         {
377035a2f44SArmin Le Grand                             Wallpaper aWallpaper(Gradient(GRADIENT_LINEAR, Color(COL_RED), Color(COL_GREEN)));
378035a2f44SArmin Le Grand                             aOut.DrawWallpaper(aRectangle, aWallpaper);
379035a2f44SArmin Le Grand                         }
380035a2f44SArmin Le Grand 
381035a2f44SArmin Le Grand                         if(false)
382035a2f44SArmin Le Grand                         {
383035a2f44SArmin Le Grand             				SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
384035a2f44SArmin Le Grand                             vcl::PNGReader aPNGReader(aRead);
385035a2f44SArmin Le Grand 		                    BitmapEx aBitmapEx(aPNGReader.Read());
386035a2f44SArmin Le Grand                             Wallpaper aWallpaper(aBitmapEx);
387035a2f44SArmin Le Grand                             aOut.DrawWallpaper(aRectangle, aWallpaper);
388035a2f44SArmin Le Grand                         }
389035a2f44SArmin Le Grand 
390035a2f44SArmin Le Grand                         if(false)
391035a2f44SArmin Le Grand                         {
392035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
393035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
394035a2f44SArmin Le Grand 							Color aColor(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0));
395035a2f44SArmin Le Grand 
396035a2f44SArmin Le Grand 							for(sal_uInt32 a(0); a < 5000; a++)
397035a2f44SArmin Le Grand 							{
398035a2f44SArmin Le Grand 								const Point aPoint(
399035a2f44SArmin Le Grand 									aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
400035a2f44SArmin Le Grand 									aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
401035a2f44SArmin Le Grand 
402035a2f44SArmin Le Grand 								if(!(a % 3))
403035a2f44SArmin Le Grand 								{
404035a2f44SArmin Le Grand 									aColor = Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0));
405035a2f44SArmin Le Grand 								}
406035a2f44SArmin Le Grand 
407035a2f44SArmin Le Grand 								aOut.DrawPixel(aPoint, aColor);
408035a2f44SArmin Le Grand 							}
409035a2f44SArmin Le Grand 						}
410035a2f44SArmin Le Grand 
411035a2f44SArmin Le Grand                         if(false)
412035a2f44SArmin Le Grand                         {
413035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
414035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
415035a2f44SArmin Le Grand 
416035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
417035a2f44SArmin Le Grand 							aOut.SetFillColor();
418035a2f44SArmin Le Grand 
419035a2f44SArmin Le Grand 							for(sal_uInt32 a(0); a < 5000; a++)
420035a2f44SArmin Le Grand 							{
421035a2f44SArmin Le Grand 								const Point aPoint(
422035a2f44SArmin Le Grand 									aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
423035a2f44SArmin Le Grand 									aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
424035a2f44SArmin Le Grand 								aOut.DrawPixel(aPoint);
425035a2f44SArmin Le Grand 							}
426035a2f44SArmin Le Grand 						}
427035a2f44SArmin Le Grand 
428035a2f44SArmin Le Grand                         if(false)
429035a2f44SArmin Le Grand                         {
430035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
431035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
432035a2f44SArmin Le Grand 
433035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
434035a2f44SArmin Le Grand 							aOut.SetFillColor();
435035a2f44SArmin Le Grand 
436035a2f44SArmin Le Grand 							Point aStart(
437035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
438035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
439035a2f44SArmin Le Grand 							Point aStop(
440035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
441035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
442035a2f44SArmin Le Grand 
443035a2f44SArmin Le Grand 							LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0));
444035a2f44SArmin Le Grand 							bool bUseLineInfo(false);
445035a2f44SArmin Le Grand 
446035a2f44SArmin Le Grand 							for(sal_uInt32 a(0); a < 20; a++)
447035a2f44SArmin Le Grand 							{
448035a2f44SArmin Le Grand 								if(!(a%6))
449035a2f44SArmin Le Grand 								{
450035a2f44SArmin Le Grand 									bUseLineInfo = !bUseLineInfo;
451035a2f44SArmin Le Grand 								}
452035a2f44SArmin Le Grand 
453035a2f44SArmin Le Grand 								if(!(a%4))
454035a2f44SArmin Le Grand 								{
455035a2f44SArmin Le Grand 									aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
456035a2f44SArmin Le Grand 								}
457035a2f44SArmin Le Grand 
458035a2f44SArmin Le Grand 								if(a%3)
459035a2f44SArmin Le Grand 								{
460035a2f44SArmin Le Grand 									aStart = aStop;
461035a2f44SArmin Le Grand 									aStop = Point(
462035a2f44SArmin Le Grand 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
463035a2f44SArmin Le Grand 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
464035a2f44SArmin Le Grand 								}
465035a2f44SArmin Le Grand 								else
466035a2f44SArmin Le Grand 								{
467035a2f44SArmin Le Grand 									aStart = Point(
468035a2f44SArmin Le Grand 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
469035a2f44SArmin Le Grand 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
470035a2f44SArmin Le Grand 									aStop = Point(
471035a2f44SArmin Le Grand 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
472035a2f44SArmin Le Grand 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
473035a2f44SArmin Le Grand 								}
474035a2f44SArmin Le Grand 
475035a2f44SArmin Le Grand 								if(bUseLineInfo)
476035a2f44SArmin Le Grand 								{
477035a2f44SArmin Le Grand 									aOut.DrawLine(aStart, aStop, aLineInfo);
478035a2f44SArmin Le Grand 								}
479035a2f44SArmin Le Grand 								else
480035a2f44SArmin Le Grand 								{
481035a2f44SArmin Le Grand 									aOut.DrawLine(aStart, aStop);
482035a2f44SArmin Le Grand 								}
483035a2f44SArmin Le Grand 							}
484035a2f44SArmin Le Grand 						}
485035a2f44SArmin Le Grand 
486035a2f44SArmin Le Grand                         if(false)
487035a2f44SArmin Le Grand                         {
488035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
489035a2f44SArmin Le Grand 							aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
490035a2f44SArmin Le Grand 							aOut.DrawRect(aRectangle);
491035a2f44SArmin Le Grand 						}
492035a2f44SArmin Le Grand 
493035a2f44SArmin Le Grand                         if(false)
494035a2f44SArmin Le Grand                         {
495035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
496035a2f44SArmin Le Grand 							aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
497035a2f44SArmin Le Grand                             const sal_uInt32 nHor(aRectangle.getWidth() / 10);
498035a2f44SArmin Le Grand                             const sal_uInt32 nVer(aRectangle.getHeight() / 10);
499035a2f44SArmin Le Grand 							aOut.DrawRect(aRectangle, nHor, nVer);
500035a2f44SArmin Le Grand 						}
501035a2f44SArmin Le Grand 
502035a2f44SArmin Le Grand                         if(false)
503035a2f44SArmin Le Grand                         {
504035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
505035a2f44SArmin Le Grand 							aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
506035a2f44SArmin Le Grand 							aOut.DrawEllipse(aRectangle);
507035a2f44SArmin Le Grand 						}
508035a2f44SArmin Le Grand 
509035a2f44SArmin Le Grand                         if(false)
510035a2f44SArmin Le Grand                         {
511035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
512035a2f44SArmin Le Grand 							aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
513035a2f44SArmin Le Grand 							aOut.DrawArc(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter());
514035a2f44SArmin Le Grand 						}
515035a2f44SArmin Le Grand 
516035a2f44SArmin Le Grand                         if(false)
517035a2f44SArmin Le Grand                         {
518035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
519035a2f44SArmin Le Grand 							aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
520035a2f44SArmin Le Grand 							aOut.DrawPie(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter());
521035a2f44SArmin Le Grand 						}
522035a2f44SArmin Le Grand 
523035a2f44SArmin Le Grand                         if(false)
524035a2f44SArmin Le Grand                         {
525035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
526035a2f44SArmin Le Grand 							aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
527035a2f44SArmin Le Grand 							aOut.DrawChord(aRectangle, aRectangle.TopLeft(), aRectangle.BottomCenter());
528035a2f44SArmin Le Grand 						}
529035a2f44SArmin Le Grand 
530035a2f44SArmin Le Grand                         if(false)
531035a2f44SArmin Le Grand                         {
532035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
533035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
534035a2f44SArmin Le Grand 
535035a2f44SArmin Le Grand 							for(sal_uInt32 b(0); b < 5; b++)
536035a2f44SArmin Le Grand 							{
537035a2f44SArmin Le Grand 								const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0)));
538035a2f44SArmin Le Grand 								const bool bClose(basegfx::fround(rand() / 32767.0));
539035a2f44SArmin Le Grand 								Polygon aPolygon(nCount + (bClose ? 1 : 0));
540035a2f44SArmin Le Grand 
541035a2f44SArmin Le Grand 								for(sal_uInt32 a(0); a < nCount; a++)
542035a2f44SArmin Le Grand 								{
543035a2f44SArmin Le Grand 									const Point aPoint(
544035a2f44SArmin Le Grand 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
545035a2f44SArmin Le Grand 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
546035a2f44SArmin Le Grand 									aPolygon[a] = aPoint;
547035a2f44SArmin Le Grand 								}
548035a2f44SArmin Le Grand 
549035a2f44SArmin Le Grand 								if(bClose)
550035a2f44SArmin Le Grand 								{
551035a2f44SArmin Le Grand 									aPolygon[aPolygon.GetSize() - 1] = aPolygon[0];
552035a2f44SArmin Le Grand 								}
553035a2f44SArmin Le Grand 
554035a2f44SArmin Le Grand 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
555035a2f44SArmin Le Grand 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
556035a2f44SArmin Le Grand 
557035a2f44SArmin Le Grand 								if(!(b%2))
558035a2f44SArmin Le Grand 								{
559035a2f44SArmin Le Grand 									const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(fHor / 50.0));
560035a2f44SArmin Le Grand 									aOut.DrawPolyLine(aPolygon, aLineInfo);
561035a2f44SArmin Le Grand 								}
562035a2f44SArmin Le Grand 								else
563035a2f44SArmin Le Grand 								{
564035a2f44SArmin Le Grand 									aOut.DrawPolyLine(aPolygon);
565035a2f44SArmin Le Grand 								}
566035a2f44SArmin Le Grand 							}
567035a2f44SArmin Le Grand 						}
568035a2f44SArmin Le Grand 
569035a2f44SArmin Le Grand                         if(false)
570035a2f44SArmin Le Grand                         {
571035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
572035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
573035a2f44SArmin Le Grand 
574035a2f44SArmin Le Grand 							for(sal_uInt32 b(0); b < 5; b++)
575035a2f44SArmin Le Grand 							{
576035a2f44SArmin Le Grand 								const sal_uInt32 nCount(basegfx::fround(rand() * (20 / 32767.0)));
577035a2f44SArmin Le Grand 								const bool bClose(basegfx::fround(rand() / 32767.0));
578035a2f44SArmin Le Grand 								Polygon aPolygon(nCount + (bClose ? 1 : 0));
579035a2f44SArmin Le Grand 
580035a2f44SArmin Le Grand 								for(sal_uInt32 a(0); a < nCount; a++)
581035a2f44SArmin Le Grand 								{
582035a2f44SArmin Le Grand 									const Point aPoint(
583035a2f44SArmin Le Grand 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
584035a2f44SArmin Le Grand 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
585035a2f44SArmin Le Grand 									aPolygon[a] = aPoint;
586035a2f44SArmin Le Grand 								}
587035a2f44SArmin Le Grand 
588035a2f44SArmin Le Grand 								if(bClose)
589035a2f44SArmin Le Grand 								{
590035a2f44SArmin Le Grand 									aPolygon[aPolygon.GetSize() - 1] = aPolygon[0];
591035a2f44SArmin Le Grand 								}
592035a2f44SArmin Le Grand 
593035a2f44SArmin Le Grand 								aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
594035a2f44SArmin Le Grand 								aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
595035a2f44SArmin Le Grand 								aOut.DrawPolygon(aPolygon);
596035a2f44SArmin Le Grand 							}
597035a2f44SArmin Le Grand 						}
598035a2f44SArmin Le Grand 
599035a2f44SArmin Le Grand                         if(false)
600035a2f44SArmin Le Grand                         {
601035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
602035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
603035a2f44SArmin Le Grand 							PolyPolygon aPolyPolygon;
604035a2f44SArmin Le Grand 
605035a2f44SArmin Le Grand 							for(sal_uInt32 b(0); b < 3; b++)
606035a2f44SArmin Le Grand 							{
607035a2f44SArmin Le Grand 								const sal_uInt32 nCount(basegfx::fround(rand() * (6 / 32767.0)));
608035a2f44SArmin Le Grand 								const bool bClose(basegfx::fround(rand() / 32767.0));
609035a2f44SArmin Le Grand 								Polygon aPolygon(nCount + (bClose ? 1 : 0));
610035a2f44SArmin Le Grand 
611035a2f44SArmin Le Grand 								for(sal_uInt32 a(0); a < nCount; a++)
612035a2f44SArmin Le Grand 								{
613035a2f44SArmin Le Grand 									const Point aPoint(
614035a2f44SArmin Le Grand 										aRectangle.Left() + basegfx::fround(rand() * (fHor / 32767.0)),
615035a2f44SArmin Le Grand 										aRectangle.Top() + basegfx::fround(rand() * (fVer / 32767.0)));
616035a2f44SArmin Le Grand 									aPolygon[a] = aPoint;
617035a2f44SArmin Le Grand 								}
618035a2f44SArmin Le Grand 
619035a2f44SArmin Le Grand 								if(bClose)
620035a2f44SArmin Le Grand 								{
621035a2f44SArmin Le Grand 									aPolygon[aPolygon.GetSize() - 1] = aPolygon[0];
622035a2f44SArmin Le Grand 								}
623035a2f44SArmin Le Grand 
624035a2f44SArmin Le Grand 								aPolyPolygon.Insert(aPolygon);
625035a2f44SArmin Le Grand 							}
626035a2f44SArmin Le Grand 
627035a2f44SArmin Le Grand 							aOut.SetLineColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
628035a2f44SArmin Le Grand 							aOut.SetFillColor(Color(basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)));
629035a2f44SArmin Le Grand 							aOut.DrawPolyPolygon(aPolyPolygon);
630035a2f44SArmin Le Grand 						}
631035a2f44SArmin Le Grand 
632035a2f44SArmin Le Grand                         if(false)
633035a2f44SArmin Le Grand                         {
634035a2f44SArmin Le Grand             				SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
635035a2f44SArmin Le Grand                             vcl::PNGReader aPNGReader(aRead);
636035a2f44SArmin Le Grand 		                    BitmapEx aBitmapEx(aPNGReader.Read());
637035a2f44SArmin Le Grand 							aOut.DrawBitmapEx(aRectangle.TopLeft(), aBitmapEx);
638035a2f44SArmin Le Grand 						}
639035a2f44SArmin Le Grand 
640035a2f44SArmin Le Grand                         if(false)
641035a2f44SArmin Le Grand                         {
642035a2f44SArmin Le Grand             				SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
643035a2f44SArmin Le Grand                             vcl::PNGReader aPNGReader(aRead);
644035a2f44SArmin Le Grand 		                    BitmapEx aBitmapEx(aPNGReader.Read());
645035a2f44SArmin Le Grand 							aOut.DrawBitmapEx(aRectangle.TopLeft(), aRectangle.GetSize(), aBitmapEx);
646035a2f44SArmin Le Grand 						}
647035a2f44SArmin Le Grand 
648035a2f44SArmin Le Grand                         if(false)
649035a2f44SArmin Le Grand                         {
650035a2f44SArmin Le Grand             				SvFileStream aRead((const String&)String(ByteString( "c:\\test.png" ), RTL_TEXTENCODING_UTF8), STREAM_READ);
651035a2f44SArmin Le Grand                             vcl::PNGReader aPNGReader(aRead);
652035a2f44SArmin Le Grand 		                    BitmapEx aBitmapEx(aPNGReader.Read());
653035a2f44SArmin Le Grand 							const Size aSizePixel(aBitmapEx.GetSizePixel());
654035a2f44SArmin Le Grand 							aOut.DrawBitmapEx(
655035a2f44SArmin Le Grand 								aRectangle.TopLeft(),
656035a2f44SArmin Le Grand 								aRectangle.GetSize(),
657035a2f44SArmin Le Grand 								Point(0, 0),
658035a2f44SArmin Le Grand 								Size(aSizePixel.Width() /2, aSizePixel.Height() / 2),
659035a2f44SArmin Le Grand 								aBitmapEx);
660035a2f44SArmin Le Grand 						}
661035a2f44SArmin Le Grand 
662035a2f44SArmin Le Grand                         if(false)
663035a2f44SArmin Le Grand                         {
664035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
665035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
666035a2f44SArmin Le Grand 							const Point aPointA(
667035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(fHor * 0.2),
668035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(fVer * 0.3));
669035a2f44SArmin Le Grand 							const Point aPointB(
670035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(fHor * 0.2),
671035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(fVer * 0.5));
672035a2f44SArmin Le Grand 							const Point aPointC(
673035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(fHor * 0.2),
674035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(fVer * 0.7));
675035a2f44SArmin Le Grand                             const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8);
676035a2f44SArmin Le Grand 
677035a2f44SArmin Le Grand                             const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8);
678035a2f44SArmin Le Grand                             Font aFont(aFontName, Size(0, 1000));
679035a2f44SArmin Le Grand                             aFont.SetAlign(ALIGN_BASELINE);
680035a2f44SArmin Le Grand                             aFont.SetColor(COL_RED);
681035a2f44SArmin Le Grand                             //sal_Int32* pDXArray = new sal_Int32[aText.Len()];
682035a2f44SArmin Le Grand 
683035a2f44SArmin Le Grand                             aFont.SetOutline(true);
684035a2f44SArmin Le Grand                             aOut.SetFont(aFont);
685035a2f44SArmin Le Grand                             aOut.DrawText(aPointA, aText, 0, aText.Len());
686035a2f44SArmin Le Grand 
687035a2f44SArmin Le Grand                             aFont.SetShadow(true);
688035a2f44SArmin Le Grand                             aOut.SetFont(aFont);
689035a2f44SArmin Le Grand                             aOut.DrawText(aPointB, aText, 0, aText.Len());
690035a2f44SArmin Le Grand 
691035a2f44SArmin Le Grand                             aFont.SetRelief(RELIEF_EMBOSSED);
692035a2f44SArmin Le Grand                             aOut.SetFont(aFont);
693035a2f44SArmin Le Grand                             aOut.DrawText(aPointC, aText, 0, aText.Len());
694035a2f44SArmin Le Grand 
695035a2f44SArmin Le Grand                             //delete pDXArray;
696035a2f44SArmin Le Grand                         }
697035a2f44SArmin Le Grand 
698035a2f44SArmin Le Grand                         if(false)
699035a2f44SArmin Le Grand                         {
700035a2f44SArmin Le Grand                             const double fHor(aRectangle.getWidth());
701035a2f44SArmin Le Grand                             const double fVer(aRectangle.getHeight());
702035a2f44SArmin Le Grand 							const Point aPointA(
703035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(fHor * 0.2),
704035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(fVer * 0.3));
705035a2f44SArmin Le Grand 							const Point aPointB(
706035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(fHor * 0.2),
707035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(fVer * 0.5));
708035a2f44SArmin Le Grand 							const Point aPointC(
709035a2f44SArmin Le Grand 								aRectangle.Left() + basegfx::fround(fHor * 0.2),
710035a2f44SArmin Le Grand 								aRectangle.Top() + basegfx::fround(fVer * 0.7));
711035a2f44SArmin Le Grand                             const String aText(ByteString("Hello, World!"), RTL_TEXTENCODING_UTF8);
712035a2f44SArmin Le Grand 
713035a2f44SArmin Le Grand                             const String aFontName(ByteString("Comic Sans MS"), RTL_TEXTENCODING_UTF8);
714035a2f44SArmin Le Grand                             Font aFont(aFontName, Size(0, 1000));
715035a2f44SArmin Le Grand                             aFont.SetAlign(ALIGN_BASELINE);
716035a2f44SArmin Le Grand                             aFont.SetColor(COL_RED);
717035a2f44SArmin Le Grand 
718035a2f44SArmin Le Grand                             aOut.SetFont(aFont);
719035a2f44SArmin Le Grand 							const sal_Int32 nWidth(aOut.GetTextWidth(aText, 0, aText.Len()));
720035a2f44SArmin Le Grand                             aOut.DrawText(aPointA, aText, 0, aText.Len());
721035a2f44SArmin Le Grand                             aOut.DrawTextLine(aPointA, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE);
722035a2f44SArmin Le Grand                             aOut.DrawTextLine(aPointB, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE);
723035a2f44SArmin Le Grand                             aOut.DrawTextLine(aPointC, nWidth, STRIKEOUT_SINGLE, UNDERLINE_SINGLE, UNDERLINE_SMALLWAVE);
724035a2f44SArmin Le Grand                         }
725035a2f44SArmin Le Grand 
726035a2f44SArmin Le Grand                         aMtf.Stop();
727035a2f44SArmin Le Grand 			            aMtf.WindStart();
728035a2f44SArmin Le Grand 		                aMtf.SetPrefMapMode(MapMode(MAP_100TH_MM));
729035a2f44SArmin Le Grand 			            aMtf.SetPrefSize(Size(aRectangle.getWidth(), aRectangle.getHeight()));
730035a2f44SArmin Le Grand 
731035a2f44SArmin Le Grand                         aRetval.realloc(1);
732035a2f44SArmin Le Grand                         aRetval[0] = new MetafilePrimitive2D(
733035a2f44SArmin Le Grand                             rTransform,
734035a2f44SArmin Le Grand                             aMtf);
735035a2f44SArmin Le Grand                     }
736035a2f44SArmin Le Grand                     else
737035a2f44SArmin Le Grand                     {
738035a2f44SArmin Le Grand #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
739035a2f44SArmin Le Grand                         // create MetafilePrimitive2D
740035a2f44SArmin Le Grand                         const GDIMetaFile& rMetafile = rGraphic.GetGDIMetaFile();
741035a2f44SArmin Le Grand 
742035a2f44SArmin Le Grand                         aRetval.realloc(1);
743035a2f44SArmin Le Grand                         aRetval[0] = new MetafilePrimitive2D(
744035a2f44SArmin Le Grand                             rTransform,
745035a2f44SArmin Le Grand                             rMetafile);
746035a2f44SArmin Le Grand 
747035a2f44SArmin Le Grand                         // #i100357# find out if clipping is needed for this primitive. Unfortunately,
748035a2f44SArmin Le Grand                         // there exist Metafiles who's content is bigger than the proposed PrefSize set
749035a2f44SArmin Le Grand                         // at them. This is an error, but we need to work around this
750035a2f44SArmin Le Grand                         const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
751035a2f44SArmin Le Grand                         const Size aMetaFileRealSize(
752035a2f44SArmin Le Grand                             const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
753035a2f44SArmin Le Grand                                 *Application::GetDefaultDevice()).GetSize());
754035a2f44SArmin Le Grand 
755035a2f44SArmin Le Grand                         if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
756035a2f44SArmin Le Grand                             || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
757035a2f44SArmin Le Grand                         {
758035a2f44SArmin Le Grand                             // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
759035a2f44SArmin Le Grand                             basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
760035a2f44SArmin Le Grand                             aMaskPolygon.transform(rTransform);
761035a2f44SArmin Le Grand 
762*05639988SArmin Le Grand                             // #124073# the clde below was compiler-dependent. Normally,
763*05639988SArmin Le Grand                             // a compiler will
764*05639988SArmin Le Grand                             // - alloc mem
765*05639988SArmin Le Grand                             // - ececute the constructor
766*05639988SArmin Le Grand                             // - do the assignment
767*05639988SArmin Le Grand                             // but the mac compiler does alloc-assign-constructor, thus
768*05639988SArmin Le Grand                             // modifying aRetval[0] befure aRetval gets used in the
769*05639988SArmin Le Grand                             // constructor. This creates an endless loop in the primitive
770*05639988SArmin Le Grand                             // stack. Thus do it the safe way.
771*05639988SArmin Le Grand                             //
772*05639988SArmin Le Grand                             // aRetval[0] = new MaskPrimitive2D(
773*05639988SArmin Le Grand                             //     basegfx::B2DPolyPolygon(aMaskPolygon),
774*05639988SArmin Le Grand                             //     aRetval);
775*05639988SArmin Le Grand                             MaskPrimitive2D* pMaskPrimitive2D = new MaskPrimitive2D(
776035a2f44SArmin Le Grand                                 basegfx::B2DPolyPolygon(aMaskPolygon),
777035a2f44SArmin Le Grand                                 aRetval);
778*05639988SArmin Le Grand                             aRetval[0] = pMaskPrimitive2D;
779035a2f44SArmin Le Grand                         }
780035a2f44SArmin Le Grand #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
781035a2f44SArmin Le Grand                     }
782035a2f44SArmin Le Grand #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
783035a2f44SArmin Le Grand 
784035a2f44SArmin Le Grand 					break;
785035a2f44SArmin Le Grand 				}
786035a2f44SArmin Le Grand 
787035a2f44SArmin Le Grand 				default:
788035a2f44SArmin Le Grand 				{
789035a2f44SArmin Le Grand 					// nothing to create
790035a2f44SArmin Le Grand 					break;
791035a2f44SArmin Le Grand 				}
792035a2f44SArmin Le Grand 			}
793035a2f44SArmin Le Grand 
794035a2f44SArmin Le Grand 			return aRetval;
795035a2f44SArmin Le Grand 		}
796035a2f44SArmin Le Grand 	} // end of namespace primitive2d
797035a2f44SArmin Le Grand } // end of namespace drawinglayer
798035a2f44SArmin Le Grand 
79949c58f9bSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
80049c58f9bSArmin Le Grand 
80149c58f9bSArmin Le Grand namespace drawinglayer
80249c58f9bSArmin Le Grand {
80349c58f9bSArmin Le Grand     namespace primitive2d
80449c58f9bSArmin Le Grand     {
80549c58f9bSArmin Le Grand         Primitive2DSequence create2DColorModifierEmbeddingsAsNeeded(
80649c58f9bSArmin Le Grand             const Primitive2DSequence& rChildren,
80749c58f9bSArmin Le Grand             GraphicDrawMode aGraphicDrawMode,
80849c58f9bSArmin Le Grand             double fLuminance,
80949c58f9bSArmin Le Grand             double fContrast,
81049c58f9bSArmin Le Grand             double fRed,
81149c58f9bSArmin Le Grand             double fGreen,
81249c58f9bSArmin Le Grand             double fBlue,
81349c58f9bSArmin Le Grand             double fGamma,
81449c58f9bSArmin Le Grand             bool bInvert)
81549c58f9bSArmin Le Grand         {
81649c58f9bSArmin Le Grand             Primitive2DSequence aRetval;
81749c58f9bSArmin Le Grand 
81849c58f9bSArmin Le Grand             if(!rChildren.getLength())
81949c58f9bSArmin Le Grand             {
82049c58f9bSArmin Le Grand                 // no child content, done
82149c58f9bSArmin Le Grand                 return aRetval;
82249c58f9bSArmin Le Grand             }
82349c58f9bSArmin Le Grand 
82449c58f9bSArmin Le Grand             // set child content as retval; that is what will be used as child content in all
82549c58f9bSArmin Le Grand             // embeddings from here
82649c58f9bSArmin Le Grand             aRetval = rChildren;
82749c58f9bSArmin Le Grand 
82849c58f9bSArmin Le Grand             if(GRAPHICDRAWMODE_WATERMARK == aGraphicDrawMode)
82949c58f9bSArmin Le Grand             {
83049c58f9bSArmin Le Grand                 // this is solved by applying fixed values additionally to luminance
83149c58f9bSArmin Le Grand                 // and contrast, do it here and reset DrawMode to GRAPHICDRAWMODE_STANDARD
83249c58f9bSArmin Le Grand                 // original in svtools uses:
83349c58f9bSArmin Le Grand                 // #define WATERMARK_LUM_OFFSET        50
83449c58f9bSArmin Le Grand                 // #define WATERMARK_CON_OFFSET        -70
83549c58f9bSArmin Le Grand                 fLuminance = basegfx::clamp(fLuminance + 0.5, -1.0, 1.0);
83649c58f9bSArmin Le Grand                 fContrast = basegfx::clamp(fContrast - 0.7, -1.0, 1.0);
83749c58f9bSArmin Le Grand                 aGraphicDrawMode = GRAPHICDRAWMODE_STANDARD;
83849c58f9bSArmin Le Grand             }
83949c58f9bSArmin Le Grand 
84049c58f9bSArmin Le Grand             // DrawMode (GRAPHICDRAWMODE_WATERMARK already handled)
84149c58f9bSArmin Le Grand             switch(aGraphicDrawMode)
84249c58f9bSArmin Le Grand             {
84349c58f9bSArmin Le Grand                 case GRAPHICDRAWMODE_GREYS:
84449c58f9bSArmin Le Grand                 {
84549c58f9bSArmin Le Grand                     // convert to grey
84649c58f9bSArmin Le Grand                     const Primitive2DReference aPrimitiveGrey(
84749c58f9bSArmin Le Grand                         new ModifiedColorPrimitive2D(
84849c58f9bSArmin Le Grand                             aRetval,
84949c58f9bSArmin Le Grand                             basegfx::BColorModifierSharedPtr(
85049c58f9bSArmin Le Grand                                 new basegfx::BColorModifier_gray())));
85149c58f9bSArmin Le Grand 
85249c58f9bSArmin Le Grand                     aRetval = Primitive2DSequence(&aPrimitiveGrey, 1);
85349c58f9bSArmin Le Grand                     break;
85449c58f9bSArmin Le Grand                 }
85549c58f9bSArmin Le Grand                 case GRAPHICDRAWMODE_MONO:
85649c58f9bSArmin Le Grand                 {
85749c58f9bSArmin Le Grand                     // convert to mono (black/white with threshold 0.5)
85849c58f9bSArmin Le Grand                     const Primitive2DReference aPrimitiveBlackAndWhite(
85949c58f9bSArmin Le Grand                         new ModifiedColorPrimitive2D(
86049c58f9bSArmin Le Grand                             aRetval,
86149c58f9bSArmin Le Grand                             basegfx::BColorModifierSharedPtr(
86249c58f9bSArmin Le Grand                                 new basegfx::BColorModifier_black_and_white(0.5))));
86349c58f9bSArmin Le Grand 
86449c58f9bSArmin Le Grand                     aRetval = Primitive2DSequence(&aPrimitiveBlackAndWhite, 1);
86549c58f9bSArmin Le Grand                     break;
86649c58f9bSArmin Le Grand                 }
86749c58f9bSArmin Le Grand                 case GRAPHICDRAWMODE_WATERMARK:
86849c58f9bSArmin Le Grand                 {
86949c58f9bSArmin Le Grand                     OSL_ENSURE(false, "OOps, GRAPHICDRAWMODE_WATERMARK should already be handled (see above)");
87049c58f9bSArmin Le Grand                     // fallthrough intended
87149c58f9bSArmin Le Grand                 }
87249c58f9bSArmin Le Grand                 default: // case GRAPHICDRAWMODE_STANDARD:
87349c58f9bSArmin Le Grand                 {
87449c58f9bSArmin Le Grand                     // nothing to do
87549c58f9bSArmin Le Grand                     break;
87649c58f9bSArmin Le Grand                 }
87749c58f9bSArmin Le Grand             }
87849c58f9bSArmin Le Grand 
87949c58f9bSArmin Le Grand             // mnContPercent, mnLumPercent, mnRPercent, mnGPercent, mnBPercent
88049c58f9bSArmin Le Grand             // handled in a single call
88149c58f9bSArmin Le Grand             if(!basegfx::fTools::equalZero(fLuminance)
88249c58f9bSArmin Le Grand                 || !basegfx::fTools::equalZero(fContrast)
88349c58f9bSArmin Le Grand                 || !basegfx::fTools::equalZero(fRed)
88449c58f9bSArmin Le Grand                 || !basegfx::fTools::equalZero(fGreen)
88549c58f9bSArmin Le Grand                 || !basegfx::fTools::equalZero(fBlue))
88649c58f9bSArmin Le Grand             {
88749c58f9bSArmin Le Grand                 const Primitive2DReference aPrimitiveRGBLuminannceContrast(
88849c58f9bSArmin Le Grand                     new ModifiedColorPrimitive2D(
88949c58f9bSArmin Le Grand                         aRetval,
89049c58f9bSArmin Le Grand                         basegfx::BColorModifierSharedPtr(
89149c58f9bSArmin Le Grand                             new basegfx::BColorModifier_RGBLuminanceContrast(
89249c58f9bSArmin Le Grand                                 fRed,
89349c58f9bSArmin Le Grand                                 fGreen,
89449c58f9bSArmin Le Grand                                 fBlue,
89549c58f9bSArmin Le Grand                                 fLuminance,
89649c58f9bSArmin Le Grand                                 fContrast))));
89749c58f9bSArmin Le Grand 
89849c58f9bSArmin Le Grand                 aRetval = Primitive2DSequence(&aPrimitiveRGBLuminannceContrast, 1);
89949c58f9bSArmin Le Grand             }
90049c58f9bSArmin Le Grand 
90149c58f9bSArmin Le Grand             // gamma (boolean)
90249c58f9bSArmin Le Grand             if(!basegfx::fTools::equal(fGamma, 1.0))
90349c58f9bSArmin Le Grand             {
90449c58f9bSArmin Le Grand                 const Primitive2DReference aPrimitiveGamma(
90549c58f9bSArmin Le Grand                     new ModifiedColorPrimitive2D(
90649c58f9bSArmin Le Grand                         aRetval,
90749c58f9bSArmin Le Grand                         basegfx::BColorModifierSharedPtr(
90849c58f9bSArmin Le Grand                             new basegfx::BColorModifier_gamma(
90949c58f9bSArmin Le Grand                                 fGamma))));
91049c58f9bSArmin Le Grand 
91149c58f9bSArmin Le Grand                 aRetval = Primitive2DSequence(&aPrimitiveGamma, 1);
91249c58f9bSArmin Le Grand             }
91349c58f9bSArmin Le Grand 
91449c58f9bSArmin Le Grand             // invert (boolean)
91549c58f9bSArmin Le Grand             if(bInvert)
91649c58f9bSArmin Le Grand             {
91749c58f9bSArmin Le Grand                 const Primitive2DReference aPrimitiveInvert(
91849c58f9bSArmin Le Grand                     new ModifiedColorPrimitive2D(
91949c58f9bSArmin Le Grand                         aRetval,
92049c58f9bSArmin Le Grand                         basegfx::BColorModifierSharedPtr(
92149c58f9bSArmin Le Grand                             new basegfx::BColorModifier_invert())));
92249c58f9bSArmin Le Grand 
92349c58f9bSArmin Le Grand                 aRetval = Primitive2DSequence(&aPrimitiveInvert, 1);
92449c58f9bSArmin Le Grand             }
92549c58f9bSArmin Le Grand 
92649c58f9bSArmin Le Grand             return aRetval;
92749c58f9bSArmin Le Grand         }
92849c58f9bSArmin Le Grand 
92949c58f9bSArmin Le Grand     } // end of namespace primitive2d
93049c58f9bSArmin Le Grand } // end of namespace drawinglayer
93149c58f9bSArmin Le Grand 
932035a2f44SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
933035a2f44SArmin Le Grand // eof
934