xref: /AOO41X/main/vcl/source/gdi/gdimtf.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir #include <vos/macros.hxx>
31*cdf0e10cSrcweir #include <rtl/crc.h>
32*cdf0e10cSrcweir #include <tools/stream.hxx>
33*cdf0e10cSrcweir #include <tools/vcompat.hxx>
34*cdf0e10cSrcweir #include <vcl/metaact.hxx>
35*cdf0e10cSrcweir #include <vcl/salbtype.hxx>
36*cdf0e10cSrcweir #include <vcl/outdev.hxx>
37*cdf0e10cSrcweir #include <vcl/window.hxx>
38*cdf0e10cSrcweir #ifndef _SV_CVTSVM_HXX
39*cdf0e10cSrcweir #include <vcl/cvtsvm.hxx>
40*cdf0e10cSrcweir #endif
41*cdf0e10cSrcweir #include <vcl/virdev.hxx>
42*cdf0e10cSrcweir #include <vcl/gdimtf.hxx>
43*cdf0e10cSrcweir #include <vcl/graphictools.hxx>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir // -----------
46*cdf0e10cSrcweir // - Defines -
47*cdf0e10cSrcweir // -----------
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #define GAMMA( _def_cVal, _def_InvGamma )	((sal_uInt8)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L))
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir // --------------------------
52*cdf0e10cSrcweir // - Color exchange structs -
53*cdf0e10cSrcweir // --------------------------
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir struct ImplColAdjustParam
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir 	sal_uInt8*	pMapR;
58*cdf0e10cSrcweir 	sal_uInt8*	pMapG;
59*cdf0e10cSrcweir 	sal_uInt8*	pMapB;
60*cdf0e10cSrcweir };
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir struct ImplBmpAdjustParam
63*cdf0e10cSrcweir {
64*cdf0e10cSrcweir 	short	nLuminancePercent;
65*cdf0e10cSrcweir 	short	nContrastPercent;
66*cdf0e10cSrcweir 	short	nChannelRPercent;
67*cdf0e10cSrcweir 	short	nChannelGPercent;
68*cdf0e10cSrcweir 	short	nChannelBPercent;
69*cdf0e10cSrcweir 	double	fGamma;
70*cdf0e10cSrcweir 	sal_Bool	bInvert;
71*cdf0e10cSrcweir };
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir // -----------------------------------------------------------------------------
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir struct ImplColConvertParam
76*cdf0e10cSrcweir {
77*cdf0e10cSrcweir 	MtfConversion	eConversion;
78*cdf0e10cSrcweir };
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir struct ImplBmpConvertParam
81*cdf0e10cSrcweir {
82*cdf0e10cSrcweir 	BmpConversion	eConversion;
83*cdf0e10cSrcweir };
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir // -----------------------------------------------------------------------------
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir struct ImplColMonoParam
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir 	Color aColor;
90*cdf0e10cSrcweir };
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir struct ImplBmpMonoParam
93*cdf0e10cSrcweir {
94*cdf0e10cSrcweir 	Color aColor;
95*cdf0e10cSrcweir };
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir // -----------------------------------------------------------------------------
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir struct ImplColReplaceParam
100*cdf0e10cSrcweir {
101*cdf0e10cSrcweir 	sal_uLong*			pMinR;
102*cdf0e10cSrcweir 	sal_uLong*			pMaxR;
103*cdf0e10cSrcweir 	sal_uLong*			pMinG;
104*cdf0e10cSrcweir 	sal_uLong*			pMaxG;
105*cdf0e10cSrcweir 	sal_uLong*			pMinB;
106*cdf0e10cSrcweir 	sal_uLong*			pMaxB;
107*cdf0e10cSrcweir 	const Color*	pDstCols;
108*cdf0e10cSrcweir 	sal_uLong			nCount;
109*cdf0e10cSrcweir };
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir struct ImplBmpReplaceParam
112*cdf0e10cSrcweir {
113*cdf0e10cSrcweir 	const Color*	pSrcCols;
114*cdf0e10cSrcweir 	const Color*	pDstCols;
115*cdf0e10cSrcweir 	sal_uLong			nCount;
116*cdf0e10cSrcweir 	const sal_uLong*	pTols;
117*cdf0e10cSrcweir };
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir // ---------
121*cdf0e10cSrcweir // - Label -
122*cdf0e10cSrcweir // ---------
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir struct ImpLabel
125*cdf0e10cSrcweir {
126*cdf0e10cSrcweir 	String	aLabelName;
127*cdf0e10cSrcweir 	sal_uLong	nActionPos;
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir 			ImpLabel( const String& rLabelName, sal_uLong _nActionPos ) :
130*cdf0e10cSrcweir 				aLabelName( rLabelName ),
131*cdf0e10cSrcweir 				nActionPos( _nActionPos ) {}
132*cdf0e10cSrcweir };
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir // -------------
135*cdf0e10cSrcweir // - LabelList -
136*cdf0e10cSrcweir // -------------
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir class ImpLabelList : private List
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir public:
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 				ImpLabelList() : List( 8, 4, 4 ) {}
143*cdf0e10cSrcweir 				ImpLabelList( const ImpLabelList& rList );
144*cdf0e10cSrcweir 				~ImpLabelList();
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir 	void		ImplInsert( ImpLabel* p ) { Insert( p, LIST_APPEND ); }
147*cdf0e10cSrcweir 	ImpLabel*	ImplRemove( sal_uLong nPos ) { return (ImpLabel*) Remove( nPos ); }
148*cdf0e10cSrcweir 	void		ImplReplace( ImpLabel* p ) { Replace( (void*)p ); }
149*cdf0e10cSrcweir 	ImpLabel*	ImplFirst() { return (ImpLabel*) First(); }
150*cdf0e10cSrcweir 	ImpLabel*	ImplNext() { return (ImpLabel*) Next(); }
151*cdf0e10cSrcweir 	ImpLabel*	ImplGetLabel( sal_uLong nPos ) const { return (ImpLabel*) GetObject( nPos ); }
152*cdf0e10cSrcweir 	sal_uLong		ImplGetLabelPos( const String& rLabelName );
153*cdf0e10cSrcweir 	sal_uLong		ImplCount() const { return Count(); }
154*cdf0e10cSrcweir };
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir // ------------------------------------------------------------------------
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir ImpLabelList::ImpLabelList( const ImpLabelList& rList ) :
159*cdf0e10cSrcweir 		List( rList )
160*cdf0e10cSrcweir {
161*cdf0e10cSrcweir 	for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() )
162*cdf0e10cSrcweir 		ImplReplace( new ImpLabel( *pLabel ) );
163*cdf0e10cSrcweir }
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir // ------------------------------------------------------------------------
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir ImpLabelList::~ImpLabelList()
168*cdf0e10cSrcweir {
169*cdf0e10cSrcweir 	for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() )
170*cdf0e10cSrcweir 		delete pLabel;
171*cdf0e10cSrcweir }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir // ------------------------------------------------------------------------
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir sal_uLong ImpLabelList::ImplGetLabelPos( const String& rLabelName )
176*cdf0e10cSrcweir {
177*cdf0e10cSrcweir 	sal_uLong nLabelPos = METAFILE_LABEL_NOTFOUND;
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 	for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() )
180*cdf0e10cSrcweir 	{
181*cdf0e10cSrcweir 		if ( rLabelName == pLabel->aLabelName )
182*cdf0e10cSrcweir 		{
183*cdf0e10cSrcweir 			nLabelPos = GetCurPos();
184*cdf0e10cSrcweir 			break;
185*cdf0e10cSrcweir 		}
186*cdf0e10cSrcweir 	}
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 	return nLabelPos;
189*cdf0e10cSrcweir }
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir // ---------------
192*cdf0e10cSrcweir // - GDIMetaFile -
193*cdf0e10cSrcweir // ---------------
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir GDIMetaFile::GDIMetaFile() :
196*cdf0e10cSrcweir 	List		( 0x3EFF, 64, 64 ),
197*cdf0e10cSrcweir 	aPrefSize	( 1, 1 ),
198*cdf0e10cSrcweir 	pPrev		( NULL ),
199*cdf0e10cSrcweir 	pNext		( NULL ),
200*cdf0e10cSrcweir 	pOutDev 	( NULL ),
201*cdf0e10cSrcweir 	pLabelList	( NULL ),
202*cdf0e10cSrcweir 	bPause		( sal_False ),
203*cdf0e10cSrcweir 	bRecord 	( sal_False )
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir }
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir // ------------------------------------------------------------------------
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir GDIMetaFile::GDIMetaFile( const GDIMetaFile& rMtf ) :
210*cdf0e10cSrcweir 	List			( rMtf ),
211*cdf0e10cSrcweir 	aPrefMapMode	( rMtf.aPrefMapMode ),
212*cdf0e10cSrcweir 	aPrefSize		( rMtf.aPrefSize ),
213*cdf0e10cSrcweir 	aHookHdlLink	( rMtf.aHookHdlLink ),
214*cdf0e10cSrcweir 	pPrev			( rMtf.pPrev ),
215*cdf0e10cSrcweir 	pNext			( rMtf.pNext ),
216*cdf0e10cSrcweir 	pOutDev 		( NULL ),
217*cdf0e10cSrcweir 	bPause			( sal_False ),
218*cdf0e10cSrcweir 	bRecord 		( sal_False )
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir 	// RefCount der MetaActions erhoehen
221*cdf0e10cSrcweir 	for( void* pAct = First(); pAct; pAct = Next() )
222*cdf0e10cSrcweir 		( (MetaAction*) pAct )->Duplicate();
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir 	if( rMtf.pLabelList )
225*cdf0e10cSrcweir 		pLabelList = new ImpLabelList( *rMtf.pLabelList );
226*cdf0e10cSrcweir 	else
227*cdf0e10cSrcweir 		pLabelList = NULL;
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 	if( rMtf.bRecord )
230*cdf0e10cSrcweir 	{
231*cdf0e10cSrcweir 		Record( rMtf.pOutDev );
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 		if ( rMtf.bPause )
234*cdf0e10cSrcweir 			Pause( sal_True );
235*cdf0e10cSrcweir 	}
236*cdf0e10cSrcweir }
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir // ------------------------------------------------------------------------
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir GDIMetaFile::~GDIMetaFile()
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir 	Clear();
243*cdf0e10cSrcweir }
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir // ------------------------------------------------------------------------
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir GDIMetaFile& GDIMetaFile::operator=( const GDIMetaFile& rMtf )
248*cdf0e10cSrcweir {
249*cdf0e10cSrcweir 	if( this != &rMtf )
250*cdf0e10cSrcweir 	{
251*cdf0e10cSrcweir 		Clear();
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir 		List::operator=( rMtf );
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 		// RefCount der MetaActions erhoehen
256*cdf0e10cSrcweir 		for( void* pAct = First(); pAct; pAct = Next() )
257*cdf0e10cSrcweir 			( (MetaAction*) pAct )->Duplicate();
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir 		if( rMtf.pLabelList )
260*cdf0e10cSrcweir 			pLabelList = new ImpLabelList( *rMtf.pLabelList );
261*cdf0e10cSrcweir 		else
262*cdf0e10cSrcweir 		   pLabelList = NULL;
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 		aPrefMapMode = rMtf.aPrefMapMode;
265*cdf0e10cSrcweir 		aPrefSize = rMtf.aPrefSize;
266*cdf0e10cSrcweir 		aHookHdlLink = rMtf.aHookHdlLink;
267*cdf0e10cSrcweir 		pPrev = rMtf.pPrev;
268*cdf0e10cSrcweir 		pNext = rMtf.pNext;
269*cdf0e10cSrcweir 		pOutDev = NULL;
270*cdf0e10cSrcweir 		bPause = sal_False;
271*cdf0e10cSrcweir 		bRecord = sal_False;
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 		if( rMtf.bRecord )
274*cdf0e10cSrcweir 		{
275*cdf0e10cSrcweir 			Record( rMtf.pOutDev );
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 			if( rMtf.bPause )
278*cdf0e10cSrcweir 				Pause( sal_True );
279*cdf0e10cSrcweir 		}
280*cdf0e10cSrcweir 	}
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir 	return *this;
283*cdf0e10cSrcweir }
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir // ------------------------------------------------------------------------
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir sal_Bool GDIMetaFile::operator==( const GDIMetaFile& rMtf ) const
288*cdf0e10cSrcweir {
289*cdf0e10cSrcweir 	const sal_uLong nObjCount = Count();
290*cdf0e10cSrcweir 	sal_Bool		bRet = sal_False;
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir 	if( this == &rMtf )
293*cdf0e10cSrcweir 		bRet = sal_True;
294*cdf0e10cSrcweir 	else if( rMtf.GetActionCount() == nObjCount &&
295*cdf0e10cSrcweir 			 rMtf.GetPrefSize() == aPrefSize &&
296*cdf0e10cSrcweir 			 rMtf.GetPrefMapMode() == aPrefMapMode )
297*cdf0e10cSrcweir 	{
298*cdf0e10cSrcweir 		bRet = sal_True;
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir 		for( sal_uLong n = 0UL; n < nObjCount; n++ )
301*cdf0e10cSrcweir 		{
302*cdf0e10cSrcweir 			if( GetObject( n ) != rMtf.GetObject( n ) )
303*cdf0e10cSrcweir 			{
304*cdf0e10cSrcweir 				bRet = sal_False;
305*cdf0e10cSrcweir 				break;
306*cdf0e10cSrcweir 			}
307*cdf0e10cSrcweir 		}
308*cdf0e10cSrcweir 	}
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir 	return bRet;
311*cdf0e10cSrcweir }
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir // ------------------------------------------------------------------------
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir sal_Bool GDIMetaFile::IsEqual( const GDIMetaFile& rMtf ) const
316*cdf0e10cSrcweir {
317*cdf0e10cSrcweir 	const sal_uLong nObjCount = Count();
318*cdf0e10cSrcweir 	sal_Bool		bRet = sal_False;
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir 	if( this == &rMtf )
321*cdf0e10cSrcweir 		bRet = sal_True;
322*cdf0e10cSrcweir 	else if( rMtf.GetActionCount() == nObjCount &&
323*cdf0e10cSrcweir 			 rMtf.GetPrefSize() == aPrefSize &&
324*cdf0e10cSrcweir 			 rMtf.GetPrefMapMode() == aPrefMapMode )
325*cdf0e10cSrcweir 	{
326*cdf0e10cSrcweir 		bRet = sal_True;
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir 		for( sal_uLong n = 0UL; n < nObjCount; n++ )
329*cdf0e10cSrcweir 		{
330*cdf0e10cSrcweir 			if(!((MetaAction*)GetObject( n ))->IsEqual(*((MetaAction*)rMtf.GetObject( n ))))
331*cdf0e10cSrcweir 			{
332*cdf0e10cSrcweir 				bRet = sal_False;
333*cdf0e10cSrcweir 				break;
334*cdf0e10cSrcweir 			}
335*cdf0e10cSrcweir 		}
336*cdf0e10cSrcweir 	}
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir 	return bRet;
339*cdf0e10cSrcweir }
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir // ------------------------------------------------------------------------
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir void GDIMetaFile::Clear()
344*cdf0e10cSrcweir {
345*cdf0e10cSrcweir 	if( bRecord )
346*cdf0e10cSrcweir 		Stop();
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir 	for( void* pAct = First(); pAct; pAct = Next() )
349*cdf0e10cSrcweir 		( (MetaAction*) pAct )->Delete();
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir 	List::Clear();
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir 	delete pLabelList;
354*cdf0e10cSrcweir 	pLabelList = NULL;
355*cdf0e10cSrcweir }
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir // ------------------------------------------------------------------------
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir void GDIMetaFile::Linker( OutputDevice* pOut, sal_Bool bLink )
360*cdf0e10cSrcweir {
361*cdf0e10cSrcweir 	if( bLink )
362*cdf0e10cSrcweir 	{
363*cdf0e10cSrcweir 		pNext = NULL;
364*cdf0e10cSrcweir 		pPrev = pOut->GetConnectMetaFile();
365*cdf0e10cSrcweir 		pOut->SetConnectMetaFile( this );
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir 		if( pPrev )
368*cdf0e10cSrcweir 			pPrev->pNext = this;
369*cdf0e10cSrcweir 	}
370*cdf0e10cSrcweir 	else
371*cdf0e10cSrcweir 	{
372*cdf0e10cSrcweir 		if( pNext )
373*cdf0e10cSrcweir 		{
374*cdf0e10cSrcweir 			pNext->pPrev = pPrev;
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 			if( pPrev )
377*cdf0e10cSrcweir 				pPrev->pNext = pNext;
378*cdf0e10cSrcweir 		}
379*cdf0e10cSrcweir 		else
380*cdf0e10cSrcweir 		{
381*cdf0e10cSrcweir 			if( pPrev )
382*cdf0e10cSrcweir 				pPrev->pNext = NULL;
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir 			pOut->SetConnectMetaFile( pPrev );
385*cdf0e10cSrcweir 		}
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir 		pPrev = NULL;
388*cdf0e10cSrcweir 		pNext = NULL;
389*cdf0e10cSrcweir 	}
390*cdf0e10cSrcweir }
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir // ------------------------------------------------------------------------
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir long GDIMetaFile::Hook()
395*cdf0e10cSrcweir {
396*cdf0e10cSrcweir 	return aHookHdlLink.Call( this );
397*cdf0e10cSrcweir }
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir // ------------------------------------------------------------------------
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir void GDIMetaFile::Record( OutputDevice* pOut )
402*cdf0e10cSrcweir {
403*cdf0e10cSrcweir 	if( bRecord )
404*cdf0e10cSrcweir 		Stop();
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 	Last();
407*cdf0e10cSrcweir 	pOutDev = pOut;
408*cdf0e10cSrcweir 	bRecord = sal_True;
409*cdf0e10cSrcweir 	Linker( pOut, sal_True );
410*cdf0e10cSrcweir }
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir // ------------------------------------------------------------------------
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir void GDIMetaFile::Play( GDIMetaFile& rMtf, sal_uLong nPos )
415*cdf0e10cSrcweir {
416*cdf0e10cSrcweir 	if ( !bRecord && !rMtf.bRecord )
417*cdf0e10cSrcweir 	{
418*cdf0e10cSrcweir 		MetaAction* pAction = GetCurAction();
419*cdf0e10cSrcweir 		const sal_uLong nObjCount = Count();
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir 		if( nPos > nObjCount )
422*cdf0e10cSrcweir 			nPos = nObjCount;
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 		for( sal_uLong nCurPos = GetCurPos(); nCurPos < nPos; nCurPos++ )
425*cdf0e10cSrcweir 		{
426*cdf0e10cSrcweir 			if( !Hook() )
427*cdf0e10cSrcweir 			{
428*cdf0e10cSrcweir 				pAction->Duplicate();
429*cdf0e10cSrcweir 				rMtf.AddAction( pAction );
430*cdf0e10cSrcweir 			}
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir 			pAction = (MetaAction*) Next();
433*cdf0e10cSrcweir 		}
434*cdf0e10cSrcweir 	}
435*cdf0e10cSrcweir }
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir // ------------------------------------------------------------------------
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir void GDIMetaFile::Play( OutputDevice* pOut, sal_uLong nPos )
440*cdf0e10cSrcweir {
441*cdf0e10cSrcweir 	if( !bRecord )
442*cdf0e10cSrcweir 	{
443*cdf0e10cSrcweir 		MetaAction* pAction = GetCurAction();
444*cdf0e10cSrcweir 		const sal_uLong nObjCount = Count();
445*cdf0e10cSrcweir 		sal_uLong		i  = 0, nSyncCount = ( pOut->GetOutDevType() == OUTDEV_WINDOW ) ? 0x000000ff : 0xffffffff;
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir         if( nPos > nObjCount )
448*cdf0e10cSrcweir 			nPos = nObjCount;
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir         // #i23407# Set backwards-compatible text language and layout mode
451*cdf0e10cSrcweir         // This is necessary, since old metafiles don't even know of these
452*cdf0e10cSrcweir 		// recent add-ons. Newer metafiles must of course explicitely set
453*cdf0e10cSrcweir         // those states.
454*cdf0e10cSrcweir         pOut->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
455*cdf0e10cSrcweir         pOut->SetLayoutMode( 0 );
456*cdf0e10cSrcweir         pOut->SetDigitLanguage( 0 );
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir 		for( sal_uLong nCurPos = GetCurPos(); nCurPos < nPos; nCurPos++ )
459*cdf0e10cSrcweir 		{
460*cdf0e10cSrcweir 			if( !Hook() )
461*cdf0e10cSrcweir 			{
462*cdf0e10cSrcweir 				pAction->Execute( pOut );
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir 				// flush output from time to time
465*cdf0e10cSrcweir 				if( i++ > nSyncCount )
466*cdf0e10cSrcweir 					( (Window*) pOut )->Flush(), i = 0;
467*cdf0e10cSrcweir 			}
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir 			pAction = (MetaAction*) Next();
470*cdf0e10cSrcweir 		}
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir         pOut->Pop();
473*cdf0e10cSrcweir 	}
474*cdf0e10cSrcweir }
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir // ------------------------------------------------------------------------
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos,
479*cdf0e10cSrcweir 						const Size& rSize, sal_uLong nPos )
480*cdf0e10cSrcweir {
481*cdf0e10cSrcweir 	Region	aDrawClipRegion;
482*cdf0e10cSrcweir 	MapMode aDrawMap( GetPrefMapMode() );
483*cdf0e10cSrcweir 	Size	aDestSize( pOut->LogicToPixel( rSize ) );
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir 	if( aDestSize.Width() && aDestSize.Height() )
486*cdf0e10cSrcweir 	{
487*cdf0e10cSrcweir 		Size			aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) );
488*cdf0e10cSrcweir 		GDIMetaFile*	pMtf = pOut->GetConnectMetaFile();
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir 		if( !aTmpPrefSize.Width() )
491*cdf0e10cSrcweir 			aTmpPrefSize.Width() = aDestSize.Width();
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir 		if( !aTmpPrefSize.Height() )
494*cdf0e10cSrcweir 			aTmpPrefSize.Height() = aDestSize.Height();
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir 		Fraction aScaleX( aDestSize.Width(), aTmpPrefSize.Width() );
497*cdf0e10cSrcweir 		Fraction aScaleY( aDestSize.Height(), aTmpPrefSize.Height() );
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir 		aScaleX *= aDrawMap.GetScaleX(); aDrawMap.SetScaleX( aScaleX );
500*cdf0e10cSrcweir 		aScaleY *= aDrawMap.GetScaleY(); aDrawMap.SetScaleY( aScaleY );
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir         // #i47260# Convert logical output position to offset within
503*cdf0e10cSrcweir         // the metafile's mapmode. Therefore, disable pixel offset on
504*cdf0e10cSrcweir         // outdev, it's inverse mnOutOffLogicX/Y is calculated for a
505*cdf0e10cSrcweir         // different mapmode (the one currently set on pOut, that is)
506*cdf0e10cSrcweir         // - thus, aDrawMap's origin would generally be wrong. And
507*cdf0e10cSrcweir         // even _if_ aDrawMap is similar to pOutDev's current mapmode,
508*cdf0e10cSrcweir         // it's _still_ undesirable to have pixel offset unequal zero,
509*cdf0e10cSrcweir         // because one would still get round-off errors (the
510*cdf0e10cSrcweir         // round-trip error for LogicToPixel( PixelToLogic() ) was the
511*cdf0e10cSrcweir         // reason for having pixel offset in the first place).
512*cdf0e10cSrcweir         const Size& rOldOffset( pOut->GetPixelOffset() );
513*cdf0e10cSrcweir         const Size  aEmptySize;
514*cdf0e10cSrcweir         pOut->SetPixelOffset( aEmptySize );
515*cdf0e10cSrcweir 		aDrawMap.SetOrigin( pOut->PixelToLogic( pOut->LogicToPixel( rPos ), aDrawMap ) );
516*cdf0e10cSrcweir         pOut->SetPixelOffset( rOldOffset );
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir 		pOut->Push();
519*cdf0e10cSrcweir 
520*cdf0e10cSrcweir 		if ( pMtf && pMtf->IsRecord() && ( pOut->GetOutDevType() != OUTDEV_PRINTER ) )
521*cdf0e10cSrcweir 			pOut->SetRelativeMapMode( aDrawMap );
522*cdf0e10cSrcweir 		else
523*cdf0e10cSrcweir 			pOut->SetMapMode( aDrawMap );
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir         // #i23407# Set backwards-compatible text language and layout mode
526*cdf0e10cSrcweir         // This is necessary, since old metafiles don't even know of these
527*cdf0e10cSrcweir 		// recent add-ons. Newer metafiles must of course explicitely set
528*cdf0e10cSrcweir         // those states.
529*cdf0e10cSrcweir         pOut->SetLayoutMode( 0 );
530*cdf0e10cSrcweir         pOut->SetDigitLanguage( 0 );
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir 		Play( pOut, nPos );
533*cdf0e10cSrcweir 
534*cdf0e10cSrcweir 		pOut->Pop();
535*cdf0e10cSrcweir 	}
536*cdf0e10cSrcweir }
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir // ------------------------------------------------------------------------
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir void GDIMetaFile::Pause( sal_Bool _bPause )
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir 	if( bRecord )
543*cdf0e10cSrcweir 	{
544*cdf0e10cSrcweir 		if( _bPause )
545*cdf0e10cSrcweir 		{
546*cdf0e10cSrcweir 			if( !bPause )
547*cdf0e10cSrcweir 				Linker( pOutDev, sal_False );
548*cdf0e10cSrcweir 		}
549*cdf0e10cSrcweir 		else
550*cdf0e10cSrcweir 		{
551*cdf0e10cSrcweir 			if( bPause )
552*cdf0e10cSrcweir 				Linker( pOutDev, sal_True );
553*cdf0e10cSrcweir 		}
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir 		bPause = _bPause;
556*cdf0e10cSrcweir 	}
557*cdf0e10cSrcweir }
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir // ------------------------------------------------------------------------
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir void GDIMetaFile::Stop()
562*cdf0e10cSrcweir {
563*cdf0e10cSrcweir 	if( bRecord )
564*cdf0e10cSrcweir 	{
565*cdf0e10cSrcweir 		bRecord = sal_False;
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir 		if( !bPause )
568*cdf0e10cSrcweir 			Linker( pOutDev, sal_False );
569*cdf0e10cSrcweir 		else
570*cdf0e10cSrcweir 			bPause = sal_False;
571*cdf0e10cSrcweir 	}
572*cdf0e10cSrcweir }
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir // ------------------------------------------------------------------------
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir void GDIMetaFile::WindStart()
577*cdf0e10cSrcweir {
578*cdf0e10cSrcweir 	if( !bRecord )
579*cdf0e10cSrcweir 		First();
580*cdf0e10cSrcweir }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir // ------------------------------------------------------------------------
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir void GDIMetaFile::WindEnd()
585*cdf0e10cSrcweir {
586*cdf0e10cSrcweir 	if( !bRecord )
587*cdf0e10cSrcweir 		Last();
588*cdf0e10cSrcweir }
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir // ------------------------------------------------------------------------
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir void GDIMetaFile::Wind( sal_uLong nActionPos )
593*cdf0e10cSrcweir {
594*cdf0e10cSrcweir 	if( !bRecord )
595*cdf0e10cSrcweir 		Seek( nActionPos );
596*cdf0e10cSrcweir }
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir // ------------------------------------------------------------------------
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir void GDIMetaFile::WindPrev()
601*cdf0e10cSrcweir {
602*cdf0e10cSrcweir 	if( !bRecord )
603*cdf0e10cSrcweir 		Prev();
604*cdf0e10cSrcweir }
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir // ------------------------------------------------------------------------
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir void GDIMetaFile::WindNext()
609*cdf0e10cSrcweir {
610*cdf0e10cSrcweir 	if( !bRecord )
611*cdf0e10cSrcweir 		Next();
612*cdf0e10cSrcweir }
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir // ------------------------------------------------------------------------
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir void GDIMetaFile::AddAction( MetaAction* pAction )
617*cdf0e10cSrcweir {
618*cdf0e10cSrcweir 	Insert( pAction, LIST_APPEND );
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir 	if( pPrev )
621*cdf0e10cSrcweir 	{
622*cdf0e10cSrcweir 		pAction->Duplicate();
623*cdf0e10cSrcweir 		pPrev->AddAction( pAction );
624*cdf0e10cSrcweir 	}
625*cdf0e10cSrcweir }
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir // ------------------------------------------------------------------------
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir void GDIMetaFile::AddAction( MetaAction* pAction, sal_uLong nPos )
630*cdf0e10cSrcweir {
631*cdf0e10cSrcweir 	Insert( pAction, nPos );
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir 	if( pPrev )
634*cdf0e10cSrcweir 	{
635*cdf0e10cSrcweir 		pAction->Duplicate();
636*cdf0e10cSrcweir 		pPrev->AddAction( pAction, nPos );
637*cdf0e10cSrcweir 	}
638*cdf0e10cSrcweir }
639*cdf0e10cSrcweir 
640*cdf0e10cSrcweir // ------------------------------------------------------------------------
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir // @since #110496#
643*cdf0e10cSrcweir void GDIMetaFile::RemoveAction( sal_uLong nPos )
644*cdf0e10cSrcweir {
645*cdf0e10cSrcweir 	Remove( nPos );
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir 	if( pPrev )
648*cdf0e10cSrcweir 		pPrev->RemoveAction( nPos );
649*cdf0e10cSrcweir }
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir // ------------------------------------------------------------------------
652*cdf0e10cSrcweir 
653*cdf0e10cSrcweir MetaAction* GDIMetaFile::CopyAction( sal_uLong nPos ) const
654*cdf0e10cSrcweir {
655*cdf0e10cSrcweir 	return ( (MetaAction*) GetObject( nPos ) )->Clone();
656*cdf0e10cSrcweir }
657*cdf0e10cSrcweir 
658*cdf0e10cSrcweir // ------------------------------------------------------------------------
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetActionPos( const String& rLabel )
661*cdf0e10cSrcweir {
662*cdf0e10cSrcweir 	ImpLabel* pLabel = NULL;
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir 	if( pLabelList )
665*cdf0e10cSrcweir 		pLabel = pLabelList->ImplGetLabel( pLabelList->ImplGetLabelPos( rLabel ) );
666*cdf0e10cSrcweir 	else
667*cdf0e10cSrcweir 		pLabel = NULL;
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir 	return( pLabel ? pLabel->nActionPos : METAFILE_LABEL_NOTFOUND );
670*cdf0e10cSrcweir }
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir // ------------------------------------------------------------------------
673*cdf0e10cSrcweir 
674*cdf0e10cSrcweir sal_Bool GDIMetaFile::InsertLabel( const String& rLabel, sal_uLong nActionPos )
675*cdf0e10cSrcweir {
676*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir 	if( !pLabelList )
679*cdf0e10cSrcweir 		pLabelList = new ImpLabelList;
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir 	if( pLabelList->ImplGetLabelPos( rLabel ) == METAFILE_LABEL_NOTFOUND )
682*cdf0e10cSrcweir 	{
683*cdf0e10cSrcweir 		pLabelList->ImplInsert( new ImpLabel( rLabel, nActionPos ) );
684*cdf0e10cSrcweir 		bRet = sal_True;
685*cdf0e10cSrcweir 	}
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir 	return bRet;
688*cdf0e10cSrcweir }
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir // ------------------------------------------------------------------------
691*cdf0e10cSrcweir 
692*cdf0e10cSrcweir void GDIMetaFile::RemoveLabel( const String& rLabel )
693*cdf0e10cSrcweir {
694*cdf0e10cSrcweir 	if( pLabelList )
695*cdf0e10cSrcweir 	{
696*cdf0e10cSrcweir 		const sal_uLong nLabelPos = pLabelList->ImplGetLabelPos( rLabel );
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir 		if( nLabelPos != METAFILE_LABEL_NOTFOUND )
699*cdf0e10cSrcweir 			delete pLabelList->ImplRemove( nLabelPos );
700*cdf0e10cSrcweir 	}
701*cdf0e10cSrcweir }
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir // ------------------------------------------------------------------------
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir void GDIMetaFile::RenameLabel( const String& rLabel, const String& rNewLabel )
706*cdf0e10cSrcweir {
707*cdf0e10cSrcweir 	if( pLabelList )
708*cdf0e10cSrcweir 	{
709*cdf0e10cSrcweir 		const sal_uLong nLabelPos = pLabelList->ImplGetLabelPos( rLabel );
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir 		if ( nLabelPos != METAFILE_LABEL_NOTFOUND )
712*cdf0e10cSrcweir 			pLabelList->ImplGetLabel( nLabelPos )->aLabelName = rNewLabel;
713*cdf0e10cSrcweir 	}
714*cdf0e10cSrcweir }
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir // ------------------------------------------------------------------------
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetLabelCount() const
719*cdf0e10cSrcweir {
720*cdf0e10cSrcweir 	return( pLabelList ? pLabelList->ImplCount() : 0UL );
721*cdf0e10cSrcweir }
722*cdf0e10cSrcweir 
723*cdf0e10cSrcweir // ------------------------------------------------------------------------
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir String GDIMetaFile::GetLabel( sal_uLong nLabel )
726*cdf0e10cSrcweir {
727*cdf0e10cSrcweir 	String aString;
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir 	if( pLabelList )
730*cdf0e10cSrcweir 	{
731*cdf0e10cSrcweir 		const ImpLabel* pLabel = pLabelList->ImplGetLabel( nLabel );
732*cdf0e10cSrcweir 
733*cdf0e10cSrcweir 		if( pLabel )
734*cdf0e10cSrcweir 			aString = pLabel->aLabelName;
735*cdf0e10cSrcweir 	}
736*cdf0e10cSrcweir 
737*cdf0e10cSrcweir 	return aString;
738*cdf0e10cSrcweir }
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir // ------------------------------------------------------------------------
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir sal_Bool GDIMetaFile::SaveStatus()
743*cdf0e10cSrcweir {
744*cdf0e10cSrcweir 	if ( bRecord )
745*cdf0e10cSrcweir 	{
746*cdf0e10cSrcweir 		if ( bPause )
747*cdf0e10cSrcweir 			Linker( pOutDev, sal_True );
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir 		AddAction( new MetaLineColorAction( pOutDev->GetLineColor(),
750*cdf0e10cSrcweir 											pOutDev->IsLineColor() ) );
751*cdf0e10cSrcweir 		AddAction( new MetaFillColorAction( pOutDev->GetFillColor(),
752*cdf0e10cSrcweir 											pOutDev->IsFillColor() ) );
753*cdf0e10cSrcweir 		AddAction( new MetaFontAction( pOutDev->GetFont() ) );
754*cdf0e10cSrcweir 		AddAction( new MetaTextColorAction( pOutDev->GetTextColor() ) );
755*cdf0e10cSrcweir 		AddAction( new MetaTextFillColorAction( pOutDev->GetTextFillColor(),
756*cdf0e10cSrcweir 												pOutDev->IsTextFillColor() ) );
757*cdf0e10cSrcweir 		AddAction( new MetaTextLineColorAction( pOutDev->GetTextLineColor(),
758*cdf0e10cSrcweir 												pOutDev->IsTextLineColor() ) );
759*cdf0e10cSrcweir 		AddAction( new MetaOverlineColorAction( pOutDev->GetOverlineColor(),
760*cdf0e10cSrcweir 												pOutDev->IsOverlineColor() ) );
761*cdf0e10cSrcweir 		AddAction( new MetaTextAlignAction( pOutDev->GetTextAlign() ) );
762*cdf0e10cSrcweir 		AddAction( new MetaRasterOpAction( pOutDev->GetRasterOp() ) );
763*cdf0e10cSrcweir 		AddAction( new MetaMapModeAction( pOutDev->GetMapMode() ) );
764*cdf0e10cSrcweir 		AddAction( new MetaClipRegionAction( pOutDev->GetClipRegion(),
765*cdf0e10cSrcweir 											 pOutDev->IsClipRegion() ) );
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir 		if ( bPause )
768*cdf0e10cSrcweir 			Linker( pOutDev, sal_False );
769*cdf0e10cSrcweir 
770*cdf0e10cSrcweir 		return sal_True;
771*cdf0e10cSrcweir 	}
772*cdf0e10cSrcweir 	else
773*cdf0e10cSrcweir 		return sal_False;
774*cdf0e10cSrcweir }
775*cdf0e10cSrcweir 
776*cdf0e10cSrcweir // ------------------------------------------------------------------------
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir sal_Bool GDIMetaFile::Mirror( sal_uLong nMirrorFlags )
779*cdf0e10cSrcweir {
780*cdf0e10cSrcweir 	const Size	aOldPrefSize( GetPrefSize() );
781*cdf0e10cSrcweir 	long	    nMoveX, nMoveY;
782*cdf0e10cSrcweir 	double	    fScaleX, fScaleY;
783*cdf0e10cSrcweir     sal_Bool        bRet;
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir 	if( nMirrorFlags & MTF_MIRROR_HORZ )
786*cdf0e10cSrcweir 		nMoveX = VOS_ABS( aOldPrefSize.Width() ) - 1, fScaleX = -1.0;
787*cdf0e10cSrcweir 	else
788*cdf0e10cSrcweir 		nMoveX = 0, fScaleX = 1.0;
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir 	if( nMirrorFlags & MTF_MIRROR_VERT )
791*cdf0e10cSrcweir 		nMoveY = VOS_ABS( aOldPrefSize.Height() ) - 1, fScaleY = -1.0;
792*cdf0e10cSrcweir 	else
793*cdf0e10cSrcweir 		nMoveY = 0, fScaleY = 1.0;
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir     if( ( fScaleX != 1.0 ) || ( fScaleY != 1.0 ) )
796*cdf0e10cSrcweir     {
797*cdf0e10cSrcweir 	    Scale( fScaleX, fScaleY );
798*cdf0e10cSrcweir 	    Move( nMoveX, nMoveY );
799*cdf0e10cSrcweir 	    SetPrefSize( aOldPrefSize );
800*cdf0e10cSrcweir         bRet = sal_True;
801*cdf0e10cSrcweir     }
802*cdf0e10cSrcweir     else
803*cdf0e10cSrcweir         bRet = sal_False;
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir     return bRet;
806*cdf0e10cSrcweir }
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir // ------------------------------------------------------------------------
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir void GDIMetaFile::Move( long nX, long nY )
811*cdf0e10cSrcweir {
812*cdf0e10cSrcweir     const Size      aBaseOffset( nX, nY );
813*cdf0e10cSrcweir     Size            aOffset( aBaseOffset );
814*cdf0e10cSrcweir     VirtualDevice   aMapVDev;
815*cdf0e10cSrcweir 
816*cdf0e10cSrcweir     aMapVDev.EnableOutput( sal_False );
817*cdf0e10cSrcweir     aMapVDev.SetMapMode( GetPrefMapMode() );
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir 	for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() )
820*cdf0e10cSrcweir 	{
821*cdf0e10cSrcweir 		const long  nType = pAct->GetType();
822*cdf0e10cSrcweir         MetaAction* pModAct;
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir 		if( pAct->GetRefCount() > 1 )
825*cdf0e10cSrcweir 		{
826*cdf0e10cSrcweir 			Replace( pModAct = pAct->Clone(), GetCurPos() );
827*cdf0e10cSrcweir 			pAct->Delete();
828*cdf0e10cSrcweir 		}
829*cdf0e10cSrcweir 		else
830*cdf0e10cSrcweir 			pModAct = pAct;
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir         if( ( META_MAPMODE_ACTION == nType ) ||
833*cdf0e10cSrcweir             ( META_PUSH_ACTION == nType ) ||
834*cdf0e10cSrcweir             ( META_POP_ACTION == nType ) )
835*cdf0e10cSrcweir         {
836*cdf0e10cSrcweir             pModAct->Execute( &aMapVDev );
837*cdf0e10cSrcweir             aOffset = aMapVDev.LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev.GetMapMode() );
838*cdf0e10cSrcweir         }
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir 		pModAct->Move( aOffset.Width(), aOffset.Height() );
841*cdf0e10cSrcweir 	}
842*cdf0e10cSrcweir }
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir void GDIMetaFile::Move( long nX, long nY, long nDPIX, long nDPIY )
845*cdf0e10cSrcweir {
846*cdf0e10cSrcweir     const Size      aBaseOffset( nX, nY );
847*cdf0e10cSrcweir     Size            aOffset( aBaseOffset );
848*cdf0e10cSrcweir     VirtualDevice   aMapVDev;
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir     aMapVDev.EnableOutput( sal_False );
851*cdf0e10cSrcweir     aMapVDev.SetReferenceDevice( nDPIX, nDPIY );
852*cdf0e10cSrcweir     aMapVDev.SetMapMode( GetPrefMapMode() );
853*cdf0e10cSrcweir 
854*cdf0e10cSrcweir 	for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() )
855*cdf0e10cSrcweir 	{
856*cdf0e10cSrcweir 		const long  nType = pAct->GetType();
857*cdf0e10cSrcweir         MetaAction* pModAct;
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir 		if( pAct->GetRefCount() > 1 )
860*cdf0e10cSrcweir 		{
861*cdf0e10cSrcweir 			Replace( pModAct = pAct->Clone(), GetCurPos() );
862*cdf0e10cSrcweir 			pAct->Delete();
863*cdf0e10cSrcweir 		}
864*cdf0e10cSrcweir 		else
865*cdf0e10cSrcweir 			pModAct = pAct;
866*cdf0e10cSrcweir 
867*cdf0e10cSrcweir         if( ( META_MAPMODE_ACTION == nType ) ||
868*cdf0e10cSrcweir             ( META_PUSH_ACTION == nType ) ||
869*cdf0e10cSrcweir             ( META_POP_ACTION == nType ) )
870*cdf0e10cSrcweir         {
871*cdf0e10cSrcweir             pModAct->Execute( &aMapVDev );
872*cdf0e10cSrcweir             if( aMapVDev.GetMapMode().GetMapUnit() == MAP_PIXEL )
873*cdf0e10cSrcweir             {
874*cdf0e10cSrcweir                 aOffset = aMapVDev.LogicToPixel( aBaseOffset, GetPrefMapMode() );
875*cdf0e10cSrcweir                 MapMode aMap( aMapVDev.GetMapMode() );
876*cdf0e10cSrcweir                 aOffset.Width() = static_cast<long>(aOffset.Width() * (double)aMap.GetScaleX());
877*cdf0e10cSrcweir                 aOffset.Height() = static_cast<long>(aOffset.Height() * (double)aMap.GetScaleY());
878*cdf0e10cSrcweir             }
879*cdf0e10cSrcweir             else
880*cdf0e10cSrcweir                 aOffset = aMapVDev.LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev.GetMapMode() );
881*cdf0e10cSrcweir         }
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir 		pModAct->Move( aOffset.Width(), aOffset.Height() );
884*cdf0e10cSrcweir 	}
885*cdf0e10cSrcweir }
886*cdf0e10cSrcweir 
887*cdf0e10cSrcweir // ------------------------------------------------------------------------
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir void GDIMetaFile::Scale( double fScaleX, double fScaleY )
890*cdf0e10cSrcweir {
891*cdf0e10cSrcweir 	for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() )
892*cdf0e10cSrcweir 	{
893*cdf0e10cSrcweir 		MetaAction* pModAct;
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir 		if( pAct->GetRefCount() > 1 )
896*cdf0e10cSrcweir 		{
897*cdf0e10cSrcweir             Replace( pModAct = pAct->Clone(), GetCurPos() );
898*cdf0e10cSrcweir 			pAct->Delete();
899*cdf0e10cSrcweir 		}
900*cdf0e10cSrcweir 		else
901*cdf0e10cSrcweir 			pModAct = pAct;
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir 		pModAct->Scale( fScaleX, fScaleY );
904*cdf0e10cSrcweir 	}
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir 	aPrefSize.Width() = FRound( aPrefSize.Width() * fScaleX );
907*cdf0e10cSrcweir 	aPrefSize.Height() = FRound( aPrefSize.Height() * fScaleY );
908*cdf0e10cSrcweir }
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir // ------------------------------------------------------------------------
911*cdf0e10cSrcweir 
912*cdf0e10cSrcweir void GDIMetaFile::Scale( const Fraction& rScaleX, const Fraction& rScaleY )
913*cdf0e10cSrcweir {
914*cdf0e10cSrcweir 	Scale( (double) rScaleX, (double) rScaleY );
915*cdf0e10cSrcweir }
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir // ------------------------------------------------------------------------
918*cdf0e10cSrcweir 
919*cdf0e10cSrcweir void GDIMetaFile::Clip( const Rectangle& i_rClipRect )
920*cdf0e10cSrcweir {
921*cdf0e10cSrcweir     Rectangle aCurRect( i_rClipRect );
922*cdf0e10cSrcweir     VirtualDevice   aMapVDev;
923*cdf0e10cSrcweir 
924*cdf0e10cSrcweir     aMapVDev.EnableOutput( sal_False );
925*cdf0e10cSrcweir     aMapVDev.SetMapMode( GetPrefMapMode() );
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir     for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() )
928*cdf0e10cSrcweir     {
929*cdf0e10cSrcweir         const long  nType = pAct->GetType();
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir         if( ( META_MAPMODE_ACTION == nType ) ||
932*cdf0e10cSrcweir             ( META_PUSH_ACTION == nType ) ||
933*cdf0e10cSrcweir             ( META_POP_ACTION == nType ) )
934*cdf0e10cSrcweir         {
935*cdf0e10cSrcweir             pAct->Execute( &aMapVDev );
936*cdf0e10cSrcweir             aCurRect = aMapVDev.LogicToLogic( i_rClipRect, GetPrefMapMode(), aMapVDev.GetMapMode() );
937*cdf0e10cSrcweir         }
938*cdf0e10cSrcweir         else if( nType == META_CLIPREGION_ACTION )
939*cdf0e10cSrcweir         {
940*cdf0e10cSrcweir             MetaClipRegionAction* pOldAct = (MetaClipRegionAction*)pAct;
941*cdf0e10cSrcweir             Region aNewReg( aCurRect );
942*cdf0e10cSrcweir             if( pOldAct->IsClipping() )
943*cdf0e10cSrcweir                 aNewReg.Intersect( pOldAct->GetRegion() );
944*cdf0e10cSrcweir             MetaClipRegionAction* pNewAct = new MetaClipRegionAction( aNewReg, sal_True );
945*cdf0e10cSrcweir             Replace( pNewAct, GetCurPos() );
946*cdf0e10cSrcweir             pOldAct->Delete();
947*cdf0e10cSrcweir         }
948*cdf0e10cSrcweir     }
949*cdf0e10cSrcweir }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir // ------------------------------------------------------------------------
952*cdf0e10cSrcweir 
953*cdf0e10cSrcweir Point GDIMetaFile::ImplGetRotatedPoint( const Point& rPt, const Point& rRotatePt,
954*cdf0e10cSrcweir                                         const Size& rOffset, double fSin, double fCos )
955*cdf0e10cSrcweir {
956*cdf0e10cSrcweir     const long nX = rPt.X() - rRotatePt.X();
957*cdf0e10cSrcweir     const long nY = rPt.Y() - rRotatePt.Y();
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir     return Point( FRound( fCos * nX + fSin * nY ) + rRotatePt.X() + rOffset.Width(),
960*cdf0e10cSrcweir                   -FRound( fSin * nX - fCos * nY ) + rRotatePt.Y() + rOffset.Height() );
961*cdf0e10cSrcweir }
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir // ------------------------------------------------------------------------
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir Polygon GDIMetaFile::ImplGetRotatedPolygon( const Polygon& rPoly, const Point& rRotatePt,
966*cdf0e10cSrcweir                                             const Size& rOffset, double fSin, double fCos )
967*cdf0e10cSrcweir {
968*cdf0e10cSrcweir     Polygon aRet( rPoly );
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir     aRet.Rotate( rRotatePt, fSin, fCos );
971*cdf0e10cSrcweir     aRet.Move( rOffset.Width(), rOffset.Height() );
972*cdf0e10cSrcweir 
973*cdf0e10cSrcweir     return aRet;
974*cdf0e10cSrcweir }
975*cdf0e10cSrcweir 
976*cdf0e10cSrcweir // ------------------------------------------------------------------------
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir PolyPolygon GDIMetaFile::ImplGetRotatedPolyPolygon( const PolyPolygon& rPolyPoly, const Point& rRotatePt,
979*cdf0e10cSrcweir                                                     const Size& rOffset, double fSin, double fCos )
980*cdf0e10cSrcweir {
981*cdf0e10cSrcweir     PolyPolygon aRet( rPolyPoly );
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir     aRet.Rotate( rRotatePt, fSin, fCos );
984*cdf0e10cSrcweir     aRet.Move( rOffset.Width(), rOffset.Height() );
985*cdf0e10cSrcweir 
986*cdf0e10cSrcweir     return aRet;
987*cdf0e10cSrcweir }
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir // ------------------------------------------------------------------------
990*cdf0e10cSrcweir 
991*cdf0e10cSrcweir void GDIMetaFile::ImplAddGradientEx( GDIMetaFile& 		  rMtf,
992*cdf0e10cSrcweir                                      const OutputDevice&  rMapDev,
993*cdf0e10cSrcweir                                      const PolyPolygon&   rPolyPoly,
994*cdf0e10cSrcweir                                      const Gradient&	  rGrad 	)
995*cdf0e10cSrcweir {
996*cdf0e10cSrcweir     // #105055# Generate comment, GradientEx and Gradient actions
997*cdf0e10cSrcweir     // (within DrawGradient)
998*cdf0e10cSrcweir     VirtualDevice aVDev( rMapDev, 0 );
999*cdf0e10cSrcweir     aVDev.EnableOutput( sal_False );
1000*cdf0e10cSrcweir     GDIMetaFile	aGradMtf;
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir     aGradMtf.Record( &aVDev );
1003*cdf0e10cSrcweir     aVDev.DrawGradient( rPolyPoly, rGrad );
1004*cdf0e10cSrcweir     aGradMtf.Stop();
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir     int i, nAct( aGradMtf.GetActionCount() );
1007*cdf0e10cSrcweir     for( i=0; i<nAct; ++i )
1008*cdf0e10cSrcweir     {
1009*cdf0e10cSrcweir         MetaAction* pMetaAct = aGradMtf.GetAction(i);
1010*cdf0e10cSrcweir         pMetaAct->Duplicate();
1011*cdf0e10cSrcweir         rMtf.AddAction( pMetaAct );
1012*cdf0e10cSrcweir     }
1013*cdf0e10cSrcweir }
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir // ------------------------------------------------------------------------
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir void GDIMetaFile::Rotate( long nAngle10 )
1018*cdf0e10cSrcweir {
1019*cdf0e10cSrcweir 	nAngle10 %= 3600L;
1020*cdf0e10cSrcweir 	nAngle10 = ( nAngle10 < 0L ) ? ( 3599L + nAngle10 ) : nAngle10;
1021*cdf0e10cSrcweir 
1022*cdf0e10cSrcweir     if( nAngle10 )
1023*cdf0e10cSrcweir     {
1024*cdf0e10cSrcweir 	    GDIMetaFile     aMtf;
1025*cdf0e10cSrcweir         VirtualDevice   aMapVDev;
1026*cdf0e10cSrcweir 	    const double    fAngle = F_PI1800 * nAngle10;
1027*cdf0e10cSrcweir         const double    fSin = sin( fAngle );
1028*cdf0e10cSrcweir         const double    fCos = cos( fAngle );
1029*cdf0e10cSrcweir 		Rectangle		aRect=Rectangle( Point(), GetPrefSize() );
1030*cdf0e10cSrcweir         Polygon         aPoly( aRect );
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir         aPoly.Rotate( Point(), fSin, fCos );
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir         aMapVDev.EnableOutput( sal_False );
1035*cdf0e10cSrcweir         aMapVDev.SetMapMode( GetPrefMapMode() );
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir         const Rectangle aNewBound( aPoly.GetBoundRect() );
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir         const Point aOrigin( GetPrefMapMode().GetOrigin().X(), GetPrefMapMode().GetOrigin().Y() );
1040*cdf0e10cSrcweir         const Size  aOffset( -aNewBound.Left(), -aNewBound.Top() );
1041*cdf0e10cSrcweir 
1042*cdf0e10cSrcweir         Point     aRotAnchor( aOrigin );
1043*cdf0e10cSrcweir         Size      aRotOffset( aOffset );
1044*cdf0e10cSrcweir 
1045*cdf0e10cSrcweir 	    for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() )
1046*cdf0e10cSrcweir 	    {
1047*cdf0e10cSrcweir 		    const sal_uInt16 nActionType = pAction->GetType();
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir 		    switch( nActionType )
1050*cdf0e10cSrcweir 		    {
1051*cdf0e10cSrcweir 			    case( META_PIXEL_ACTION ):
1052*cdf0e10cSrcweir 			    {
1053*cdf0e10cSrcweir 				    MetaPixelAction* pAct = (MetaPixelAction*) pAction;
1054*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaPixelAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
1055*cdf0e10cSrcweir                                                                               pAct->GetColor() ) );
1056*cdf0e10cSrcweir 			    }
1057*cdf0e10cSrcweir 			    break;
1058*cdf0e10cSrcweir 
1059*cdf0e10cSrcweir 			    case( META_POINT_ACTION ):
1060*cdf0e10cSrcweir 			    {
1061*cdf0e10cSrcweir 				    MetaPointAction* pAct = (MetaPointAction*) pAction;
1062*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaPointAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
1063*cdf0e10cSrcweir 			    }
1064*cdf0e10cSrcweir 			    break;
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir                 case( META_LINE_ACTION ):
1067*cdf0e10cSrcweir                 {
1068*cdf0e10cSrcweir 				    MetaLineAction* pAct = (MetaLineAction*) pAction;
1069*cdf0e10cSrcweir                     aMtf.AddAction( new MetaLineAction( ImplGetRotatedPoint( pAct->GetStartPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
1070*cdf0e10cSrcweir                                                         ImplGetRotatedPoint( pAct->GetEndPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
1071*cdf0e10cSrcweir                                                         pAct->GetLineInfo() ) );
1072*cdf0e10cSrcweir                 }
1073*cdf0e10cSrcweir                 break;
1074*cdf0e10cSrcweir 
1075*cdf0e10cSrcweir                 case( META_RECT_ACTION ):
1076*cdf0e10cSrcweir                 {
1077*cdf0e10cSrcweir 				    MetaRectAction* pAct = (MetaRectAction*) pAction;
1078*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
1079*cdf0e10cSrcweir                 }
1080*cdf0e10cSrcweir                 break;
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir                 case( META_ROUNDRECT_ACTION ):
1083*cdf0e10cSrcweir                 {
1084*cdf0e10cSrcweir 				    MetaRoundRectAction*    pAct = (MetaRoundRectAction*) pAction;
1085*cdf0e10cSrcweir                     const Polygon           aRoundRectPoly( pAct->GetRect(), pAct->GetHorzRound(), pAct->GetVertRound() );
1086*cdf0e10cSrcweir 
1087*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aRoundRectPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
1088*cdf0e10cSrcweir                 }
1089*cdf0e10cSrcweir                 break;
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir                 case( META_ELLIPSE_ACTION ):
1092*cdf0e10cSrcweir                 {
1093*cdf0e10cSrcweir 				    MetaEllipseAction*      pAct = (MetaEllipseAction*) pAction;
1094*cdf0e10cSrcweir                     const Polygon           aEllipsePoly( pAct->GetRect().Center(), pAct->GetRect().GetWidth() >> 1, pAct->GetRect().GetHeight() >> 1 );
1095*cdf0e10cSrcweir 
1096*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aEllipsePoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
1097*cdf0e10cSrcweir                 }
1098*cdf0e10cSrcweir                 break;
1099*cdf0e10cSrcweir 
1100*cdf0e10cSrcweir                 case( META_ARC_ACTION ):
1101*cdf0e10cSrcweir                 {
1102*cdf0e10cSrcweir 				    MetaArcAction*  pAct = (MetaArcAction*) pAction;
1103*cdf0e10cSrcweir                     const Polygon   aArcPoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), POLY_ARC );
1104*cdf0e10cSrcweir 
1105*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aArcPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
1106*cdf0e10cSrcweir                 }
1107*cdf0e10cSrcweir                 break;
1108*cdf0e10cSrcweir 
1109*cdf0e10cSrcweir                 case( META_PIE_ACTION ):
1110*cdf0e10cSrcweir                 {
1111*cdf0e10cSrcweir 				    MetaPieAction*  pAct = (MetaPieAction*) pAction;
1112*cdf0e10cSrcweir                     const Polygon   aPiePoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), POLY_PIE );
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aPiePoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
1115*cdf0e10cSrcweir                 }
1116*cdf0e10cSrcweir                 break;
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir                 case( META_CHORD_ACTION	):
1119*cdf0e10cSrcweir                 {
1120*cdf0e10cSrcweir 				    MetaChordAction*    pAct = (MetaChordAction*) pAction;
1121*cdf0e10cSrcweir                     const Polygon       aChordPoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), POLY_CHORD );
1122*cdf0e10cSrcweir 
1123*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aChordPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
1124*cdf0e10cSrcweir                 }
1125*cdf0e10cSrcweir                 break;
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir                 case( META_POLYLINE_ACTION ):
1128*cdf0e10cSrcweir                 {
1129*cdf0e10cSrcweir 				    MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
1130*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolyLineAction( ImplGetRotatedPolygon( pAct->GetPolygon(), aRotAnchor, aRotOffset, fSin, fCos ), pAct->GetLineInfo() ) );
1131*cdf0e10cSrcweir                 }
1132*cdf0e10cSrcweir                 break;
1133*cdf0e10cSrcweir 
1134*cdf0e10cSrcweir                 case( META_POLYGON_ACTION ):
1135*cdf0e10cSrcweir                 {
1136*cdf0e10cSrcweir 				    MetaPolygonAction* pAct = (MetaPolygonAction*) pAction;
1137*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct->GetPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
1138*cdf0e10cSrcweir                 }
1139*cdf0e10cSrcweir                 break;
1140*cdf0e10cSrcweir 
1141*cdf0e10cSrcweir                 case( META_POLYPOLYGON_ACTION ):
1142*cdf0e10cSrcweir                 {
1143*cdf0e10cSrcweir 				    MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
1144*cdf0e10cSrcweir                     aMtf.AddAction( new MetaPolyPolygonAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
1145*cdf0e10cSrcweir                 }
1146*cdf0e10cSrcweir                 break;
1147*cdf0e10cSrcweir 
1148*cdf0e10cSrcweir                 case( META_TEXT_ACTION ):
1149*cdf0e10cSrcweir                 {
1150*cdf0e10cSrcweir 				    MetaTextAction* pAct = (MetaTextAction*) pAction;
1151*cdf0e10cSrcweir                     aMtf.AddAction( new MetaTextAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
1152*cdf0e10cSrcweir                                                                              pAct->GetText(), pAct->GetIndex(), pAct->GetLen() ) );
1153*cdf0e10cSrcweir                 }
1154*cdf0e10cSrcweir                 break;
1155*cdf0e10cSrcweir 
1156*cdf0e10cSrcweir                 case( META_TEXTARRAY_ACTION	):
1157*cdf0e10cSrcweir                 {
1158*cdf0e10cSrcweir 				    MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction;
1159*cdf0e10cSrcweir                     aMtf.AddAction( new MetaTextArrayAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
1160*cdf0e10cSrcweir                                                                                   pAct->GetText(), pAct->GetDXArray(), pAct->GetIndex(), pAct->GetLen() ) );
1161*cdf0e10cSrcweir                 }
1162*cdf0e10cSrcweir                 break;
1163*cdf0e10cSrcweir 
1164*cdf0e10cSrcweir                 case( META_STRETCHTEXT_ACTION ):
1165*cdf0e10cSrcweir                 {
1166*cdf0e10cSrcweir 				    MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction;
1167*cdf0e10cSrcweir                     aMtf.AddAction( new MetaStretchTextAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
1168*cdf0e10cSrcweir                                                                                     pAct->GetWidth(), pAct->GetText(), pAct->GetIndex(), pAct->GetLen() ) );
1169*cdf0e10cSrcweir                 }
1170*cdf0e10cSrcweir                 break;
1171*cdf0e10cSrcweir 
1172*cdf0e10cSrcweir                 case( META_TEXTLINE_ACTION ):
1173*cdf0e10cSrcweir                 {
1174*cdf0e10cSrcweir 				    MetaTextLineAction* pAct = (MetaTextLineAction*) pAction;
1175*cdf0e10cSrcweir                     aMtf.AddAction( new MetaTextLineAction( ImplGetRotatedPoint( pAct->GetStartPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
1176*cdf0e10cSrcweir                                                                                  pAct->GetWidth(), pAct->GetStrikeout(), pAct->GetUnderline(), pAct->GetOverline() ) );
1177*cdf0e10cSrcweir                 }
1178*cdf0e10cSrcweir                 break;
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir 			    case( META_BMPSCALE_ACTION ):
1181*cdf0e10cSrcweir 			    {
1182*cdf0e10cSrcweir 				    MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
1183*cdf0e10cSrcweir                     Polygon             aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1184*cdf0e10cSrcweir                     Rectangle           aBmpRect( aBmpPoly.GetBoundRect() );
1185*cdf0e10cSrcweir                     BitmapEx            aBmpEx( pAct->GetBitmap() );
1186*cdf0e10cSrcweir 
1187*cdf0e10cSrcweir                     aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) );
1188*cdf0e10cSrcweir                     aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(),
1189*cdf0e10cSrcweir                                                               aBmpEx ) );
1190*cdf0e10cSrcweir 			    }
1191*cdf0e10cSrcweir 			    break;
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir 			    case( META_BMPSCALEPART_ACTION ):
1194*cdf0e10cSrcweir 			    {
1195*cdf0e10cSrcweir 				    MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
1196*cdf0e10cSrcweir                     Polygon                 aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetDestPoint(), pAct->GetDestSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1197*cdf0e10cSrcweir                     Rectangle               aBmpRect( aBmpPoly.GetBoundRect() );
1198*cdf0e10cSrcweir                     BitmapEx                aBmpEx( pAct->GetBitmap() );
1199*cdf0e10cSrcweir 
1200*cdf0e10cSrcweir                     aBmpEx.Crop( Rectangle( pAct->GetSrcPoint(), pAct->GetSrcSize() ) );
1201*cdf0e10cSrcweir                     aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) );
1202*cdf0e10cSrcweir 
1203*cdf0e10cSrcweir                     aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) );
1204*cdf0e10cSrcweir 			    }
1205*cdf0e10cSrcweir 			    break;
1206*cdf0e10cSrcweir 
1207*cdf0e10cSrcweir 			    case( META_BMPEXSCALE_ACTION ):
1208*cdf0e10cSrcweir 			    {
1209*cdf0e10cSrcweir 				    MetaBmpExScaleAction*   pAct = (MetaBmpExScaleAction*) pAction;
1210*cdf0e10cSrcweir                     Polygon                 aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1211*cdf0e10cSrcweir                     Rectangle               aBmpRect( aBmpPoly.GetBoundRect() );
1212*cdf0e10cSrcweir                     BitmapEx                aBmpEx( pAct->GetBitmapEx() );
1213*cdf0e10cSrcweir 
1214*cdf0e10cSrcweir                     aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) );
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir                     aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) );
1217*cdf0e10cSrcweir 			    }
1218*cdf0e10cSrcweir 			    break;
1219*cdf0e10cSrcweir 
1220*cdf0e10cSrcweir 			    case( META_BMPEXSCALEPART_ACTION ):
1221*cdf0e10cSrcweir 			    {
1222*cdf0e10cSrcweir 				    MetaBmpExScalePartAction*   pAct = (MetaBmpExScalePartAction*) pAction;
1223*cdf0e10cSrcweir                     Polygon                     aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetDestPoint(), pAct->GetDestSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1224*cdf0e10cSrcweir                     Rectangle                   aBmpRect( aBmpPoly.GetBoundRect() );
1225*cdf0e10cSrcweir                     BitmapEx                    aBmpEx( pAct->GetBitmapEx() );
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir                     aBmpEx.Crop( Rectangle( pAct->GetSrcPoint(), pAct->GetSrcSize() ) );
1228*cdf0e10cSrcweir                     aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) );
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir                     aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) );
1231*cdf0e10cSrcweir 			    }
1232*cdf0e10cSrcweir 			    break;
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir 			    case( META_GRADIENT_ACTION ):
1235*cdf0e10cSrcweir 			    {
1236*cdf0e10cSrcweir 				    MetaGradientAction* pAct = (MetaGradientAction*) pAction;
1237*cdf0e10cSrcweir 
1238*cdf0e10cSrcweir                     ImplAddGradientEx( aMtf, aMapVDev,
1239*cdf0e10cSrcweir                                        ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ),
1240*cdf0e10cSrcweir                                        pAct->GetGradient() );
1241*cdf0e10cSrcweir 			    }
1242*cdf0e10cSrcweir 			    break;
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir 			    case( META_GRADIENTEX_ACTION ):
1245*cdf0e10cSrcweir 			    {
1246*cdf0e10cSrcweir 				    MetaGradientExAction* pAct = (MetaGradientExAction*) pAction;
1247*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaGradientExAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1248*cdf0e10cSrcweir                                                               pAct->GetGradient() ) );
1249*cdf0e10cSrcweir 			    }
1250*cdf0e10cSrcweir 			    break;
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir                 // #105055# Handle gradientex comment block correctly
1253*cdf0e10cSrcweir                 case( META_COMMENT_ACTION ):
1254*cdf0e10cSrcweir                 {
1255*cdf0e10cSrcweir 				    MetaCommentAction* pCommentAct = (MetaCommentAction*) pAction;
1256*cdf0e10cSrcweir                     if( pCommentAct->GetComment().Equals( "XGRAD_SEQ_BEGIN" ) )
1257*cdf0e10cSrcweir                     {
1258*cdf0e10cSrcweir                         int nBeginComments( 1 );
1259*cdf0e10cSrcweir                         pAction = (MetaAction*) Next();
1260*cdf0e10cSrcweir 
1261*cdf0e10cSrcweir                         // skip everything, except gradientex action
1262*cdf0e10cSrcweir                         while( pAction )
1263*cdf0e10cSrcweir                         {
1264*cdf0e10cSrcweir                             const sal_uInt16 nType = pAction->GetType();
1265*cdf0e10cSrcweir 
1266*cdf0e10cSrcweir                             if( META_GRADIENTEX_ACTION == nType )
1267*cdf0e10cSrcweir                             {
1268*cdf0e10cSrcweir                                 // Add rotated gradientex
1269*cdf0e10cSrcweir                                 MetaGradientExAction* pAct = (MetaGradientExAction*) pAction;
1270*cdf0e10cSrcweir                                 ImplAddGradientEx( aMtf, aMapVDev,
1271*cdf0e10cSrcweir                                                    ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1272*cdf0e10cSrcweir                                                    pAct->GetGradient() );
1273*cdf0e10cSrcweir                             }
1274*cdf0e10cSrcweir                             else if( META_COMMENT_ACTION == nType)
1275*cdf0e10cSrcweir                             {
1276*cdf0e10cSrcweir                                 MetaCommentAction* pAct = (MetaCommentAction*) pAction;
1277*cdf0e10cSrcweir                                 if( pAct->GetComment().Equals( "XGRAD_SEQ_END" ) )
1278*cdf0e10cSrcweir                                 {
1279*cdf0e10cSrcweir                                     // handle nested blocks
1280*cdf0e10cSrcweir                                     --nBeginComments;
1281*cdf0e10cSrcweir 
1282*cdf0e10cSrcweir                                     // gradientex comment block: end reached, done.
1283*cdf0e10cSrcweir                                     if( !nBeginComments )
1284*cdf0e10cSrcweir                                         break;
1285*cdf0e10cSrcweir                                 }
1286*cdf0e10cSrcweir                                 else if( pAct->GetComment().Equals( "XGRAD_SEQ_BEGIN" ) )
1287*cdf0e10cSrcweir                                 {
1288*cdf0e10cSrcweir                                     // handle nested blocks
1289*cdf0e10cSrcweir                                     ++nBeginComments;
1290*cdf0e10cSrcweir                                 }
1291*cdf0e10cSrcweir 
1292*cdf0e10cSrcweir                             }
1293*cdf0e10cSrcweir 
1294*cdf0e10cSrcweir                             pAction = (MetaAction*) Next();
1295*cdf0e10cSrcweir                         }
1296*cdf0e10cSrcweir                     }
1297*cdf0e10cSrcweir 					else
1298*cdf0e10cSrcweir 					{
1299*cdf0e10cSrcweir 						sal_Bool bPathStroke = pCommentAct->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" );
1300*cdf0e10cSrcweir 						if ( bPathStroke || pCommentAct->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) )
1301*cdf0e10cSrcweir 						{
1302*cdf0e10cSrcweir 							if ( pCommentAct->GetDataSize() )
1303*cdf0e10cSrcweir 							{
1304*cdf0e10cSrcweir 								SvMemoryStream aMemStm( (void*)pCommentAct->GetData(), pCommentAct->GetDataSize(), STREAM_READ );
1305*cdf0e10cSrcweir 								SvMemoryStream aDest;
1306*cdf0e10cSrcweir 								if ( bPathStroke )
1307*cdf0e10cSrcweir 								{
1308*cdf0e10cSrcweir 									SvtGraphicStroke aStroke;
1309*cdf0e10cSrcweir 									aMemStm >> aStroke;
1310*cdf0e10cSrcweir 									Polygon aPath;
1311*cdf0e10cSrcweir 									aStroke.getPath( aPath );
1312*cdf0e10cSrcweir 									aStroke.setPath( ImplGetRotatedPolygon( aPath, aRotAnchor, aRotOffset, fSin, fCos ) );
1313*cdf0e10cSrcweir 									aDest << aStroke;
1314*cdf0e10cSrcweir 									aMtf.AddAction( new MetaCommentAction( "XPATHSTROKE_SEQ_BEGIN", 0,
1315*cdf0e10cSrcweir 														static_cast<const sal_uInt8*>( aDest.GetData()), aDest.Tell() ) );
1316*cdf0e10cSrcweir 								}
1317*cdf0e10cSrcweir 								else
1318*cdf0e10cSrcweir 								{
1319*cdf0e10cSrcweir 									SvtGraphicFill aFill;
1320*cdf0e10cSrcweir 									aMemStm >> aFill;
1321*cdf0e10cSrcweir 									PolyPolygon aPath;
1322*cdf0e10cSrcweir 									aFill.getPath( aPath );
1323*cdf0e10cSrcweir 									aFill.setPath( ImplGetRotatedPolyPolygon( aPath, aRotAnchor, aRotOffset, fSin, fCos ) );
1324*cdf0e10cSrcweir 									aDest << aFill;
1325*cdf0e10cSrcweir 									aMtf.AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
1326*cdf0e10cSrcweir 														static_cast<const sal_uInt8*>( aDest.GetData()), aDest.Tell() ) );
1327*cdf0e10cSrcweir 								}
1328*cdf0e10cSrcweir 							}
1329*cdf0e10cSrcweir 						}
1330*cdf0e10cSrcweir 						else if ( pCommentAct->GetComment().Equals( "XPATHSTROKE_SEQ_END" )
1331*cdf0e10cSrcweir 							   || pCommentAct->GetComment().Equals( "XPATHFILL_SEQ_END" ) )
1332*cdf0e10cSrcweir 						{
1333*cdf0e10cSrcweir 						    pAction->Execute( &aMapVDev );
1334*cdf0e10cSrcweir 						    pAction->Duplicate();
1335*cdf0e10cSrcweir 						    aMtf.AddAction( pAction );
1336*cdf0e10cSrcweir 						}
1337*cdf0e10cSrcweir 					}
1338*cdf0e10cSrcweir                 }
1339*cdf0e10cSrcweir                 break;
1340*cdf0e10cSrcweir 
1341*cdf0e10cSrcweir 			    case( META_HATCH_ACTION ):
1342*cdf0e10cSrcweir 			    {
1343*cdf0e10cSrcweir 				    MetaHatchAction*	pAct = (MetaHatchAction*) pAction;
1344*cdf0e10cSrcweir 				    Hatch				aHatch( pAct->GetHatch() );
1345*cdf0e10cSrcweir 
1346*cdf0e10cSrcweir                     aHatch.SetAngle( aHatch.GetAngle() + (sal_uInt16) nAngle10 );
1347*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaHatchAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1348*cdf0e10cSrcweir                                                                                     aHatch ) );
1349*cdf0e10cSrcweir 			    }
1350*cdf0e10cSrcweir 			    break;
1351*cdf0e10cSrcweir 
1352*cdf0e10cSrcweir                 case( META_TRANSPARENT_ACTION ):
1353*cdf0e10cSrcweir                 {
1354*cdf0e10cSrcweir 				    MetaTransparentAction* pAct = (MetaTransparentAction*) pAction;
1355*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaTransparentAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1356*cdf0e10cSrcweir                                                                                           pAct->GetTransparence() ) );
1357*cdf0e10cSrcweir                 }
1358*cdf0e10cSrcweir                 break;
1359*cdf0e10cSrcweir 
1360*cdf0e10cSrcweir 			    case( META_FLOATTRANSPARENT_ACTION ):
1361*cdf0e10cSrcweir 			    {
1362*cdf0e10cSrcweir 				    MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction;
1363*cdf0e10cSrcweir 				    GDIMetaFile					aTransMtf( pAct->GetGDIMetaFile() );
1364*cdf0e10cSrcweir                     Polygon                     aMtfPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1365*cdf0e10cSrcweir                     Rectangle                   aMtfRect( aMtfPoly.GetBoundRect() );
1366*cdf0e10cSrcweir 
1367*cdf0e10cSrcweir                     aTransMtf.Rotate( nAngle10 );
1368*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaFloatTransparentAction( aTransMtf, aMtfRect.TopLeft(), aMtfRect.GetSize(),
1369*cdf0e10cSrcweir                                                                     pAct->GetGradient() ) );
1370*cdf0e10cSrcweir 			    }
1371*cdf0e10cSrcweir 			    break;
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir 			    case( META_EPS_ACTION ):
1374*cdf0e10cSrcweir 			    {
1375*cdf0e10cSrcweir 				    MetaEPSAction*	pAct = (MetaEPSAction*) pAction;
1376*cdf0e10cSrcweir 				    GDIMetaFile		aEPSMtf( pAct->GetSubstitute() );
1377*cdf0e10cSrcweir                     Polygon         aEPSPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1378*cdf0e10cSrcweir                     Rectangle       aEPSRect( aEPSPoly.GetBoundRect() );
1379*cdf0e10cSrcweir 
1380*cdf0e10cSrcweir                     aEPSMtf.Rotate( nAngle10 );
1381*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaEPSAction( aEPSRect.TopLeft(), aEPSRect.GetSize(),
1382*cdf0e10cSrcweir 												       pAct->GetLink(), aEPSMtf ) );
1383*cdf0e10cSrcweir 			    }
1384*cdf0e10cSrcweir 			    break;
1385*cdf0e10cSrcweir 
1386*cdf0e10cSrcweir                 case( META_CLIPREGION_ACTION ):
1387*cdf0e10cSrcweir                 {
1388*cdf0e10cSrcweir 				    MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction;
1389*cdf0e10cSrcweir 
1390*cdf0e10cSrcweir                     if( pAct->IsClipping() && pAct->GetRegion().HasPolyPolygon() )
1391*cdf0e10cSrcweir                         aMtf.AddAction( new MetaClipRegionAction( Region( ImplGetRotatedPolyPolygon( pAct->GetRegion().GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ), sal_True ) );
1392*cdf0e10cSrcweir                     else
1393*cdf0e10cSrcweir                     {
1394*cdf0e10cSrcweir 				        pAction->Duplicate();
1395*cdf0e10cSrcweir 				        aMtf.AddAction( pAction );
1396*cdf0e10cSrcweir                     }
1397*cdf0e10cSrcweir                 }
1398*cdf0e10cSrcweir                 break;
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir                 case( META_ISECTRECTCLIPREGION_ACTION ):
1401*cdf0e10cSrcweir                 {
1402*cdf0e10cSrcweir 				    MetaISectRectClipRegionAction*	pAct = (MetaISectRectClipRegionAction*) pAction;
1403*cdf0e10cSrcweir                     aMtf.AddAction( new MetaISectRegionClipRegionAction( ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
1404*cdf0e10cSrcweir                 }
1405*cdf0e10cSrcweir                 break;
1406*cdf0e10cSrcweir 
1407*cdf0e10cSrcweir                 case( META_ISECTREGIONCLIPREGION_ACTION	):
1408*cdf0e10cSrcweir                 {
1409*cdf0e10cSrcweir 				    MetaISectRegionClipRegionAction*    pAct = (MetaISectRegionClipRegionAction*) pAction;
1410*cdf0e10cSrcweir                     const Region&                       rRegion = pAct->GetRegion();
1411*cdf0e10cSrcweir 
1412*cdf0e10cSrcweir                     if( rRegion.HasPolyPolygon() )
1413*cdf0e10cSrcweir                         aMtf.AddAction( new MetaISectRegionClipRegionAction( Region( ImplGetRotatedPolyPolygon( rRegion.GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) ) );
1414*cdf0e10cSrcweir                     else
1415*cdf0e10cSrcweir                     {
1416*cdf0e10cSrcweir 				        pAction->Duplicate();
1417*cdf0e10cSrcweir 				        aMtf.AddAction( pAction );
1418*cdf0e10cSrcweir                     }
1419*cdf0e10cSrcweir                 }
1420*cdf0e10cSrcweir                 break;
1421*cdf0e10cSrcweir 
1422*cdf0e10cSrcweir                 case( META_REFPOINT_ACTION ):
1423*cdf0e10cSrcweir                 {
1424*cdf0e10cSrcweir 				    MetaRefPointAction* pAct = (MetaRefPointAction*) pAction;
1425*cdf0e10cSrcweir                     aMtf.AddAction( new MetaRefPointAction( ImplGetRotatedPoint( pAct->GetRefPoint(), aRotAnchor, aRotOffset, fSin, fCos ), pAct->IsSetting() ) );
1426*cdf0e10cSrcweir                 }
1427*cdf0e10cSrcweir                 break;
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir 			    case( META_FONT_ACTION ):
1430*cdf0e10cSrcweir 			    {
1431*cdf0e10cSrcweir 				    MetaFontAction* pAct = (MetaFontAction*) pAction;
1432*cdf0e10cSrcweir 				    Font			aFont( pAct->GetFont() );
1433*cdf0e10cSrcweir 
1434*cdf0e10cSrcweir 				    aFont.SetOrientation( aFont.GetOrientation() + (sal_uInt16) nAngle10 );
1435*cdf0e10cSrcweir 				    aMtf.AddAction( new MetaFontAction( aFont ) );
1436*cdf0e10cSrcweir 			    }
1437*cdf0e10cSrcweir 			    break;
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir 			    case( META_BMP_ACTION ):
1440*cdf0e10cSrcweir 			    case( META_BMPEX_ACTION ):
1441*cdf0e10cSrcweir 			    case( META_MASK_ACTION ):
1442*cdf0e10cSrcweir 			    case( META_MASKSCALE_ACTION ):
1443*cdf0e10cSrcweir 			    case( META_MASKSCALEPART_ACTION ):
1444*cdf0e10cSrcweir                 case( META_WALLPAPER_ACTION ):
1445*cdf0e10cSrcweir                 case( META_TEXTRECT_ACTION ):
1446*cdf0e10cSrcweir                 case( META_MOVECLIPREGION_ACTION ):
1447*cdf0e10cSrcweir 			    {
1448*cdf0e10cSrcweir 				    DBG_ERROR( "GDIMetaFile::Rotate(): unsupported action" );
1449*cdf0e10cSrcweir 			    }
1450*cdf0e10cSrcweir 			    break;
1451*cdf0e10cSrcweir 
1452*cdf0e10cSrcweir 			    case( META_RENDERGRAPHIC_ACTION ):
1453*cdf0e10cSrcweir                 {
1454*cdf0e10cSrcweir                     OSL_TRACE( "Rotate not supported for RenderGraphic MetaActions yet" );
1455*cdf0e10cSrcweir 
1456*cdf0e10cSrcweir 				    pAction->Duplicate();
1457*cdf0e10cSrcweir 				    aMtf.AddAction( pAction );
1458*cdf0e10cSrcweir                 }
1459*cdf0e10cSrcweir                 break;
1460*cdf0e10cSrcweir 
1461*cdf0e10cSrcweir 			    default:
1462*cdf0e10cSrcweir 			    {
1463*cdf0e10cSrcweir                     pAction->Execute( &aMapVDev );
1464*cdf0e10cSrcweir 				    pAction->Duplicate();
1465*cdf0e10cSrcweir 				    aMtf.AddAction( pAction );
1466*cdf0e10cSrcweir 
1467*cdf0e10cSrcweir                     // update rotation point and offset, if necessary
1468*cdf0e10cSrcweir                     if( ( META_MAPMODE_ACTION == nActionType ) ||
1469*cdf0e10cSrcweir                         ( META_PUSH_ACTION == nActionType ) ||
1470*cdf0e10cSrcweir                         ( META_POP_ACTION == nActionType ) )
1471*cdf0e10cSrcweir                     {
1472*cdf0e10cSrcweir                         aRotAnchor = aMapVDev.LogicToLogic( aOrigin, aPrefMapMode, aMapVDev.GetMapMode() );
1473*cdf0e10cSrcweir                         aRotOffset = aMapVDev.LogicToLogic( aOffset, aPrefMapMode, aMapVDev.GetMapMode() );
1474*cdf0e10cSrcweir                     }
1475*cdf0e10cSrcweir 			    }
1476*cdf0e10cSrcweir 			    break;
1477*cdf0e10cSrcweir 		    }
1478*cdf0e10cSrcweir 	    }
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir 	    aMtf.aPrefMapMode = aPrefMapMode;
1481*cdf0e10cSrcweir 	    aMtf.aPrefSize = aNewBound.GetSize();
1482*cdf0e10cSrcweir 
1483*cdf0e10cSrcweir 	    *this = aMtf;
1484*cdf0e10cSrcweir     }
1485*cdf0e10cSrcweir }
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir // ------------------------------------------------------------------------
1488*cdf0e10cSrcweir 
1489*cdf0e10cSrcweir static void ImplActionBounds( Rectangle& o_rOutBounds,
1490*cdf0e10cSrcweir                               const Rectangle& i_rInBounds,
1491*cdf0e10cSrcweir                               const std::vector<Rectangle>& i_rClipStack )
1492*cdf0e10cSrcweir {
1493*cdf0e10cSrcweir     Rectangle aBounds( i_rInBounds );
1494*cdf0e10cSrcweir     if( ! i_rInBounds.IsEmpty() && ! i_rClipStack.empty() && ! i_rClipStack.back().IsEmpty() )
1495*cdf0e10cSrcweir         aBounds.Intersection( i_rClipStack.back() );
1496*cdf0e10cSrcweir     if( ! aBounds.IsEmpty() )
1497*cdf0e10cSrcweir     {
1498*cdf0e10cSrcweir         if( ! o_rOutBounds.IsEmpty() )
1499*cdf0e10cSrcweir             o_rOutBounds.Union( aBounds );
1500*cdf0e10cSrcweir         else
1501*cdf0e10cSrcweir             o_rOutBounds = aBounds;
1502*cdf0e10cSrcweir     }
1503*cdf0e10cSrcweir }
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir Rectangle GDIMetaFile::GetBoundRect( OutputDevice& i_rReference )
1506*cdf0e10cSrcweir {
1507*cdf0e10cSrcweir     GDIMetaFile     aMtf;
1508*cdf0e10cSrcweir     VirtualDevice   aMapVDev( i_rReference );
1509*cdf0e10cSrcweir 
1510*cdf0e10cSrcweir     aMapVDev.EnableOutput( sal_False );
1511*cdf0e10cSrcweir     aMapVDev.SetMapMode( GetPrefMapMode() );
1512*cdf0e10cSrcweir 
1513*cdf0e10cSrcweir     std::vector<Rectangle> aClipStack( 1, Rectangle() );
1514*cdf0e10cSrcweir     std::vector<sal_uInt16> aPushFlagStack;
1515*cdf0e10cSrcweir 
1516*cdf0e10cSrcweir     Rectangle aBound;
1517*cdf0e10cSrcweir 
1518*cdf0e10cSrcweir     for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() )
1519*cdf0e10cSrcweir     {
1520*cdf0e10cSrcweir         const sal_uInt16 nActionType = pAction->GetType();
1521*cdf0e10cSrcweir 
1522*cdf0e10cSrcweir         switch( nActionType )
1523*cdf0e10cSrcweir         {
1524*cdf0e10cSrcweir         case( META_PIXEL_ACTION ):
1525*cdf0e10cSrcweir         {
1526*cdf0e10cSrcweir             MetaPixelAction* pAct = (MetaPixelAction*) pAction;
1527*cdf0e10cSrcweir             ImplActionBounds( aBound,
1528*cdf0e10cSrcweir                              Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ),
1529*cdf0e10cSrcweir                                        aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
1530*cdf0e10cSrcweir                              aClipStack );
1531*cdf0e10cSrcweir         }
1532*cdf0e10cSrcweir         break;
1533*cdf0e10cSrcweir 
1534*cdf0e10cSrcweir         case( META_POINT_ACTION ):
1535*cdf0e10cSrcweir         {
1536*cdf0e10cSrcweir             MetaPointAction* pAct = (MetaPointAction*) pAction;
1537*cdf0e10cSrcweir             ImplActionBounds( aBound,
1538*cdf0e10cSrcweir                              Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ),
1539*cdf0e10cSrcweir                                        aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
1540*cdf0e10cSrcweir                              aClipStack );
1541*cdf0e10cSrcweir         }
1542*cdf0e10cSrcweir         break;
1543*cdf0e10cSrcweir 
1544*cdf0e10cSrcweir         case( META_LINE_ACTION ):
1545*cdf0e10cSrcweir         {
1546*cdf0e10cSrcweir             MetaLineAction* pAct = (MetaLineAction*) pAction;
1547*cdf0e10cSrcweir             Point aP1( pAct->GetStartPoint() ), aP2( pAct->GetEndPoint() );
1548*cdf0e10cSrcweir             Rectangle aRect( aP1, aP2 );
1549*cdf0e10cSrcweir             aRect.Justify();
1550*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1551*cdf0e10cSrcweir         }
1552*cdf0e10cSrcweir         break;
1553*cdf0e10cSrcweir 
1554*cdf0e10cSrcweir         case( META_RECT_ACTION ):
1555*cdf0e10cSrcweir         {
1556*cdf0e10cSrcweir             MetaRectAction* pAct = (MetaRectAction*) pAction;
1557*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1558*cdf0e10cSrcweir         }
1559*cdf0e10cSrcweir         break;
1560*cdf0e10cSrcweir 
1561*cdf0e10cSrcweir         case( META_ROUNDRECT_ACTION ):
1562*cdf0e10cSrcweir         {
1563*cdf0e10cSrcweir             MetaRoundRectAction*    pAct = (MetaRoundRectAction*) pAction;
1564*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1565*cdf0e10cSrcweir         }
1566*cdf0e10cSrcweir         break;
1567*cdf0e10cSrcweir 
1568*cdf0e10cSrcweir         case( META_ELLIPSE_ACTION ):
1569*cdf0e10cSrcweir         {
1570*cdf0e10cSrcweir             MetaEllipseAction*      pAct = (MetaEllipseAction*) pAction;
1571*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1572*cdf0e10cSrcweir         }
1573*cdf0e10cSrcweir         break;
1574*cdf0e10cSrcweir 
1575*cdf0e10cSrcweir         case( META_ARC_ACTION ):
1576*cdf0e10cSrcweir         {
1577*cdf0e10cSrcweir             MetaArcAction*  pAct = (MetaArcAction*) pAction;
1578*cdf0e10cSrcweir             // FIXME: this is imprecise
1579*cdf0e10cSrcweir             // e.g. for small arcs the whole rectangle is WAY too large
1580*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1581*cdf0e10cSrcweir         }
1582*cdf0e10cSrcweir         break;
1583*cdf0e10cSrcweir 
1584*cdf0e10cSrcweir         case( META_PIE_ACTION ):
1585*cdf0e10cSrcweir         {
1586*cdf0e10cSrcweir             MetaPieAction*  pAct = (MetaPieAction*) pAction;
1587*cdf0e10cSrcweir             // FIXME: this is imprecise
1588*cdf0e10cSrcweir             // e.g. for small arcs the whole rectangle is WAY too large
1589*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1590*cdf0e10cSrcweir         }
1591*cdf0e10cSrcweir         break;
1592*cdf0e10cSrcweir 
1593*cdf0e10cSrcweir         case( META_CHORD_ACTION	):
1594*cdf0e10cSrcweir         {
1595*cdf0e10cSrcweir             MetaChordAction*    pAct = (MetaChordAction*) pAction;
1596*cdf0e10cSrcweir             // FIXME: this is imprecise
1597*cdf0e10cSrcweir             // e.g. for small arcs the whole rectangle is WAY too large
1598*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1599*cdf0e10cSrcweir         }
1600*cdf0e10cSrcweir         break;
1601*cdf0e10cSrcweir 
1602*cdf0e10cSrcweir         case( META_POLYLINE_ACTION ):
1603*cdf0e10cSrcweir         {
1604*cdf0e10cSrcweir             MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
1605*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPolygon().GetBoundRect() );
1606*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1607*cdf0e10cSrcweir         }
1608*cdf0e10cSrcweir         break;
1609*cdf0e10cSrcweir 
1610*cdf0e10cSrcweir         case( META_POLYGON_ACTION ):
1611*cdf0e10cSrcweir         {
1612*cdf0e10cSrcweir             MetaPolygonAction* pAct = (MetaPolygonAction*) pAction;
1613*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPolygon().GetBoundRect() );
1614*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1615*cdf0e10cSrcweir         }
1616*cdf0e10cSrcweir         break;
1617*cdf0e10cSrcweir 
1618*cdf0e10cSrcweir         case( META_POLYPOLYGON_ACTION ):
1619*cdf0e10cSrcweir         {
1620*cdf0e10cSrcweir             MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
1621*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1622*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1623*cdf0e10cSrcweir         }
1624*cdf0e10cSrcweir         break;
1625*cdf0e10cSrcweir 
1626*cdf0e10cSrcweir         case( META_TEXT_ACTION ):
1627*cdf0e10cSrcweir         {
1628*cdf0e10cSrcweir             MetaTextAction* pAct = (MetaTextAction*) pAction;
1629*cdf0e10cSrcweir             Rectangle aRect;
1630*cdf0e10cSrcweir             // hdu said base = index
1631*cdf0e10cSrcweir             aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen() );
1632*cdf0e10cSrcweir             Point aPt( pAct->GetPoint() );
1633*cdf0e10cSrcweir             aRect.Move( aPt.X(), aPt.Y() );
1634*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1635*cdf0e10cSrcweir         }
1636*cdf0e10cSrcweir         break;
1637*cdf0e10cSrcweir 
1638*cdf0e10cSrcweir         case( META_TEXTARRAY_ACTION	):
1639*cdf0e10cSrcweir         {
1640*cdf0e10cSrcweir             MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction;
1641*cdf0e10cSrcweir             Rectangle aRect;
1642*cdf0e10cSrcweir             // hdu said base = index
1643*cdf0e10cSrcweir             aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(),
1644*cdf0e10cSrcweir                                        0, pAct->GetDXArray() );
1645*cdf0e10cSrcweir             Point aPt( pAct->GetPoint() );
1646*cdf0e10cSrcweir             aRect.Move( aPt.X(), aPt.Y() );
1647*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1648*cdf0e10cSrcweir         }
1649*cdf0e10cSrcweir         break;
1650*cdf0e10cSrcweir 
1651*cdf0e10cSrcweir         case( META_STRETCHTEXT_ACTION ):
1652*cdf0e10cSrcweir         {
1653*cdf0e10cSrcweir             MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction;
1654*cdf0e10cSrcweir             Rectangle aRect;
1655*cdf0e10cSrcweir             // hdu said base = index
1656*cdf0e10cSrcweir             aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(),
1657*cdf0e10cSrcweir                                        pAct->GetWidth(), NULL );
1658*cdf0e10cSrcweir             Point aPt( pAct->GetPoint() );
1659*cdf0e10cSrcweir             aRect.Move( aPt.X(), aPt.Y() );
1660*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1661*cdf0e10cSrcweir         }
1662*cdf0e10cSrcweir         break;
1663*cdf0e10cSrcweir 
1664*cdf0e10cSrcweir         case( META_TEXTLINE_ACTION ):
1665*cdf0e10cSrcweir         {
1666*cdf0e10cSrcweir             MetaTextLineAction* pAct = (MetaTextLineAction*) pAction;
1667*cdf0e10cSrcweir             // measure a test string to get ascend and descent right
1668*cdf0e10cSrcweir             static const sal_Unicode pStr[] = { 0xc4, 0x67, 0 };
1669*cdf0e10cSrcweir             String aStr( pStr );
1670*cdf0e10cSrcweir 
1671*cdf0e10cSrcweir             Rectangle aRect;
1672*cdf0e10cSrcweir             aMapVDev.GetTextBoundRect( aRect, aStr, 0, 0, aStr.Len(), 0, NULL );
1673*cdf0e10cSrcweir             Point aPt( pAct->GetStartPoint() );
1674*cdf0e10cSrcweir             aRect.Move( aPt.X(), aPt.Y() );
1675*cdf0e10cSrcweir             aRect.Right() = aRect.Left() + pAct->GetWidth();
1676*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1677*cdf0e10cSrcweir         }
1678*cdf0e10cSrcweir         break;
1679*cdf0e10cSrcweir 
1680*cdf0e10cSrcweir         case( META_BMPSCALE_ACTION ):
1681*cdf0e10cSrcweir         {
1682*cdf0e10cSrcweir             MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
1683*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1684*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1685*cdf0e10cSrcweir         }
1686*cdf0e10cSrcweir         break;
1687*cdf0e10cSrcweir 
1688*cdf0e10cSrcweir         case( META_BMPSCALEPART_ACTION ):
1689*cdf0e10cSrcweir         {
1690*cdf0e10cSrcweir             MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
1691*cdf0e10cSrcweir             Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1692*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1693*cdf0e10cSrcweir         }
1694*cdf0e10cSrcweir         break;
1695*cdf0e10cSrcweir 
1696*cdf0e10cSrcweir         case( META_BMPEXSCALE_ACTION ):
1697*cdf0e10cSrcweir         {
1698*cdf0e10cSrcweir             MetaBmpExScaleAction*   pAct = (MetaBmpExScaleAction*) pAction;
1699*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1700*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1701*cdf0e10cSrcweir         }
1702*cdf0e10cSrcweir         break;
1703*cdf0e10cSrcweir 
1704*cdf0e10cSrcweir         case( META_BMPEXSCALEPART_ACTION ):
1705*cdf0e10cSrcweir         {
1706*cdf0e10cSrcweir             MetaBmpExScalePartAction*   pAct = (MetaBmpExScalePartAction*) pAction;
1707*cdf0e10cSrcweir             Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1708*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1709*cdf0e10cSrcweir         }
1710*cdf0e10cSrcweir         break;
1711*cdf0e10cSrcweir 
1712*cdf0e10cSrcweir         case( META_GRADIENT_ACTION ):
1713*cdf0e10cSrcweir         {
1714*cdf0e10cSrcweir             MetaGradientAction* pAct = (MetaGradientAction*) pAction;
1715*cdf0e10cSrcweir             Rectangle aRect( pAct->GetRect() );
1716*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1717*cdf0e10cSrcweir         }
1718*cdf0e10cSrcweir         break;
1719*cdf0e10cSrcweir 
1720*cdf0e10cSrcweir         case( META_GRADIENTEX_ACTION ):
1721*cdf0e10cSrcweir         {
1722*cdf0e10cSrcweir             MetaGradientExAction* pAct = (MetaGradientExAction*) pAction;
1723*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1724*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1725*cdf0e10cSrcweir         }
1726*cdf0e10cSrcweir         break;
1727*cdf0e10cSrcweir 
1728*cdf0e10cSrcweir         case( META_COMMENT_ACTION ):
1729*cdf0e10cSrcweir         {
1730*cdf0e10cSrcweir             // nothing to do
1731*cdf0e10cSrcweir         };
1732*cdf0e10cSrcweir         break;
1733*cdf0e10cSrcweir 
1734*cdf0e10cSrcweir         case( META_HATCH_ACTION ):
1735*cdf0e10cSrcweir         {
1736*cdf0e10cSrcweir             MetaHatchAction*	pAct = (MetaHatchAction*) pAction;
1737*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1738*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1739*cdf0e10cSrcweir         }
1740*cdf0e10cSrcweir         break;
1741*cdf0e10cSrcweir 
1742*cdf0e10cSrcweir         case( META_TRANSPARENT_ACTION ):
1743*cdf0e10cSrcweir         {
1744*cdf0e10cSrcweir             MetaTransparentAction* pAct = (MetaTransparentAction*) pAction;
1745*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1746*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1747*cdf0e10cSrcweir         }
1748*cdf0e10cSrcweir         break;
1749*cdf0e10cSrcweir 
1750*cdf0e10cSrcweir         case( META_FLOATTRANSPARENT_ACTION ):
1751*cdf0e10cSrcweir         {
1752*cdf0e10cSrcweir             MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction;
1753*cdf0e10cSrcweir             GDIMetaFile					aTransMtf( pAct->GetGDIMetaFile() );
1754*cdf0e10cSrcweir             // get the bound rect of the contained metafile
1755*cdf0e10cSrcweir             Rectangle aRect( aTransMtf.GetBoundRect( i_rReference ) );
1756*cdf0e10cSrcweir             // scale the rect now on the assumption that the correct top left of the metafile
1757*cdf0e10cSrcweir             // (not its bounds !) is (0,0)
1758*cdf0e10cSrcweir             Size aPSize( aTransMtf.GetPrefSize() );
1759*cdf0e10cSrcweir             aPSize = aMapVDev.LogicToLogic( aPSize, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() );
1760*cdf0e10cSrcweir             Size aActSize( pAct->GetSize() );
1761*cdf0e10cSrcweir             double fX = double(aActSize.Width())/double(aPSize.Width());
1762*cdf0e10cSrcweir             double fY = double(aActSize.Height())/double(aPSize.Height());
1763*cdf0e10cSrcweir             aRect.Left()   = long(double(aRect.Left())*fX);
1764*cdf0e10cSrcweir             aRect.Right()  = long(double(aRect.Right())*fX);
1765*cdf0e10cSrcweir             aRect.Top()    = long(double(aRect.Top())*fY);
1766*cdf0e10cSrcweir             aRect.Bottom() = long(double(aRect.Bottom())*fY);
1767*cdf0e10cSrcweir 
1768*cdf0e10cSrcweir             // transform the rect to current VDev state
1769*cdf0e10cSrcweir             aRect = aMapVDev.LogicToLogic( aRect, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() );
1770*cdf0e10cSrcweir 
1771*cdf0e10cSrcweir             ImplActionBounds( aBound, aRect, aClipStack );
1772*cdf0e10cSrcweir         }
1773*cdf0e10cSrcweir         break;
1774*cdf0e10cSrcweir 
1775*cdf0e10cSrcweir         case( META_EPS_ACTION ):
1776*cdf0e10cSrcweir         {
1777*cdf0e10cSrcweir             MetaEPSAction*	pAct = (MetaEPSAction*) pAction;
1778*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1779*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1780*cdf0e10cSrcweir         }
1781*cdf0e10cSrcweir         break;
1782*cdf0e10cSrcweir 
1783*cdf0e10cSrcweir         case( META_CLIPREGION_ACTION ):
1784*cdf0e10cSrcweir         {
1785*cdf0e10cSrcweir             MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction;
1786*cdf0e10cSrcweir             if( pAct->IsClipping() )
1787*cdf0e10cSrcweir                 aClipStack.back() = aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() );
1788*cdf0e10cSrcweir             else
1789*cdf0e10cSrcweir                 aClipStack.back() = Rectangle();
1790*cdf0e10cSrcweir         }
1791*cdf0e10cSrcweir         break;
1792*cdf0e10cSrcweir 
1793*cdf0e10cSrcweir         case( META_ISECTRECTCLIPREGION_ACTION ):
1794*cdf0e10cSrcweir         {
1795*cdf0e10cSrcweir             MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction;
1796*cdf0e10cSrcweir             Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) );
1797*cdf0e10cSrcweir             if( aClipStack.back().IsEmpty() )
1798*cdf0e10cSrcweir                 aClipStack.back() = aRect;
1799*cdf0e10cSrcweir             else
1800*cdf0e10cSrcweir                 aClipStack.back().Intersection( aRect );
1801*cdf0e10cSrcweir         }
1802*cdf0e10cSrcweir         break;
1803*cdf0e10cSrcweir 
1804*cdf0e10cSrcweir         case( META_ISECTREGIONCLIPREGION_ACTION	):
1805*cdf0e10cSrcweir         {
1806*cdf0e10cSrcweir             MetaISectRegionClipRegionAction*    pAct = (MetaISectRegionClipRegionAction*) pAction;
1807*cdf0e10cSrcweir             Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) );
1808*cdf0e10cSrcweir             if( aClipStack.back().IsEmpty() )
1809*cdf0e10cSrcweir                 aClipStack.back() = aRect;
1810*cdf0e10cSrcweir             else
1811*cdf0e10cSrcweir                 aClipStack.back().Intersection( aRect );
1812*cdf0e10cSrcweir         }
1813*cdf0e10cSrcweir         break;
1814*cdf0e10cSrcweir 
1815*cdf0e10cSrcweir         case( META_BMP_ACTION ):
1816*cdf0e10cSrcweir         {
1817*cdf0e10cSrcweir             MetaBmpAction* pAct = (MetaBmpAction*) pAction;
1818*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) );
1819*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1820*cdf0e10cSrcweir         }
1821*cdf0e10cSrcweir         break;
1822*cdf0e10cSrcweir 
1823*cdf0e10cSrcweir         case( META_BMPEX_ACTION ):
1824*cdf0e10cSrcweir         {
1825*cdf0e10cSrcweir             MetaBmpExAction* pAct = (MetaBmpExAction*) pAction;
1826*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) );
1827*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1828*cdf0e10cSrcweir         }
1829*cdf0e10cSrcweir         break;
1830*cdf0e10cSrcweir 
1831*cdf0e10cSrcweir         case( META_MASK_ACTION ):
1832*cdf0e10cSrcweir         {
1833*cdf0e10cSrcweir             MetaMaskAction* pAct = (MetaMaskAction*) pAction;
1834*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) );
1835*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1836*cdf0e10cSrcweir         }
1837*cdf0e10cSrcweir         break;
1838*cdf0e10cSrcweir 
1839*cdf0e10cSrcweir         case( META_MASKSCALE_ACTION ):
1840*cdf0e10cSrcweir         {
1841*cdf0e10cSrcweir             MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
1842*cdf0e10cSrcweir             Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1843*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1844*cdf0e10cSrcweir         }
1845*cdf0e10cSrcweir         break;
1846*cdf0e10cSrcweir 
1847*cdf0e10cSrcweir         case( META_MASKSCALEPART_ACTION ):
1848*cdf0e10cSrcweir         {
1849*cdf0e10cSrcweir             MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
1850*cdf0e10cSrcweir             Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1851*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1852*cdf0e10cSrcweir         }
1853*cdf0e10cSrcweir         break;
1854*cdf0e10cSrcweir 
1855*cdf0e10cSrcweir         case( META_WALLPAPER_ACTION ):
1856*cdf0e10cSrcweir         {
1857*cdf0e10cSrcweir             MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction;
1858*cdf0e10cSrcweir             Rectangle aRect( pAct->GetRect() );
1859*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1860*cdf0e10cSrcweir         }
1861*cdf0e10cSrcweir         break;
1862*cdf0e10cSrcweir 
1863*cdf0e10cSrcweir         case( META_TEXTRECT_ACTION ):
1864*cdf0e10cSrcweir         {
1865*cdf0e10cSrcweir             MetaTextRectAction* pAct = (MetaTextRectAction*) pAction;
1866*cdf0e10cSrcweir             Rectangle aRect( pAct->GetRect() );
1867*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1868*cdf0e10cSrcweir         }
1869*cdf0e10cSrcweir         break;
1870*cdf0e10cSrcweir 
1871*cdf0e10cSrcweir         case( META_MOVECLIPREGION_ACTION ):
1872*cdf0e10cSrcweir         {
1873*cdf0e10cSrcweir             MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction;
1874*cdf0e10cSrcweir             if( ! aClipStack.back().IsEmpty() )
1875*cdf0e10cSrcweir             {
1876*cdf0e10cSrcweir                 Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() );
1877*cdf0e10cSrcweir                 aDelta = aMapVDev.LogicToLogic( aDelta, aMapVDev.GetMapMode(), GetPrefMapMode() );
1878*cdf0e10cSrcweir                 aClipStack.back().Move( aDelta.Width(), aDelta.Width() );
1879*cdf0e10cSrcweir             }
1880*cdf0e10cSrcweir         }
1881*cdf0e10cSrcweir         break;
1882*cdf0e10cSrcweir 
1883*cdf0e10cSrcweir         case( META_RENDERGRAPHIC_ACTION ):
1884*cdf0e10cSrcweir         {
1885*cdf0e10cSrcweir             MetaRenderGraphicAction* pAct = (MetaRenderGraphicAction*) pAction;
1886*cdf0e10cSrcweir             Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1887*cdf0e10cSrcweir             ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
1888*cdf0e10cSrcweir         }
1889*cdf0e10cSrcweir         break;
1890*cdf0e10cSrcweir 
1891*cdf0e10cSrcweir         default:
1892*cdf0e10cSrcweir             {
1893*cdf0e10cSrcweir                 pAction->Execute( &aMapVDev );
1894*cdf0e10cSrcweir 
1895*cdf0e10cSrcweir                 if( nActionType == META_PUSH_ACTION )
1896*cdf0e10cSrcweir                 {
1897*cdf0e10cSrcweir                     MetaPushAction* pAct = (MetaPushAction*) pAction;
1898*cdf0e10cSrcweir                     aPushFlagStack.push_back( pAct->GetFlags() );
1899*cdf0e10cSrcweir                     if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 )
1900*cdf0e10cSrcweir                     {
1901*cdf0e10cSrcweir                         Rectangle aRect( aClipStack.back() );
1902*cdf0e10cSrcweir                         aClipStack.push_back( aRect );
1903*cdf0e10cSrcweir                     }
1904*cdf0e10cSrcweir                 }
1905*cdf0e10cSrcweir                 else if( nActionType == META_POP_ACTION )
1906*cdf0e10cSrcweir                 {
1907*cdf0e10cSrcweir                     // sanity check
1908*cdf0e10cSrcweir                     if( ! aPushFlagStack.empty() )
1909*cdf0e10cSrcweir                     {
1910*cdf0e10cSrcweir                         if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 )
1911*cdf0e10cSrcweir                         {
1912*cdf0e10cSrcweir                             if( aClipStack.size() > 1 )
1913*cdf0e10cSrcweir                                 aClipStack.pop_back();
1914*cdf0e10cSrcweir                         }
1915*cdf0e10cSrcweir                         aPushFlagStack.pop_back();
1916*cdf0e10cSrcweir                     }
1917*cdf0e10cSrcweir                 }
1918*cdf0e10cSrcweir             }
1919*cdf0e10cSrcweir             break;
1920*cdf0e10cSrcweir         }
1921*cdf0e10cSrcweir     }
1922*cdf0e10cSrcweir     return aBound;
1923*cdf0e10cSrcweir }
1924*cdf0e10cSrcweir 
1925*cdf0e10cSrcweir // ------------------------------------------------------------------------
1926*cdf0e10cSrcweir 
1927*cdf0e10cSrcweir Color GDIMetaFile::ImplColAdjustFnc( const Color& rColor, const void* pColParam )
1928*cdf0e10cSrcweir {
1929*cdf0e10cSrcweir 	return Color( rColor.GetTransparency(),
1930*cdf0e10cSrcweir 				  ( (const ImplColAdjustParam*) pColParam )->pMapR[ rColor.GetRed() ],
1931*cdf0e10cSrcweir 				  ( (const ImplColAdjustParam*) pColParam )->pMapG[ rColor.GetGreen() ],
1932*cdf0e10cSrcweir 				  ( (const ImplColAdjustParam*) pColParam )->pMapB[ rColor.GetBlue() ] );
1933*cdf0e10cSrcweir 
1934*cdf0e10cSrcweir }
1935*cdf0e10cSrcweir 
1936*cdf0e10cSrcweir // ------------------------------------------------------------------------
1937*cdf0e10cSrcweir 
1938*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpAdjustFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
1939*cdf0e10cSrcweir {
1940*cdf0e10cSrcweir 	const ImplBmpAdjustParam*	p = (const ImplBmpAdjustParam*) pBmpParam;
1941*cdf0e10cSrcweir 	BitmapEx					aRet( rBmpEx );
1942*cdf0e10cSrcweir 
1943*cdf0e10cSrcweir 	aRet.Adjust( p->nLuminancePercent, p->nContrastPercent,
1944*cdf0e10cSrcweir 				 p->nChannelRPercent, p->nChannelGPercent, p->nChannelBPercent,
1945*cdf0e10cSrcweir 				 p->fGamma, p->bInvert );
1946*cdf0e10cSrcweir 
1947*cdf0e10cSrcweir 	return aRet;
1948*cdf0e10cSrcweir }
1949*cdf0e10cSrcweir 
1950*cdf0e10cSrcweir // ------------------------------------------------------------------------
1951*cdf0e10cSrcweir 
1952*cdf0e10cSrcweir Color GDIMetaFile::ImplColConvertFnc( const Color& rColor, const void* pColParam )
1953*cdf0e10cSrcweir {
1954*cdf0e10cSrcweir 	sal_uInt8 cLum = rColor.GetLuminance();
1955*cdf0e10cSrcweir 
1956*cdf0e10cSrcweir 	if( MTF_CONVERSION_1BIT_THRESHOLD == ( (const ImplColConvertParam*) pColParam )->eConversion )
1957*cdf0e10cSrcweir 		cLum = ( cLum < 128 ) ? 0 : 255;
1958*cdf0e10cSrcweir 
1959*cdf0e10cSrcweir 	return Color( rColor.GetTransparency(), cLum, cLum, cLum );
1960*cdf0e10cSrcweir }
1961*cdf0e10cSrcweir 
1962*cdf0e10cSrcweir // ------------------------------------------------------------------------
1963*cdf0e10cSrcweir 
1964*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpConvertFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
1965*cdf0e10cSrcweir {
1966*cdf0e10cSrcweir 	BitmapEx aRet( rBmpEx );
1967*cdf0e10cSrcweir 
1968*cdf0e10cSrcweir 	aRet.Convert( ( (const ImplBmpConvertParam*) pBmpParam )->eConversion );
1969*cdf0e10cSrcweir 
1970*cdf0e10cSrcweir 	return aRet;
1971*cdf0e10cSrcweir }
1972*cdf0e10cSrcweir 
1973*cdf0e10cSrcweir // ------------------------------------------------------------------------
1974*cdf0e10cSrcweir 
1975*cdf0e10cSrcweir Color GDIMetaFile::ImplColMonoFnc( const Color&, const void* pColParam )
1976*cdf0e10cSrcweir {
1977*cdf0e10cSrcweir 	return( ( (const ImplColMonoParam*) pColParam )->aColor );
1978*cdf0e10cSrcweir }
1979*cdf0e10cSrcweir 
1980*cdf0e10cSrcweir // ------------------------------------------------------------------------
1981*cdf0e10cSrcweir 
1982*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpMonoFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
1983*cdf0e10cSrcweir {
1984*cdf0e10cSrcweir 	BitmapPalette aPal( 3 );
1985*cdf0e10cSrcweir 
1986*cdf0e10cSrcweir 	aPal[ 0 ] = Color( COL_BLACK );
1987*cdf0e10cSrcweir 	aPal[ 1 ] = Color( COL_WHITE );
1988*cdf0e10cSrcweir 	aPal[ 2 ] = ( (const ImplBmpMonoParam*) pBmpParam )->aColor;
1989*cdf0e10cSrcweir 
1990*cdf0e10cSrcweir 	Bitmap aBmp( rBmpEx.GetSizePixel(), 4, &aPal );
1991*cdf0e10cSrcweir 	aBmp.Erase( ( (const ImplBmpMonoParam*) pBmpParam )->aColor );
1992*cdf0e10cSrcweir 
1993*cdf0e10cSrcweir 	if( rBmpEx.IsAlpha() )
1994*cdf0e10cSrcweir 		return BitmapEx( aBmp, rBmpEx.GetAlpha() );
1995*cdf0e10cSrcweir 	else if( rBmpEx.IsTransparent() )
1996*cdf0e10cSrcweir 		return BitmapEx( aBmp, rBmpEx.GetMask() );
1997*cdf0e10cSrcweir 	else
1998*cdf0e10cSrcweir 		return aBmp;
1999*cdf0e10cSrcweir }
2000*cdf0e10cSrcweir 
2001*cdf0e10cSrcweir // ------------------------------------------------------------------------
2002*cdf0e10cSrcweir 
2003*cdf0e10cSrcweir Color GDIMetaFile::ImplColReplaceFnc( const Color& rColor, const void* pColParam )
2004*cdf0e10cSrcweir {
2005*cdf0e10cSrcweir 	const sal_uLong nR = rColor.GetRed(), nG = rColor.GetGreen(), nB = rColor.GetBlue();
2006*cdf0e10cSrcweir 
2007*cdf0e10cSrcweir 	for( sal_uLong i = 0; i < ( (const ImplColReplaceParam*) pColParam )->nCount; i++ )
2008*cdf0e10cSrcweir 	{
2009*cdf0e10cSrcweir 		if( ( ( (const ImplColReplaceParam*) pColParam )->pMinR[ i ] <= nR ) &&
2010*cdf0e10cSrcweir 			( ( (const ImplColReplaceParam*) pColParam )->pMaxR[ i ] >= nR ) &&
2011*cdf0e10cSrcweir 			( ( (const ImplColReplaceParam*) pColParam )->pMinG[ i ] <= nG ) &&
2012*cdf0e10cSrcweir 			( ( (const ImplColReplaceParam*) pColParam )->pMaxG[ i ] >= nG ) &&
2013*cdf0e10cSrcweir 			( ( (const ImplColReplaceParam*) pColParam )->pMinB[ i ] <= nB ) &&
2014*cdf0e10cSrcweir 			( ( (const ImplColReplaceParam*) pColParam )->pMaxB[ i ] >= nB ) )
2015*cdf0e10cSrcweir 		{
2016*cdf0e10cSrcweir 			return( ( (const ImplColReplaceParam*) pColParam )->pDstCols[ i ] );
2017*cdf0e10cSrcweir 		}
2018*cdf0e10cSrcweir 	}
2019*cdf0e10cSrcweir 
2020*cdf0e10cSrcweir 	return rColor;
2021*cdf0e10cSrcweir }
2022*cdf0e10cSrcweir 
2023*cdf0e10cSrcweir // ------------------------------------------------------------------------
2024*cdf0e10cSrcweir 
2025*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpReplaceFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
2026*cdf0e10cSrcweir {
2027*cdf0e10cSrcweir 	const ImplBmpReplaceParam*	p = (const ImplBmpReplaceParam*) pBmpParam;
2028*cdf0e10cSrcweir 	BitmapEx					aRet( rBmpEx );
2029*cdf0e10cSrcweir 
2030*cdf0e10cSrcweir 	aRet.Replace( p->pSrcCols, p->pDstCols, p->nCount, p->pTols );
2031*cdf0e10cSrcweir 
2032*cdf0e10cSrcweir 	return aRet;
2033*cdf0e10cSrcweir }
2034*cdf0e10cSrcweir 
2035*cdf0e10cSrcweir // ------------------------------------------------------------------------
2036*cdf0e10cSrcweir 
2037*cdf0e10cSrcweir void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pColParam,
2038*cdf0e10cSrcweir 									  BmpExchangeFnc pFncBmp, const void* pBmpParam )
2039*cdf0e10cSrcweir {
2040*cdf0e10cSrcweir 	GDIMetaFile aMtf;
2041*cdf0e10cSrcweir 
2042*cdf0e10cSrcweir 	aMtf.aPrefSize = aPrefSize;
2043*cdf0e10cSrcweir 	aMtf.aPrefMapMode = aPrefMapMode;
2044*cdf0e10cSrcweir 
2045*cdf0e10cSrcweir 	for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() )
2046*cdf0e10cSrcweir 	{
2047*cdf0e10cSrcweir 		const sal_uInt16 nType = pAction->GetType();
2048*cdf0e10cSrcweir 
2049*cdf0e10cSrcweir 		switch( nType )
2050*cdf0e10cSrcweir 		{
2051*cdf0e10cSrcweir 			case( META_PIXEL_ACTION ):
2052*cdf0e10cSrcweir 			{
2053*cdf0e10cSrcweir 				MetaPixelAction* pAct = (MetaPixelAction*) pAction;
2054*cdf0e10cSrcweir 				aMtf.Insert( new MetaPixelAction( pAct->GetPoint(), pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND );
2055*cdf0e10cSrcweir 			}
2056*cdf0e10cSrcweir 			break;
2057*cdf0e10cSrcweir 
2058*cdf0e10cSrcweir 			case( META_LINECOLOR_ACTION ):
2059*cdf0e10cSrcweir 			{
2060*cdf0e10cSrcweir 				MetaLineColorAction* pAct = (MetaLineColorAction*) pAction;
2061*cdf0e10cSrcweir 
2062*cdf0e10cSrcweir 				if( !pAct->IsSetting() )
2063*cdf0e10cSrcweir 					pAct->Duplicate();
2064*cdf0e10cSrcweir 				else
2065*cdf0e10cSrcweir 					pAct = new MetaLineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True );
2066*cdf0e10cSrcweir 
2067*cdf0e10cSrcweir 				aMtf.Insert( pAct, LIST_APPEND );
2068*cdf0e10cSrcweir 			}
2069*cdf0e10cSrcweir 			break;
2070*cdf0e10cSrcweir 
2071*cdf0e10cSrcweir 			case( META_FILLCOLOR_ACTION ):
2072*cdf0e10cSrcweir 			{
2073*cdf0e10cSrcweir 				MetaFillColorAction* pAct = (MetaFillColorAction*) pAction;
2074*cdf0e10cSrcweir 
2075*cdf0e10cSrcweir 				if( !pAct->IsSetting() )
2076*cdf0e10cSrcweir 					pAct->Duplicate();
2077*cdf0e10cSrcweir 				else
2078*cdf0e10cSrcweir 					pAct = new MetaFillColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True );
2079*cdf0e10cSrcweir 
2080*cdf0e10cSrcweir 				aMtf.Insert( pAct, LIST_APPEND );
2081*cdf0e10cSrcweir 			}
2082*cdf0e10cSrcweir 			break;
2083*cdf0e10cSrcweir 
2084*cdf0e10cSrcweir 			case( META_TEXTCOLOR_ACTION ):
2085*cdf0e10cSrcweir 			{
2086*cdf0e10cSrcweir 				MetaTextColorAction* pAct = (MetaTextColorAction*) pAction;
2087*cdf0e10cSrcweir 				aMtf.Insert( new MetaTextColorAction( pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND );
2088*cdf0e10cSrcweir 			}
2089*cdf0e10cSrcweir 			break;
2090*cdf0e10cSrcweir 
2091*cdf0e10cSrcweir 			case( META_TEXTFILLCOLOR_ACTION ):
2092*cdf0e10cSrcweir 			{
2093*cdf0e10cSrcweir 				MetaTextFillColorAction* pAct = (MetaTextFillColorAction*) pAction;
2094*cdf0e10cSrcweir 
2095*cdf0e10cSrcweir 				if( !pAct->IsSetting() )
2096*cdf0e10cSrcweir 					pAct->Duplicate();
2097*cdf0e10cSrcweir 				else
2098*cdf0e10cSrcweir 					pAct = new MetaTextFillColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True );
2099*cdf0e10cSrcweir 
2100*cdf0e10cSrcweir 				aMtf.Insert( pAct, LIST_APPEND );
2101*cdf0e10cSrcweir 			}
2102*cdf0e10cSrcweir 			break;
2103*cdf0e10cSrcweir 
2104*cdf0e10cSrcweir 			case( META_TEXTLINECOLOR_ACTION ):
2105*cdf0e10cSrcweir 			{
2106*cdf0e10cSrcweir 				MetaTextLineColorAction* pAct = (MetaTextLineColorAction*) pAction;
2107*cdf0e10cSrcweir 
2108*cdf0e10cSrcweir 				if( !pAct->IsSetting() )
2109*cdf0e10cSrcweir 					pAct->Duplicate();
2110*cdf0e10cSrcweir 				else
2111*cdf0e10cSrcweir 					pAct = new MetaTextLineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True );
2112*cdf0e10cSrcweir 
2113*cdf0e10cSrcweir 				aMtf.Insert( pAct, LIST_APPEND );
2114*cdf0e10cSrcweir 			}
2115*cdf0e10cSrcweir 			break;
2116*cdf0e10cSrcweir 
2117*cdf0e10cSrcweir 			case( META_OVERLINECOLOR_ACTION ):
2118*cdf0e10cSrcweir 			{
2119*cdf0e10cSrcweir 				MetaOverlineColorAction* pAct = (MetaOverlineColorAction*) pAction;
2120*cdf0e10cSrcweir 
2121*cdf0e10cSrcweir 				if( !pAct->IsSetting() )
2122*cdf0e10cSrcweir 					pAct->Duplicate();
2123*cdf0e10cSrcweir 				else
2124*cdf0e10cSrcweir 					pAct = new MetaOverlineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True );
2125*cdf0e10cSrcweir 
2126*cdf0e10cSrcweir 				aMtf.Insert( pAct, LIST_APPEND );
2127*cdf0e10cSrcweir 			}
2128*cdf0e10cSrcweir 			break;
2129*cdf0e10cSrcweir 
2130*cdf0e10cSrcweir 			case( META_FONT_ACTION ):
2131*cdf0e10cSrcweir 			{
2132*cdf0e10cSrcweir 				MetaFontAction* pAct = (MetaFontAction*) pAction;
2133*cdf0e10cSrcweir 				Font			aFont( pAct->GetFont() );
2134*cdf0e10cSrcweir 
2135*cdf0e10cSrcweir 				aFont.SetColor( pFncCol( aFont.GetColor(), pColParam ) );
2136*cdf0e10cSrcweir 				aFont.SetFillColor( pFncCol( aFont.GetFillColor(), pColParam ) );
2137*cdf0e10cSrcweir 				aMtf.Insert( new MetaFontAction( aFont ), LIST_APPEND );
2138*cdf0e10cSrcweir 			}
2139*cdf0e10cSrcweir 			break;
2140*cdf0e10cSrcweir 
2141*cdf0e10cSrcweir 			case( META_WALLPAPER_ACTION ):
2142*cdf0e10cSrcweir 			{
2143*cdf0e10cSrcweir 				MetaWallpaperAction*	pAct = (MetaWallpaperAction*) pAction;
2144*cdf0e10cSrcweir 				Wallpaper				aWall( pAct->GetWallpaper() );
2145*cdf0e10cSrcweir 				const Rectangle&		rRect = pAct->GetRect();
2146*cdf0e10cSrcweir 
2147*cdf0e10cSrcweir 				aWall.SetColor( pFncCol( aWall.GetColor(), pColParam ) );
2148*cdf0e10cSrcweir 
2149*cdf0e10cSrcweir 				if( aWall.IsBitmap() )
2150*cdf0e10cSrcweir 					aWall.SetBitmap( pFncBmp( aWall.GetBitmap(), pBmpParam ) );
2151*cdf0e10cSrcweir 
2152*cdf0e10cSrcweir 				if( aWall.IsGradient() )
2153*cdf0e10cSrcweir 				{
2154*cdf0e10cSrcweir 					Gradient aGradient( aWall.GetGradient() );
2155*cdf0e10cSrcweir 
2156*cdf0e10cSrcweir 					aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
2157*cdf0e10cSrcweir 					aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
2158*cdf0e10cSrcweir 					aWall.SetGradient( aGradient );
2159*cdf0e10cSrcweir 				}
2160*cdf0e10cSrcweir 
2161*cdf0e10cSrcweir 				aMtf.Insert( new MetaWallpaperAction( rRect, aWall ), LIST_APPEND );
2162*cdf0e10cSrcweir 			}
2163*cdf0e10cSrcweir 			break;
2164*cdf0e10cSrcweir 
2165*cdf0e10cSrcweir 			case( META_BMP_ACTION ):
2166*cdf0e10cSrcweir 			case( META_BMPEX_ACTION ):
2167*cdf0e10cSrcweir 			case( META_MASK_ACTION ):
2168*cdf0e10cSrcweir 			{
2169*cdf0e10cSrcweir 				DBG_ERROR( "Don't use bitmap actions of this type in metafiles!" );
2170*cdf0e10cSrcweir 			}
2171*cdf0e10cSrcweir 			break;
2172*cdf0e10cSrcweir 
2173*cdf0e10cSrcweir 			case( META_BMPSCALE_ACTION ):
2174*cdf0e10cSrcweir 			{
2175*cdf0e10cSrcweir 				MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
2176*cdf0e10cSrcweir 				aMtf.Insert( new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(),
2177*cdf0e10cSrcweir 													 pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ),
2178*cdf0e10cSrcweir 													 LIST_APPEND );
2179*cdf0e10cSrcweir 			}
2180*cdf0e10cSrcweir 			break;
2181*cdf0e10cSrcweir 
2182*cdf0e10cSrcweir 			case( META_BMPSCALEPART_ACTION ):
2183*cdf0e10cSrcweir 			{
2184*cdf0e10cSrcweir 				MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
2185*cdf0e10cSrcweir 				aMtf.Insert( new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
2186*cdf0e10cSrcweir 														 pAct->GetSrcPoint(), pAct->GetSrcSize(),
2187*cdf0e10cSrcweir 														 pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ),
2188*cdf0e10cSrcweir 														 LIST_APPEND );
2189*cdf0e10cSrcweir 			}
2190*cdf0e10cSrcweir 			break;
2191*cdf0e10cSrcweir 
2192*cdf0e10cSrcweir 			case( META_BMPEXSCALE_ACTION ):
2193*cdf0e10cSrcweir 			{
2194*cdf0e10cSrcweir 				MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
2195*cdf0e10cSrcweir 				aMtf.Insert( new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(),
2196*cdf0e10cSrcweir 													   pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ),
2197*cdf0e10cSrcweir 													   LIST_APPEND );
2198*cdf0e10cSrcweir 			}
2199*cdf0e10cSrcweir 			break;
2200*cdf0e10cSrcweir 
2201*cdf0e10cSrcweir 			case( META_BMPEXSCALEPART_ACTION ):
2202*cdf0e10cSrcweir 			{
2203*cdf0e10cSrcweir 				MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
2204*cdf0e10cSrcweir 				aMtf.Insert( new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
2205*cdf0e10cSrcweir 														   pAct->GetSrcPoint(), pAct->GetSrcSize(),
2206*cdf0e10cSrcweir 														   pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ),
2207*cdf0e10cSrcweir 														   LIST_APPEND );
2208*cdf0e10cSrcweir 			}
2209*cdf0e10cSrcweir 			break;
2210*cdf0e10cSrcweir 
2211*cdf0e10cSrcweir 			case( META_MASKSCALE_ACTION ):
2212*cdf0e10cSrcweir 			{
2213*cdf0e10cSrcweir 				MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction;
2214*cdf0e10cSrcweir 				aMtf.Insert( new MetaMaskScaleAction( pAct->GetPoint(), pAct->GetSize(),
2215*cdf0e10cSrcweir 													  pAct->GetBitmap(),
2216*cdf0e10cSrcweir 													  pFncCol( pAct->GetColor(), pColParam ) ),
2217*cdf0e10cSrcweir 													  LIST_APPEND );
2218*cdf0e10cSrcweir 			}
2219*cdf0e10cSrcweir 			break;
2220*cdf0e10cSrcweir 
2221*cdf0e10cSrcweir 			case( META_MASKSCALEPART_ACTION ):
2222*cdf0e10cSrcweir 			{
2223*cdf0e10cSrcweir 				MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
2224*cdf0e10cSrcweir 				aMtf.Insert( new MetaMaskScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
2225*cdf0e10cSrcweir 														  pAct->GetSrcPoint(), pAct->GetSrcSize(),
2226*cdf0e10cSrcweir 														  pAct->GetBitmap(),
2227*cdf0e10cSrcweir 														  pFncCol( pAct->GetColor(), pColParam ) ),
2228*cdf0e10cSrcweir 														  LIST_APPEND );
2229*cdf0e10cSrcweir 			}
2230*cdf0e10cSrcweir 			break;
2231*cdf0e10cSrcweir 
2232*cdf0e10cSrcweir 			case( META_GRADIENT_ACTION ):
2233*cdf0e10cSrcweir 			{
2234*cdf0e10cSrcweir 				MetaGradientAction* pAct = (MetaGradientAction*) pAction;
2235*cdf0e10cSrcweir 				Gradient			aGradient( pAct->GetGradient() );
2236*cdf0e10cSrcweir 
2237*cdf0e10cSrcweir 				aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
2238*cdf0e10cSrcweir 				aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
2239*cdf0e10cSrcweir 				aMtf.Insert( new MetaGradientAction( pAct->GetRect(), aGradient ), LIST_APPEND );
2240*cdf0e10cSrcweir 			}
2241*cdf0e10cSrcweir 			break;
2242*cdf0e10cSrcweir 
2243*cdf0e10cSrcweir 			case( META_GRADIENTEX_ACTION ):
2244*cdf0e10cSrcweir 			{
2245*cdf0e10cSrcweir 				MetaGradientExAction* pAct = (MetaGradientExAction*) pAction;
2246*cdf0e10cSrcweir 				Gradient			  aGradient( pAct->GetGradient() );
2247*cdf0e10cSrcweir 
2248*cdf0e10cSrcweir 				aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
2249*cdf0e10cSrcweir 				aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
2250*cdf0e10cSrcweir 				aMtf.Insert( new MetaGradientExAction( pAct->GetPolyPolygon(), aGradient ), LIST_APPEND );
2251*cdf0e10cSrcweir 			}
2252*cdf0e10cSrcweir 			break;
2253*cdf0e10cSrcweir 
2254*cdf0e10cSrcweir 			case( META_HATCH_ACTION ):
2255*cdf0e10cSrcweir 			{
2256*cdf0e10cSrcweir 				MetaHatchAction*	pAct = (MetaHatchAction*) pAction;
2257*cdf0e10cSrcweir 				Hatch				aHatch( pAct->GetHatch() );
2258*cdf0e10cSrcweir 
2259*cdf0e10cSrcweir 				aHatch.SetColor( pFncCol( aHatch.GetColor(), pColParam ) );
2260*cdf0e10cSrcweir 				aMtf.Insert( new MetaHatchAction( pAct->GetPolyPolygon(), aHatch ), LIST_APPEND );
2261*cdf0e10cSrcweir 			}
2262*cdf0e10cSrcweir 			break;
2263*cdf0e10cSrcweir 
2264*cdf0e10cSrcweir 			case( META_FLOATTRANSPARENT_ACTION ):
2265*cdf0e10cSrcweir 			{
2266*cdf0e10cSrcweir 				MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction;
2267*cdf0e10cSrcweir 				GDIMetaFile					aTransMtf( pAct->GetGDIMetaFile() );
2268*cdf0e10cSrcweir 
2269*cdf0e10cSrcweir 				aTransMtf.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam );
2270*cdf0e10cSrcweir 				aMtf.Insert( new MetaFloatTransparentAction( aTransMtf,
2271*cdf0e10cSrcweir 															 pAct->GetPoint(), pAct->GetSize(),
2272*cdf0e10cSrcweir 															 pAct->GetGradient() ),
2273*cdf0e10cSrcweir 															 LIST_APPEND );
2274*cdf0e10cSrcweir 			}
2275*cdf0e10cSrcweir 			break;
2276*cdf0e10cSrcweir 
2277*cdf0e10cSrcweir 			case( META_EPS_ACTION ):
2278*cdf0e10cSrcweir 			{
2279*cdf0e10cSrcweir 				MetaEPSAction*	pAct = (MetaEPSAction*) pAction;
2280*cdf0e10cSrcweir 				GDIMetaFile		aSubst( pAct->GetSubstitute() );
2281*cdf0e10cSrcweir 
2282*cdf0e10cSrcweir 				aSubst.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam );
2283*cdf0e10cSrcweir 				aMtf.Insert( new MetaEPSAction( pAct->GetPoint(), pAct->GetSize(),
2284*cdf0e10cSrcweir 												pAct->GetLink(), aSubst ),
2285*cdf0e10cSrcweir 												LIST_APPEND );
2286*cdf0e10cSrcweir 			}
2287*cdf0e10cSrcweir 			break;
2288*cdf0e10cSrcweir 
2289*cdf0e10cSrcweir             case( META_RENDERGRAPHIC_ACTION ):
2290*cdf0e10cSrcweir             {
2291*cdf0e10cSrcweir                 OSL_TRACE( "ExchangeColors not supported for RenderGraphic MetaActions yet" );
2292*cdf0e10cSrcweir 
2293*cdf0e10cSrcweir 				pAction->Duplicate();
2294*cdf0e10cSrcweir 				aMtf.Insert( pAction, LIST_APPEND );
2295*cdf0e10cSrcweir             }
2296*cdf0e10cSrcweir             break;
2297*cdf0e10cSrcweir 
2298*cdf0e10cSrcweir 			default:
2299*cdf0e10cSrcweir 			{
2300*cdf0e10cSrcweir 				pAction->Duplicate();
2301*cdf0e10cSrcweir 				aMtf.Insert( pAction, LIST_APPEND );
2302*cdf0e10cSrcweir 			}
2303*cdf0e10cSrcweir 			break;
2304*cdf0e10cSrcweir 		}
2305*cdf0e10cSrcweir 	}
2306*cdf0e10cSrcweir 
2307*cdf0e10cSrcweir 	*this = aMtf;
2308*cdf0e10cSrcweir }
2309*cdf0e10cSrcweir 
2310*cdf0e10cSrcweir // ------------------------------------------------------------------------
2311*cdf0e10cSrcweir 
2312*cdf0e10cSrcweir void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
2313*cdf0e10cSrcweir 						  short nChannelRPercent, short nChannelGPercent,
2314*cdf0e10cSrcweir 						  short nChannelBPercent, double fGamma, sal_Bool bInvert )
2315*cdf0e10cSrcweir {
2316*cdf0e10cSrcweir 	// nothing to do? => return quickly
2317*cdf0e10cSrcweir 	if( nLuminancePercent || nContrastPercent ||
2318*cdf0e10cSrcweir 		nChannelRPercent || nChannelGPercent || nChannelBPercent ||
2319*cdf0e10cSrcweir 		( fGamma != 1.0 ) || bInvert )
2320*cdf0e10cSrcweir 	{
2321*cdf0e10cSrcweir 		double				fM, fROff, fGOff, fBOff, fOff;
2322*cdf0e10cSrcweir 		ImplColAdjustParam	aColParam;
2323*cdf0e10cSrcweir 		ImplBmpAdjustParam	aBmpParam;
2324*cdf0e10cSrcweir 
2325*cdf0e10cSrcweir 		aColParam.pMapR = new sal_uInt8[ 256 ];
2326*cdf0e10cSrcweir 		aColParam.pMapG = new sal_uInt8[ 256 ];
2327*cdf0e10cSrcweir 		aColParam.pMapB = new sal_uInt8[ 256 ];
2328*cdf0e10cSrcweir 
2329*cdf0e10cSrcweir 		// calculate slope
2330*cdf0e10cSrcweir 		if( nContrastPercent >= 0 )
2331*cdf0e10cSrcweir 			fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) );
2332*cdf0e10cSrcweir 		else
2333*cdf0e10cSrcweir 			fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0;
2334*cdf0e10cSrcweir 
2335*cdf0e10cSrcweir 		// total offset = luminance offset + contrast offset
2336*cdf0e10cSrcweir 		fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
2337*cdf0e10cSrcweir 
2338*cdf0e10cSrcweir 		// channel offset = channel offset	+ total offset
2339*cdf0e10cSrcweir 		fROff = nChannelRPercent * 2.55 + fOff;
2340*cdf0e10cSrcweir 		fGOff = nChannelGPercent * 2.55 + fOff;
2341*cdf0e10cSrcweir 		fBOff = nChannelBPercent * 2.55 + fOff;
2342*cdf0e10cSrcweir 
2343*cdf0e10cSrcweir 		// calculate gamma value
2344*cdf0e10cSrcweir 		fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma );
2345*cdf0e10cSrcweir 		const sal_Bool bGamma = ( fGamma != 1.0 );
2346*cdf0e10cSrcweir 
2347*cdf0e10cSrcweir 		// create mapping table
2348*cdf0e10cSrcweir 		for( long nX = 0L; nX < 256L; nX++ )
2349*cdf0e10cSrcweir 		{
2350*cdf0e10cSrcweir 			aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
2351*cdf0e10cSrcweir 			aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
2352*cdf0e10cSrcweir 			aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
2353*cdf0e10cSrcweir 
2354*cdf0e10cSrcweir 			if( bGamma )
2355*cdf0e10cSrcweir 			{
2356*cdf0e10cSrcweir 				aColParam.pMapR[ nX ] = GAMMA( aColParam.pMapR[ nX ], fGamma );
2357*cdf0e10cSrcweir 				aColParam.pMapG[ nX ] = GAMMA( aColParam.pMapG[ nX ], fGamma );
2358*cdf0e10cSrcweir 				aColParam.pMapB[ nX ] = GAMMA( aColParam.pMapB[ nX ], fGamma );
2359*cdf0e10cSrcweir 			}
2360*cdf0e10cSrcweir 
2361*cdf0e10cSrcweir 			if( bInvert )
2362*cdf0e10cSrcweir 			{
2363*cdf0e10cSrcweir 				aColParam.pMapR[ nX ] = ~aColParam.pMapR[ nX ];
2364*cdf0e10cSrcweir 				aColParam.pMapG[ nX ] = ~aColParam.pMapG[ nX ];
2365*cdf0e10cSrcweir 				aColParam.pMapB[ nX ] = ~aColParam.pMapB[ nX ];
2366*cdf0e10cSrcweir 			}
2367*cdf0e10cSrcweir 		}
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir 		aBmpParam.nLuminancePercent = nLuminancePercent;
2370*cdf0e10cSrcweir 		aBmpParam.nContrastPercent = nContrastPercent;
2371*cdf0e10cSrcweir 		aBmpParam.nChannelRPercent = nChannelRPercent;
2372*cdf0e10cSrcweir 		aBmpParam.nChannelGPercent = nChannelGPercent;
2373*cdf0e10cSrcweir 		aBmpParam.nChannelBPercent = nChannelBPercent;
2374*cdf0e10cSrcweir 		aBmpParam.fGamma = fGamma;
2375*cdf0e10cSrcweir 		aBmpParam.bInvert = bInvert;
2376*cdf0e10cSrcweir 
2377*cdf0e10cSrcweir 		// do color adjustment
2378*cdf0e10cSrcweir 		ImplExchangeColors( ImplColAdjustFnc, &aColParam, ImplBmpAdjustFnc, &aBmpParam );
2379*cdf0e10cSrcweir 
2380*cdf0e10cSrcweir 		delete[] aColParam.pMapR;
2381*cdf0e10cSrcweir 		delete[] aColParam.pMapG;
2382*cdf0e10cSrcweir 		delete[] aColParam.pMapB;
2383*cdf0e10cSrcweir 	}
2384*cdf0e10cSrcweir }
2385*cdf0e10cSrcweir 
2386*cdf0e10cSrcweir // ------------------------------------------------------------------------
2387*cdf0e10cSrcweir 
2388*cdf0e10cSrcweir void GDIMetaFile::Convert( MtfConversion eConversion )
2389*cdf0e10cSrcweir {
2390*cdf0e10cSrcweir 	// nothing to do? => return quickly
2391*cdf0e10cSrcweir 	if( eConversion != MTF_CONVERSION_NONE )
2392*cdf0e10cSrcweir 	{
2393*cdf0e10cSrcweir 		ImplColConvertParam	aColParam;
2394*cdf0e10cSrcweir 		ImplBmpConvertParam	aBmpParam;
2395*cdf0e10cSrcweir 
2396*cdf0e10cSrcweir 		aColParam.eConversion = eConversion;
2397*cdf0e10cSrcweir 		aBmpParam.eConversion = ( MTF_CONVERSION_1BIT_THRESHOLD == eConversion ) ? BMP_CONVERSION_1BIT_THRESHOLD : BMP_CONVERSION_8BIT_GREYS;
2398*cdf0e10cSrcweir 
2399*cdf0e10cSrcweir 		ImplExchangeColors( ImplColConvertFnc, &aColParam, ImplBmpConvertFnc, &aBmpParam );
2400*cdf0e10cSrcweir 	}
2401*cdf0e10cSrcweir }
2402*cdf0e10cSrcweir 
2403*cdf0e10cSrcweir // ------------------------------------------------------------------------
2404*cdf0e10cSrcweir 
2405*cdf0e10cSrcweir void GDIMetaFile::ReplaceColors( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
2406*cdf0e10cSrcweir {
2407*cdf0e10cSrcweir 	ReplaceColors( &rSearchColor, &rReplaceColor, 1, &nTol );
2408*cdf0e10cSrcweir }
2409*cdf0e10cSrcweir 
2410*cdf0e10cSrcweir // ------------------------------------------------------------------------
2411*cdf0e10cSrcweir 
2412*cdf0e10cSrcweir void GDIMetaFile::ReplaceColors( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, sal_uLong* pTols )
2413*cdf0e10cSrcweir {
2414*cdf0e10cSrcweir 	ImplColReplaceParam aColParam;
2415*cdf0e10cSrcweir 	ImplBmpReplaceParam aBmpParam;
2416*cdf0e10cSrcweir 
2417*cdf0e10cSrcweir 	aColParam.pMinR = new sal_uLong[ nColorCount ];
2418*cdf0e10cSrcweir 	aColParam.pMaxR = new sal_uLong[ nColorCount ];
2419*cdf0e10cSrcweir 	aColParam.pMinG = new sal_uLong[ nColorCount ];
2420*cdf0e10cSrcweir 	aColParam.pMaxG = new sal_uLong[ nColorCount ];
2421*cdf0e10cSrcweir 	aColParam.pMinB = new sal_uLong[ nColorCount ];
2422*cdf0e10cSrcweir 	aColParam.pMaxB = new sal_uLong[ nColorCount ];
2423*cdf0e10cSrcweir 
2424*cdf0e10cSrcweir 	for( sal_uLong i = 0; i < nColorCount; i++ )
2425*cdf0e10cSrcweir 	{
2426*cdf0e10cSrcweir 		const long	nTol = pTols ? ( pTols[ i ] * 255 ) / 100 : 0;
2427*cdf0e10cSrcweir 		long		nVal;
2428*cdf0e10cSrcweir 
2429*cdf0e10cSrcweir 		nVal = pSearchColors[ i ].GetRed();
2430*cdf0e10cSrcweir 		aColParam.pMinR[ i ] = (sal_uLong) Max( nVal - nTol, 0L );
2431*cdf0e10cSrcweir 		aColParam.pMaxR[ i ] = (sal_uLong) Min( nVal + nTol, 255L );
2432*cdf0e10cSrcweir 
2433*cdf0e10cSrcweir 		nVal = pSearchColors[ i ].GetGreen();
2434*cdf0e10cSrcweir 		aColParam.pMinG[ i ] = (sal_uLong) Max( nVal - nTol, 0L );
2435*cdf0e10cSrcweir 		aColParam.pMaxG[ i ] = (sal_uLong) Min( nVal + nTol, 255L );
2436*cdf0e10cSrcweir 
2437*cdf0e10cSrcweir 		nVal = pSearchColors[ i ].GetBlue();
2438*cdf0e10cSrcweir 		aColParam.pMinB[ i ] = (sal_uLong) Max( nVal - nTol, 0L );
2439*cdf0e10cSrcweir 		aColParam.pMaxB[ i ] = (sal_uLong) Min( nVal + nTol, 255L );
2440*cdf0e10cSrcweir 	}
2441*cdf0e10cSrcweir 
2442*cdf0e10cSrcweir 	aColParam.pDstCols = pReplaceColors;
2443*cdf0e10cSrcweir 	aColParam.nCount = nColorCount;
2444*cdf0e10cSrcweir 
2445*cdf0e10cSrcweir 	aBmpParam.pSrcCols = pSearchColors;
2446*cdf0e10cSrcweir 	aBmpParam.pDstCols = pReplaceColors;
2447*cdf0e10cSrcweir 	aBmpParam.nCount = nColorCount;
2448*cdf0e10cSrcweir 	aBmpParam.pTols = pTols;
2449*cdf0e10cSrcweir 
2450*cdf0e10cSrcweir 	ImplExchangeColors( ImplColReplaceFnc, &aColParam, ImplBmpReplaceFnc, &aBmpParam );
2451*cdf0e10cSrcweir 
2452*cdf0e10cSrcweir 	delete[] aColParam.pMinR;
2453*cdf0e10cSrcweir 	delete[] aColParam.pMaxR;
2454*cdf0e10cSrcweir 	delete[] aColParam.pMinG;
2455*cdf0e10cSrcweir 	delete[] aColParam.pMaxG;
2456*cdf0e10cSrcweir 	delete[] aColParam.pMinB;
2457*cdf0e10cSrcweir 	delete[] aColParam.pMaxB;
2458*cdf0e10cSrcweir };
2459*cdf0e10cSrcweir 
2460*cdf0e10cSrcweir // ------------------------------------------------------------------------
2461*cdf0e10cSrcweir 
2462*cdf0e10cSrcweir GDIMetaFile GDIMetaFile::GetMonochromeMtf( const Color& rColor ) const
2463*cdf0e10cSrcweir {
2464*cdf0e10cSrcweir 	GDIMetaFile aRet( *this );
2465*cdf0e10cSrcweir 
2466*cdf0e10cSrcweir 	ImplColMonoParam	aColParam;
2467*cdf0e10cSrcweir 	ImplBmpMonoParam	aBmpParam;
2468*cdf0e10cSrcweir 
2469*cdf0e10cSrcweir 	aColParam.aColor = rColor;
2470*cdf0e10cSrcweir 	aBmpParam.aColor = rColor;
2471*cdf0e10cSrcweir 
2472*cdf0e10cSrcweir 	aRet.ImplExchangeColors( ImplColMonoFnc, &aColParam, ImplBmpMonoFnc, &aBmpParam );
2473*cdf0e10cSrcweir 
2474*cdf0e10cSrcweir 	return aRet;
2475*cdf0e10cSrcweir }
2476*cdf0e10cSrcweir 
2477*cdf0e10cSrcweir // ------------------------------------------------------------------------
2478*cdf0e10cSrcweir 
2479*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetChecksum() const
2480*cdf0e10cSrcweir {
2481*cdf0e10cSrcweir 	GDIMetaFile			aMtf;
2482*cdf0e10cSrcweir 	SvMemoryStream		aMemStm( 65535, 65535 );
2483*cdf0e10cSrcweir 	ImplMetaWriteData	aWriteData;
2484*cdf0e10cSrcweir 	SVBT16				aBT16;
2485*cdf0e10cSrcweir 	SVBT32				aBT32;
2486*cdf0e10cSrcweir 	sal_uLong				nCrc = 0;
2487*cdf0e10cSrcweir 
2488*cdf0e10cSrcweir 	aWriteData.meActualCharSet = aMemStm.GetStreamCharSet();
2489*cdf0e10cSrcweir 
2490*cdf0e10cSrcweir 	for( sal_uLong i = 0, nObjCount = GetActionCount(); i < nObjCount; i++ )
2491*cdf0e10cSrcweir 	{
2492*cdf0e10cSrcweir 		MetaAction* pAction = GetAction( i );
2493*cdf0e10cSrcweir 
2494*cdf0e10cSrcweir 		switch( pAction->GetType() )
2495*cdf0e10cSrcweir 		{
2496*cdf0e10cSrcweir 			case( META_BMP_ACTION ):
2497*cdf0e10cSrcweir 			{
2498*cdf0e10cSrcweir 				MetaBmpAction* pAct = (MetaBmpAction*) pAction;
2499*cdf0e10cSrcweir 
2500*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2501*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2502*cdf0e10cSrcweir 
2503*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
2504*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2505*cdf0e10cSrcweir 
2506*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2507*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2508*cdf0e10cSrcweir 
2509*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2510*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2511*cdf0e10cSrcweir 			}
2512*cdf0e10cSrcweir 			break;
2513*cdf0e10cSrcweir 
2514*cdf0e10cSrcweir 			case( META_BMPSCALE_ACTION ):
2515*cdf0e10cSrcweir 			{
2516*cdf0e10cSrcweir 				MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
2517*cdf0e10cSrcweir 
2518*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2519*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2520*cdf0e10cSrcweir 
2521*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
2522*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2523*cdf0e10cSrcweir 
2524*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2525*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2526*cdf0e10cSrcweir 
2527*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2528*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2529*cdf0e10cSrcweir 
2530*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 );
2531*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2532*cdf0e10cSrcweir 
2533*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 );
2534*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2535*cdf0e10cSrcweir 			}
2536*cdf0e10cSrcweir 			break;
2537*cdf0e10cSrcweir 
2538*cdf0e10cSrcweir 			case( META_BMPSCALEPART_ACTION ):
2539*cdf0e10cSrcweir 			{
2540*cdf0e10cSrcweir 				MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
2541*cdf0e10cSrcweir 
2542*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2543*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2544*cdf0e10cSrcweir 
2545*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
2546*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2547*cdf0e10cSrcweir 
2548*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 );
2549*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2550*cdf0e10cSrcweir 
2551*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
2552*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2553*cdf0e10cSrcweir 
2554*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 );
2555*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2556*cdf0e10cSrcweir 
2557*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 );
2558*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2559*cdf0e10cSrcweir 
2560*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
2561*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2562*cdf0e10cSrcweir 
2563*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
2564*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2565*cdf0e10cSrcweir 
2566*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
2567*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2568*cdf0e10cSrcweir 
2569*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
2570*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2571*cdf0e10cSrcweir 			}
2572*cdf0e10cSrcweir 			break;
2573*cdf0e10cSrcweir 
2574*cdf0e10cSrcweir 			case( META_BMPEX_ACTION ):
2575*cdf0e10cSrcweir 			{
2576*cdf0e10cSrcweir 				MetaBmpExAction* pAct = (MetaBmpExAction*) pAction;
2577*cdf0e10cSrcweir 
2578*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2579*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2580*cdf0e10cSrcweir 
2581*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 );
2582*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2583*cdf0e10cSrcweir 
2584*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2585*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2586*cdf0e10cSrcweir 
2587*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2588*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2589*cdf0e10cSrcweir 			}
2590*cdf0e10cSrcweir 			break;
2591*cdf0e10cSrcweir 
2592*cdf0e10cSrcweir 			case( META_BMPEXSCALE_ACTION ):
2593*cdf0e10cSrcweir 			{
2594*cdf0e10cSrcweir 				MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
2595*cdf0e10cSrcweir 
2596*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2597*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2598*cdf0e10cSrcweir 
2599*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 );
2600*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2601*cdf0e10cSrcweir 
2602*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2603*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2604*cdf0e10cSrcweir 
2605*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2606*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2607*cdf0e10cSrcweir 
2608*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 );
2609*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2610*cdf0e10cSrcweir 
2611*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 );
2612*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2613*cdf0e10cSrcweir 			}
2614*cdf0e10cSrcweir 			break;
2615*cdf0e10cSrcweir 
2616*cdf0e10cSrcweir 			case( META_BMPEXSCALEPART_ACTION ):
2617*cdf0e10cSrcweir 			{
2618*cdf0e10cSrcweir 				MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
2619*cdf0e10cSrcweir 
2620*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2621*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2622*cdf0e10cSrcweir 
2623*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 );
2624*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2625*cdf0e10cSrcweir 
2626*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 );
2627*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2628*cdf0e10cSrcweir 
2629*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
2630*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2631*cdf0e10cSrcweir 
2632*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 );
2633*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2634*cdf0e10cSrcweir 
2635*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 );
2636*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2637*cdf0e10cSrcweir 
2638*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
2639*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2640*cdf0e10cSrcweir 
2641*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
2642*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2643*cdf0e10cSrcweir 
2644*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
2645*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2646*cdf0e10cSrcweir 
2647*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
2648*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2649*cdf0e10cSrcweir 			}
2650*cdf0e10cSrcweir 			break;
2651*cdf0e10cSrcweir 
2652*cdf0e10cSrcweir 			case( META_MASK_ACTION ):
2653*cdf0e10cSrcweir 			{
2654*cdf0e10cSrcweir 				MetaMaskAction* pAct = (MetaMaskAction*) pAction;
2655*cdf0e10cSrcweir 
2656*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2657*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2658*cdf0e10cSrcweir 
2659*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
2660*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2661*cdf0e10cSrcweir 
2662*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 );
2663*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2664*cdf0e10cSrcweir 
2665*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2666*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2667*cdf0e10cSrcweir 
2668*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2669*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2670*cdf0e10cSrcweir 			}
2671*cdf0e10cSrcweir 			break;
2672*cdf0e10cSrcweir 
2673*cdf0e10cSrcweir 			case( META_MASKSCALE_ACTION ):
2674*cdf0e10cSrcweir 			{
2675*cdf0e10cSrcweir 				MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction;
2676*cdf0e10cSrcweir 
2677*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2678*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2679*cdf0e10cSrcweir 
2680*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
2681*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2682*cdf0e10cSrcweir 
2683*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 );
2684*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2685*cdf0e10cSrcweir 
2686*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2687*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2688*cdf0e10cSrcweir 
2689*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2690*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2691*cdf0e10cSrcweir 
2692*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 );
2693*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2694*cdf0e10cSrcweir 
2695*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 );
2696*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2697*cdf0e10cSrcweir 			}
2698*cdf0e10cSrcweir 			break;
2699*cdf0e10cSrcweir 
2700*cdf0e10cSrcweir 			case( META_MASKSCALEPART_ACTION ):
2701*cdf0e10cSrcweir 			{
2702*cdf0e10cSrcweir 				MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
2703*cdf0e10cSrcweir 
2704*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2705*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2706*cdf0e10cSrcweir 
2707*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 );
2708*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2709*cdf0e10cSrcweir 
2710*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 );
2711*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2712*cdf0e10cSrcweir 
2713*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 );
2714*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2715*cdf0e10cSrcweir 
2716*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
2717*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2718*cdf0e10cSrcweir 
2719*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 );
2720*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2721*cdf0e10cSrcweir 
2722*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 );
2723*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2724*cdf0e10cSrcweir 
2725*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
2726*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2727*cdf0e10cSrcweir 
2728*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
2729*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2730*cdf0e10cSrcweir 
2731*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
2732*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2733*cdf0e10cSrcweir 
2734*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
2735*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2736*cdf0e10cSrcweir 			}
2737*cdf0e10cSrcweir 			break;
2738*cdf0e10cSrcweir 
2739*cdf0e10cSrcweir 			case META_EPS_ACTION :
2740*cdf0e10cSrcweir 			{
2741*cdf0e10cSrcweir 				MetaEPSAction* pAct = (MetaEPSAction*) pAction;
2742*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, pAct->GetLink().GetData(), pAct->GetLink().GetDataSize() );
2743*cdf0e10cSrcweir 			}
2744*cdf0e10cSrcweir 			break;
2745*cdf0e10cSrcweir 
2746*cdf0e10cSrcweir             case( META_RENDERGRAPHIC_ACTION ):
2747*cdf0e10cSrcweir             {
2748*cdf0e10cSrcweir                 MetaRenderGraphicAction*    pAct = (MetaRenderGraphicAction*) pAction;
2749*cdf0e10cSrcweir 				const ::vcl::RenderGraphic& rRenderGraphic = pAct->GetRenderGraphic();
2750*cdf0e10cSrcweir 
2751*cdf0e10cSrcweir 				ShortToSVBT16( pAct->GetType(), aBT16 );
2752*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT16, 2 );
2753*cdf0e10cSrcweir 
2754*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, rRenderGraphic.GetGraphicData().get(), rRenderGraphic.GetGraphicDataLength() );
2755*cdf0e10cSrcweir 
2756*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2757*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2758*cdf0e10cSrcweir 
2759*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2760*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2761*cdf0e10cSrcweir 
2762*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 );
2763*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2764*cdf0e10cSrcweir 
2765*cdf0e10cSrcweir 				UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 );
2766*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aBT32, 4 );
2767*cdf0e10cSrcweir             }
2768*cdf0e10cSrcweir             break;
2769*cdf0e10cSrcweir 
2770*cdf0e10cSrcweir 			default:
2771*cdf0e10cSrcweir 			{
2772*cdf0e10cSrcweir 				pAction->Write( aMemStm, &aWriteData );
2773*cdf0e10cSrcweir 				nCrc = rtl_crc32( nCrc, aMemStm.GetData(), aMemStm.Tell() );
2774*cdf0e10cSrcweir 				aMemStm.Seek( 0 );
2775*cdf0e10cSrcweir 			}
2776*cdf0e10cSrcweir 			break;
2777*cdf0e10cSrcweir 		}
2778*cdf0e10cSrcweir 	}
2779*cdf0e10cSrcweir 
2780*cdf0e10cSrcweir 	return nCrc;
2781*cdf0e10cSrcweir }
2782*cdf0e10cSrcweir 
2783*cdf0e10cSrcweir // ------------------------------------------------------------------------
2784*cdf0e10cSrcweir 
2785*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetSizeBytes() const
2786*cdf0e10cSrcweir {
2787*cdf0e10cSrcweir     sal_uLong nSizeBytes = 0;
2788*cdf0e10cSrcweir 
2789*cdf0e10cSrcweir     for( sal_uLong i = 0, nObjCount = GetActionCount(); i < nObjCount; ++i )
2790*cdf0e10cSrcweir     {
2791*cdf0e10cSrcweir         MetaAction* pAction = GetAction( i );
2792*cdf0e10cSrcweir 
2793*cdf0e10cSrcweir         // default action size is set to 32 (=> not the exact value)
2794*cdf0e10cSrcweir         nSizeBytes += 32;
2795*cdf0e10cSrcweir 
2796*cdf0e10cSrcweir         // add sizes for large action content
2797*cdf0e10cSrcweir         switch( pAction->GetType() )
2798*cdf0e10cSrcweir         {
2799*cdf0e10cSrcweir             case( META_BMP_ACTION ): nSizeBytes += ( (MetaBmpAction*) pAction )->GetBitmap().GetSizeBytes(); break;
2800*cdf0e10cSrcweir             case( META_BMPSCALE_ACTION ): nSizeBytes += ( (MetaBmpScaleAction*) pAction )->GetBitmap().GetSizeBytes(); break;
2801*cdf0e10cSrcweir             case( META_BMPSCALEPART_ACTION ): nSizeBytes += ( (MetaBmpScalePartAction*) pAction )->GetBitmap().GetSizeBytes(); break;
2802*cdf0e10cSrcweir 
2803*cdf0e10cSrcweir             case( META_BMPEX_ACTION ): nSizeBytes += ( (MetaBmpExAction*) pAction )->GetBitmapEx().GetSizeBytes(); break;
2804*cdf0e10cSrcweir             case( META_BMPEXSCALE_ACTION ): nSizeBytes += ( (MetaBmpExScaleAction*) pAction )->GetBitmapEx().GetSizeBytes(); break;
2805*cdf0e10cSrcweir             case( META_BMPEXSCALEPART_ACTION ): nSizeBytes += ( (MetaBmpExScalePartAction*) pAction )->GetBitmapEx().GetSizeBytes(); break;
2806*cdf0e10cSrcweir 
2807*cdf0e10cSrcweir             case( META_MASK_ACTION ): nSizeBytes += ( (MetaMaskAction*) pAction )->GetBitmap().GetSizeBytes(); break;
2808*cdf0e10cSrcweir             case( META_MASKSCALE_ACTION ): nSizeBytes += ( (MetaMaskScaleAction*) pAction )->GetBitmap().GetSizeBytes(); break;
2809*cdf0e10cSrcweir             case( META_MASKSCALEPART_ACTION ): nSizeBytes += ( (MetaMaskScalePartAction*) pAction )->GetBitmap().GetSizeBytes(); break;
2810*cdf0e10cSrcweir 
2811*cdf0e10cSrcweir             case( META_POLYLINE_ACTION ): nSizeBytes += ( ( (MetaPolyLineAction*) pAction )->GetPolygon().GetSize() * sizeof( Point ) ); break;
2812*cdf0e10cSrcweir             case( META_POLYGON_ACTION ): nSizeBytes += ( ( (MetaPolygonAction*) pAction )->GetPolygon().GetSize() * sizeof( Point ) ); break;
2813*cdf0e10cSrcweir             case( META_POLYPOLYGON_ACTION ):
2814*cdf0e10cSrcweir             {
2815*cdf0e10cSrcweir                 const PolyPolygon& rPolyPoly = ( (MetaPolyPolygonAction*) pAction )->GetPolyPolygon();
2816*cdf0e10cSrcweir 
2817*cdf0e10cSrcweir                 for( sal_uInt16 n = 0; n < rPolyPoly.Count(); ++n )
2818*cdf0e10cSrcweir                     nSizeBytes += ( rPolyPoly[ n ].GetSize() * sizeof( Point ) );
2819*cdf0e10cSrcweir             }
2820*cdf0e10cSrcweir             break;
2821*cdf0e10cSrcweir 
2822*cdf0e10cSrcweir             case( META_TEXT_ACTION ): nSizeBytes += ( ( (MetaTextAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break;
2823*cdf0e10cSrcweir             case( META_STRETCHTEXT_ACTION ): nSizeBytes += ( ( (MetaStretchTextAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break;
2824*cdf0e10cSrcweir             case( META_TEXTRECT_ACTION ): nSizeBytes += ( ( (MetaTextRectAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break;
2825*cdf0e10cSrcweir             case( META_TEXTARRAY_ACTION ):
2826*cdf0e10cSrcweir             {
2827*cdf0e10cSrcweir                 MetaTextArrayAction* pTextArrayAction = (MetaTextArrayAction*) pAction;
2828*cdf0e10cSrcweir 
2829*cdf0e10cSrcweir                 nSizeBytes += ( pTextArrayAction->GetText().Len() * sizeof( sal_Unicode ) );
2830*cdf0e10cSrcweir 
2831*cdf0e10cSrcweir                 if( pTextArrayAction->GetDXArray() )
2832*cdf0e10cSrcweir                     nSizeBytes += ( pTextArrayAction->GetLen() << 2 );
2833*cdf0e10cSrcweir             }
2834*cdf0e10cSrcweir             break;
2835*cdf0e10cSrcweir 
2836*cdf0e10cSrcweir             case( META_RENDERGRAPHIC_ACTION ): nSizeBytes += ( ( (MetaRenderGraphicAction*) pAction )->GetRenderGraphic() ).GetGraphicDataLength(); break;
2837*cdf0e10cSrcweir         }
2838*cdf0e10cSrcweir     }
2839*cdf0e10cSrcweir 
2840*cdf0e10cSrcweir     return( nSizeBytes );
2841*cdf0e10cSrcweir }
2842*cdf0e10cSrcweir 
2843*cdf0e10cSrcweir // ------------------------------------------------------------------------
2844*cdf0e10cSrcweir 
2845*cdf0e10cSrcweir SvStream& operator>>( SvStream& rIStm, GDIMetaFile& rGDIMetaFile )
2846*cdf0e10cSrcweir {
2847*cdf0e10cSrcweir 	if( !rIStm.GetError() )
2848*cdf0e10cSrcweir 	{
2849*cdf0e10cSrcweir 		char	aId[ 7 ];
2850*cdf0e10cSrcweir 		sal_uLong	nStmPos = rIStm.Tell();
2851*cdf0e10cSrcweir 		sal_uInt16	nOldFormat = rIStm.GetNumberFormatInt();
2852*cdf0e10cSrcweir 
2853*cdf0e10cSrcweir 		rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
2854*cdf0e10cSrcweir 
2855*cdf0e10cSrcweir 		aId[ 0 ] = 0;
2856*cdf0e10cSrcweir 		aId[ 6 ] = 0;
2857*cdf0e10cSrcweir 		rIStm.Read( aId, 6 );
2858*cdf0e10cSrcweir 
2859*cdf0e10cSrcweir 		if ( !strcmp( aId, "VCLMTF" ) )
2860*cdf0e10cSrcweir 		{
2861*cdf0e10cSrcweir 			// new format
2862*cdf0e10cSrcweir 			VersionCompat*	pCompat;
2863*cdf0e10cSrcweir 			MetaAction* 	pAction;
2864*cdf0e10cSrcweir 			sal_uInt32		nStmCompressMode = 0;
2865*cdf0e10cSrcweir 			sal_uInt32		nCount = 0;
2866*cdf0e10cSrcweir 			sal_uInt8		bRenderGraphicReplacements = 0;
2867*cdf0e10cSrcweir 
2868*cdf0e10cSrcweir 			pCompat = new VersionCompat( rIStm, STREAM_READ );
2869*cdf0e10cSrcweir 			{
2870*cdf0e10cSrcweir 				// version 1
2871*cdf0e10cSrcweir 				rIStm >> nStmCompressMode;
2872*cdf0e10cSrcweir 				rIStm >> rGDIMetaFile.aPrefMapMode;
2873*cdf0e10cSrcweir 				rIStm >> rGDIMetaFile.aPrefSize;
2874*cdf0e10cSrcweir 				rIStm >> nCount;
2875*cdf0e10cSrcweir 
2876*cdf0e10cSrcweir 				if( pCompat->GetVersion() >= 2 )
2877*cdf0e10cSrcweir 				{
2878*cdf0e10cSrcweir 					// version 2
2879*cdf0e10cSrcweir 					// =========
2880*cdf0e10cSrcweir 					// contains an additional flag to indicate that RenderGraphic
2881*cdf0e10cSrcweir 					// actions are immediately followed by a replacement image, that
2882*cdf0e10cSrcweir 					// needs to be skipped in case the flag is set (KA 01/2011)
2883*cdf0e10cSrcweir 
2884*cdf0e10cSrcweir 					rIStm >> bRenderGraphicReplacements;
2885*cdf0e10cSrcweir 				}
2886*cdf0e10cSrcweir 			}
2887*cdf0e10cSrcweir 			delete pCompat;
2888*cdf0e10cSrcweir 
2889*cdf0e10cSrcweir 			ImplMetaReadData aReadData;
2890*cdf0e10cSrcweir 			aReadData.meActualCharSet = rIStm.GetStreamCharSet();
2891*cdf0e10cSrcweir 
2892*cdf0e10cSrcweir 			for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); ++nAction )
2893*cdf0e10cSrcweir 			{
2894*cdf0e10cSrcweir 				pAction = MetaAction::ReadMetaAction( rIStm, &aReadData );
2895*cdf0e10cSrcweir 
2896*cdf0e10cSrcweir 				if( pAction )
2897*cdf0e10cSrcweir 				{
2898*cdf0e10cSrcweir 					rGDIMetaFile.AddAction( pAction );
2899*cdf0e10cSrcweir 
2900*cdf0e10cSrcweir 					// if the MetaFile was written in RenderGraphics replacement mode
2901*cdf0e10cSrcweir 					// and we just read a RenderGraphic action, skip the following
2902*cdf0e10cSrcweir 					// META_BMPEXSCALE_ACTION, since this is the replacement image,
2903*cdf0e10cSrcweir 					// just needed for old implementations; don't forget to increment
2904*cdf0e10cSrcweir 					// the action read counter! (KA 01/2011)
2905*cdf0e10cSrcweir 					if( bRenderGraphicReplacements &&
2906*cdf0e10cSrcweir 						( META_RENDERGRAPHIC_ACTION == pAction->GetType() ) &&
2907*cdf0e10cSrcweir 						( ++nAction < nCount ) && !rIStm.IsEof() )
2908*cdf0e10cSrcweir 					{
2909*cdf0e10cSrcweir 						sal_uInt16 nFollowingType;
2910*cdf0e10cSrcweir 
2911*cdf0e10cSrcweir 						// dummy read of the next following META_BMPEXSCALE_ACTION
2912*cdf0e10cSrcweir 						// RenderGraphic replacement action (KA 01/2011)
2913*cdf0e10cSrcweir 						rIStm >> nFollowingType;
2914*cdf0e10cSrcweir 						delete ( new VersionCompat( rIStm, STREAM_READ ) );
2915*cdf0e10cSrcweir 
2916*cdf0e10cSrcweir 						OSL_ENSURE( META_BMPEXSCALE_ACTION == nFollowingType, \
2917*cdf0e10cSrcweir "META_RENDERGRAPHIC_ACTION read in RenderGraphic replacement mode \
2918*cdf0e10cSrcweir without following META_BMPEXSCALE_ACTION replacement" );
2919*cdf0e10cSrcweir 					}
2920*cdf0e10cSrcweir 				}
2921*cdf0e10cSrcweir 			}
2922*cdf0e10cSrcweir 		}
2923*cdf0e10cSrcweir 		else
2924*cdf0e10cSrcweir 		{
2925*cdf0e10cSrcweir 			// to avoid possible compiler optimizations => new/delete
2926*cdf0e10cSrcweir 			rIStm.Seek( nStmPos );
2927*cdf0e10cSrcweir 			delete( new SVMConverter( rIStm, rGDIMetaFile, CONVERT_FROM_SVM1 ) );
2928*cdf0e10cSrcweir 		}
2929*cdf0e10cSrcweir 
2930*cdf0e10cSrcweir 		// check for errors
2931*cdf0e10cSrcweir 		if( rIStm.GetError() )
2932*cdf0e10cSrcweir 		{
2933*cdf0e10cSrcweir 			rGDIMetaFile.Clear();
2934*cdf0e10cSrcweir 			rIStm.Seek( nStmPos );
2935*cdf0e10cSrcweir 		}
2936*cdf0e10cSrcweir 
2937*cdf0e10cSrcweir 		rIStm.SetNumberFormatInt( nOldFormat );
2938*cdf0e10cSrcweir 	}
2939*cdf0e10cSrcweir 
2940*cdf0e10cSrcweir 	return rIStm;
2941*cdf0e10cSrcweir }
2942*cdf0e10cSrcweir 
2943*cdf0e10cSrcweir // ------------------------------------------------------------------------
2944*cdf0e10cSrcweir 
2945*cdf0e10cSrcweir SvStream& operator<<( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile )
2946*cdf0e10cSrcweir {
2947*cdf0e10cSrcweir 	if( !rOStm.GetError() )
2948*cdf0e10cSrcweir 	{
2949*cdf0e10cSrcweir         static const char*  pEnableSVM1 = getenv( "SAL_ENABLE_SVM1" );
2950*cdf0e10cSrcweir         static const bool   bNoSVM1 = (NULL == pEnableSVM1 ) || ( '0' == *pEnableSVM1 );
2951*cdf0e10cSrcweir 
2952*cdf0e10cSrcweir         if( bNoSVM1 || rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50  )
2953*cdf0e10cSrcweir         {
2954*cdf0e10cSrcweir             const_cast< GDIMetaFile& >( rGDIMetaFile ).Write( rOStm );
2955*cdf0e10cSrcweir         }
2956*cdf0e10cSrcweir         else
2957*cdf0e10cSrcweir         {
2958*cdf0e10cSrcweir             delete( new SVMConverter( rOStm, const_cast< GDIMetaFile& >( rGDIMetaFile ), CONVERT_TO_SVM1 ) );
2959*cdf0e10cSrcweir         }
2960*cdf0e10cSrcweir 
2961*cdf0e10cSrcweir #ifdef DEBUG
2962*cdf0e10cSrcweir         if( !bNoSVM1 && rOStm.GetVersion() < SOFFICE_FILEFORMAT_50 )
2963*cdf0e10cSrcweir         {
2964*cdf0e10cSrcweir OSL_TRACE( \
2965*cdf0e10cSrcweir "GDIMetaFile would normally be written in old SVM1 format by this call. \
2966*cdf0e10cSrcweir The current implementation always writes in VCLMTF format. \
2967*cdf0e10cSrcweir Please set environment variable SAL_ENABLE_SVM1 to '1' to reenable old behavior" );
2968*cdf0e10cSrcweir 		}
2969*cdf0e10cSrcweir #endif // DEBUG
2970*cdf0e10cSrcweir 	}
2971*cdf0e10cSrcweir 
2972*cdf0e10cSrcweir 	return rOStm;
2973*cdf0e10cSrcweir }
2974*cdf0e10cSrcweir 
2975*cdf0e10cSrcweir // ------------------------------------------------------------------------
2976*cdf0e10cSrcweir 
2977*cdf0e10cSrcweir SvStream& GDIMetaFile::Read( SvStream& rIStm )
2978*cdf0e10cSrcweir {
2979*cdf0e10cSrcweir 	Clear();
2980*cdf0e10cSrcweir 	rIStm >> *this;
2981*cdf0e10cSrcweir 
2982*cdf0e10cSrcweir 	return rIStm;
2983*cdf0e10cSrcweir }
2984*cdf0e10cSrcweir 
2985*cdf0e10cSrcweir // ------------------------------------------------------------------------
2986*cdf0e10cSrcweir 
2987*cdf0e10cSrcweir SvStream& GDIMetaFile::Write( SvStream& rOStm, GDIMetaFileWriteFlags nWriteFlags )
2988*cdf0e10cSrcweir {
2989*cdf0e10cSrcweir 	VersionCompat*	pCompat;
2990*cdf0e10cSrcweir 	const sal_uInt32    nStmCompressMode = rOStm.GetCompressMode();
2991*cdf0e10cSrcweir 	sal_uInt16		    nOldFormat = rOStm.GetNumberFormatInt();
2992*cdf0e10cSrcweir 	const 			    sal_uInt8 bRenderGraphicReplacements =
2993*cdf0e10cSrcweir 								( ( ( GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC & nWriteFlags ) != 0 ) ? 1 : 0 );
2994*cdf0e10cSrcweir 
2995*cdf0e10cSrcweir 	// With the introduction of the META_RENDERGRAPHIC_ACTION, it is neccessary
2996*cdf0e10cSrcweir 	// to provide some kind of document backward compatibility:
2997*cdf0e10cSrcweir 	//
2998*cdf0e10cSrcweir 	//	If the flag GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set in
2999*cdf0e10cSrcweir 	//	parameter nWriteFlags, each META_RENDERGRAPHIC_ACTION is followed by
3000*cdf0e10cSrcweir 	//  an additional META_BMPEXSCALE_ACTION, that contains a replacement
3001*cdf0e10cSrcweir 	//	image for the new RenderGraphic action.
3002*cdf0e10cSrcweir 	//
3003*cdf0e10cSrcweir 	//	Old implementations, not knowing anything about META_RENDERGRAPHIC_ACTION,
3004*cdf0e10cSrcweir 	//  will skip this new action and read the META_BMPEXSCALE_ACTION instead
3005*cdf0e10cSrcweir 	//
3006*cdf0e10cSrcweir 	//  Since the current implementation is able to handle the new action, the
3007*cdf0e10cSrcweir 	//  then following image replacement action needs to be skipped by this
3008*cdf0e10cSrcweir 	//  implementation, if the metafile was written in the RenderGraphic
3009*cdf0e10cSrcweir 	//  replacement mode.
3010*cdf0e10cSrcweir 	//
3011*cdf0e10cSrcweir 	//  To be able to detect this compatibility mode, the header needs to
3012*cdf0e10cSrcweir 	//  be extended by a corresponding flag, resulting in version 2 of
3013*cdf0e10cSrcweir 	//  the header. The surrounding VersionCompat of the header
3014*cdf0e10cSrcweir 	//  allows to add such new data without any problems (KA 01/2011)
3015*cdf0e10cSrcweir 
3016*cdf0e10cSrcweir 	rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3017*cdf0e10cSrcweir 	rOStm.Write( "VCLMTF", 6 );
3018*cdf0e10cSrcweir 
3019*cdf0e10cSrcweir 	pCompat = new VersionCompat( rOStm, STREAM_WRITE, 2 );
3020*cdf0e10cSrcweir 
3021*cdf0e10cSrcweir 	{
3022*cdf0e10cSrcweir 		// version 1
3023*cdf0e10cSrcweir 		sal_uInt32 nActionCount = 0;
3024*cdf0e10cSrcweir 
3025*cdf0e10cSrcweir 		// calculate correct action count and watch for
3026*cdf0e10cSrcweir 		// additional RenderGraphic replacement actions, if the
3027*cdf0e10cSrcweir 		// GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set
3028*cdf0e10cSrcweir 		// and META_RENDERGRAPHIC_ACTION are encountered (KA 01/2011)
3029*cdf0e10cSrcweir 		for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) )
3030*cdf0e10cSrcweir 		{
3031*cdf0e10cSrcweir 			nActionCount += ( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) ? 2 : 1 );
3032*cdf0e10cSrcweir 		}
3033*cdf0e10cSrcweir 
3034*cdf0e10cSrcweir 		rOStm << nStmCompressMode << aPrefMapMode << aPrefSize << nActionCount;
3035*cdf0e10cSrcweir 
3036*cdf0e10cSrcweir 		{
3037*cdf0e10cSrcweir 			// version 2
3038*cdf0e10cSrcweir 			// =========
3039*cdf0e10cSrcweir 			// since version 2, a GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag
3040*cdf0e10cSrcweir 			// is written, to indicate that each META_BMPEXSCALE_ACTION following
3041*cdf0e10cSrcweir 			// a META_RENDERGRAPHIC_ACTION needs to be skipped, in case the flag is
3042*cdf0e10cSrcweir 			// set (KA 01/2011)
3043*cdf0e10cSrcweir 			rOStm << bRenderGraphicReplacements;
3044*cdf0e10cSrcweir 		}
3045*cdf0e10cSrcweir 	}
3046*cdf0e10cSrcweir 
3047*cdf0e10cSrcweir 	delete pCompat;
3048*cdf0e10cSrcweir 
3049*cdf0e10cSrcweir 	ImplMetaWriteData aWriteData;
3050*cdf0e10cSrcweir 
3051*cdf0e10cSrcweir 	aWriteData.meActualCharSet = rOStm.GetStreamCharSet();
3052*cdf0e10cSrcweir 	aWriteData.mnWriteFlags = nWriteFlags;
3053*cdf0e10cSrcweir 
3054*cdf0e10cSrcweir 	for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) )
3055*cdf0e10cSrcweir 	{
3056*cdf0e10cSrcweir 		pAct->Write( rOStm, &aWriteData );
3057*cdf0e10cSrcweir 
3058*cdf0e10cSrcweir 		// write the RenderGraphic replacement image, if the
3059*cdf0e10cSrcweir 		// GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag is set
3060*cdf0e10cSrcweir 		// and if a META_RENDERGRAPHIC_ACTION is encountered (KA 01/2011)
3061*cdf0e10cSrcweir 		if( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) )
3062*cdf0e10cSrcweir 		{
3063*cdf0e10cSrcweir 			MetaRenderGraphicAction* 	pRenderAction = static_cast< MetaRenderGraphicAction* >( pAct );
3064*cdf0e10cSrcweir 			MetaBmpExScaleAction*		pBmpExScaleAction = new MetaBmpExScaleAction(
3065*cdf0e10cSrcweir 											pRenderAction->GetPoint(), pRenderAction->GetSize(),
3066*cdf0e10cSrcweir 											pRenderAction->GetRenderGraphic().GetReplacement() );
3067*cdf0e10cSrcweir 
3068*cdf0e10cSrcweir 			pBmpExScaleAction->Write( rOStm, &aWriteData );
3069*cdf0e10cSrcweir 			pBmpExScaleAction->Delete();
3070*cdf0e10cSrcweir 		}
3071*cdf0e10cSrcweir 	}
3072*cdf0e10cSrcweir 
3073*cdf0e10cSrcweir 	rOStm.SetNumberFormatInt( nOldFormat );
3074*cdf0e10cSrcweir 
3075*cdf0e10cSrcweir 	return rOStm;
3076*cdf0e10cSrcweir }
3077*cdf0e10cSrcweir 
3078*cdf0e10cSrcweir // ------------------------------------------------------------------------
3079*cdf0e10cSrcweir 
3080*cdf0e10cSrcweir sal_Bool GDIMetaFile::CreateThumbnail( sal_uInt32 nMaximumExtent,
3081*cdf0e10cSrcweir 									BitmapEx& rBmpEx,
3082*cdf0e10cSrcweir 									const BitmapEx* pOverlay,
3083*cdf0e10cSrcweir 									const Rectangle* pOverlayRect ) const
3084*cdf0e10cSrcweir {
3085*cdf0e10cSrcweir 	// the implementation is provided by KA
3086*cdf0e10cSrcweir 
3087*cdf0e10cSrcweir 	// initialization seems to be complicated but is used to avoid rounding errors
3088*cdf0e10cSrcweir 	VirtualDevice	aVDev;
3089*cdf0e10cSrcweir 	const Point     aNullPt;
3090*cdf0e10cSrcweir 	const Point     aTLPix( aVDev.LogicToPixel( aNullPt, GetPrefMapMode() ) );
3091*cdf0e10cSrcweir 	const Point     aBRPix( aVDev.LogicToPixel( Point( GetPrefSize().Width() - 1, GetPrefSize().Height() - 1 ), GetPrefMapMode() ) );
3092*cdf0e10cSrcweir 	Size            aDrawSize( aVDev.LogicToPixel( GetPrefSize(), GetPrefMapMode() ) );
3093*cdf0e10cSrcweir 	Size			aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
3094*cdf0e10cSrcweir 	Point			aPosPix;
3095*cdf0e10cSrcweir 
3096*cdf0e10cSrcweir 	if ( !rBmpEx.IsEmpty() )
3097*cdf0e10cSrcweir 		rBmpEx.SetEmpty();
3098*cdf0e10cSrcweir 
3099*cdf0e10cSrcweir 	// determine size that has the same aspect ratio as image size and
3100*cdf0e10cSrcweir 	// fits into the rectangle determined by nMaximumExtent
3101*cdf0e10cSrcweir 	if ( aSizePix.Width() && aSizePix.Height()
3102*cdf0e10cSrcweir 	  && ( sal::static_int_cast< unsigned long >(aSizePix.Width()) >
3103*cdf0e10cSrcweir                nMaximumExtent ||
3104*cdf0e10cSrcweir            sal::static_int_cast< unsigned long >(aSizePix.Height()) >
3105*cdf0e10cSrcweir                nMaximumExtent ) )
3106*cdf0e10cSrcweir 	{
3107*cdf0e10cSrcweir 		const Size  aOldSizePix( aSizePix );
3108*cdf0e10cSrcweir 		double      fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height();
3109*cdf0e10cSrcweir 
3110*cdf0e10cSrcweir 		if ( fWH <= 1.0 )
3111*cdf0e10cSrcweir 		{
3112*cdf0e10cSrcweir 			aSizePix.Width() = FRound( nMaximumExtent * fWH );
3113*cdf0e10cSrcweir 			aSizePix.Height() = nMaximumExtent;
3114*cdf0e10cSrcweir 		}
3115*cdf0e10cSrcweir 		else
3116*cdf0e10cSrcweir 		{
3117*cdf0e10cSrcweir 			aSizePix.Width() = nMaximumExtent;
3118*cdf0e10cSrcweir 			aSizePix.Height() = FRound(  nMaximumExtent / fWH );
3119*cdf0e10cSrcweir 		}
3120*cdf0e10cSrcweir 
3121*cdf0e10cSrcweir 		aDrawSize.Width() = FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() );
3122*cdf0e10cSrcweir 		aDrawSize.Height() = FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() );
3123*cdf0e10cSrcweir 	}
3124*cdf0e10cSrcweir 
3125*cdf0e10cSrcweir 	Size 		aFullSize;
3126*cdf0e10cSrcweir 	Point		aBackPosPix;
3127*cdf0e10cSrcweir 	Rectangle 	aOverlayRect;
3128*cdf0e10cSrcweir 
3129*cdf0e10cSrcweir 	// calculate addigtional positions and sizes if an overlay image is used
3130*cdf0e10cSrcweir 	if (  pOverlay )
3131*cdf0e10cSrcweir 	{
3132*cdf0e10cSrcweir 		aFullSize = Size( nMaximumExtent, nMaximumExtent );
3133*cdf0e10cSrcweir 		aOverlayRect = Rectangle( aNullPt, aFullSize  );
3134*cdf0e10cSrcweir 
3135*cdf0e10cSrcweir 		aOverlayRect.Intersection( pOverlayRect ? *pOverlayRect : Rectangle( aNullPt, pOverlay->GetSizePixel() ) );
3136*cdf0e10cSrcweir 
3137*cdf0e10cSrcweir 		if ( !aOverlayRect.IsEmpty() )
3138*cdf0e10cSrcweir 			aBackPosPix = Point( ( nMaximumExtent - aSizePix.Width() ) >> 1, ( nMaximumExtent - aSizePix.Height() ) >> 1 );
3139*cdf0e10cSrcweir 		else
3140*cdf0e10cSrcweir 			pOverlay = NULL;
3141*cdf0e10cSrcweir 	}
3142*cdf0e10cSrcweir 	else
3143*cdf0e10cSrcweir 	{
3144*cdf0e10cSrcweir 		aFullSize = aSizePix;
3145*cdf0e10cSrcweir 		pOverlay = NULL;
3146*cdf0e10cSrcweir 	}
3147*cdf0e10cSrcweir 
3148*cdf0e10cSrcweir 	// draw image(s) into VDev and get resulting image
3149*cdf0e10cSrcweir 	if ( aVDev.SetOutputSizePixel( aFullSize ) )
3150*cdf0e10cSrcweir 	{
3151*cdf0e10cSrcweir 		// draw metafile into VDev
3152*cdf0e10cSrcweir 		const_cast<GDIMetaFile *>(this)->WindStart();
3153*cdf0e10cSrcweir 		const_cast<GDIMetaFile *>(this)->Play( &aVDev, aBackPosPix, aDrawSize );
3154*cdf0e10cSrcweir 
3155*cdf0e10cSrcweir 		// draw overlay if neccessary
3156*cdf0e10cSrcweir 		if ( pOverlay )
3157*cdf0e10cSrcweir 			aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), *pOverlay );
3158*cdf0e10cSrcweir 
3159*cdf0e10cSrcweir 		// get paint bitmap
3160*cdf0e10cSrcweir 		Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
3161*cdf0e10cSrcweir 
3162*cdf0e10cSrcweir 		// assure that we have a true color image
3163*cdf0e10cSrcweir 		if ( aBmp.GetBitCount() != 24 )
3164*cdf0e10cSrcweir 			aBmp.Convert( BMP_CONVERSION_24BIT );
3165*cdf0e10cSrcweir 
3166*cdf0e10cSrcweir 		// create resulting mask bitmap with metafile output set to black
3167*cdf0e10cSrcweir 		GDIMetaFile aMonchromeMtf( GetMonochromeMtf( COL_BLACK ) );
3168*cdf0e10cSrcweir 		aVDev.DrawWallpaper( Rectangle( aNullPt, aSizePix ), Wallpaper( Color( COL_WHITE ) ) );
3169*cdf0e10cSrcweir 		aMonchromeMtf.WindStart();
3170*cdf0e10cSrcweir 		aMonchromeMtf.Play( &aVDev, aBackPosPix, aDrawSize );
3171*cdf0e10cSrcweir 
3172*cdf0e10cSrcweir 		// watch for overlay mask
3173*cdf0e10cSrcweir 		if ( pOverlay  )
3174*cdf0e10cSrcweir 		{
3175*cdf0e10cSrcweir 			Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) );
3176*cdf0e10cSrcweir 
3177*cdf0e10cSrcweir 			// create ANDed resulting mask at overlay area
3178*cdf0e10cSrcweir 			if ( pOverlay->IsTransparent() )
3179*cdf0e10cSrcweir 				aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), pOverlay->GetMask() );
3180*cdf0e10cSrcweir 			else
3181*cdf0e10cSrcweir 			{
3182*cdf0e10cSrcweir 				aVDev.SetLineColor( COL_BLACK );
3183*cdf0e10cSrcweir 				aVDev.SetFillColor( COL_BLACK );
3184*cdf0e10cSrcweir 				aVDev.DrawRect( aOverlayRect);
3185*cdf0e10cSrcweir 			}
3186*cdf0e10cSrcweir 
3187*cdf0e10cSrcweir 			aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND );
3188*cdf0e10cSrcweir 			aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp );
3189*cdf0e10cSrcweir 		}
3190*cdf0e10cSrcweir 
3191*cdf0e10cSrcweir 		rBmpEx = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
3192*cdf0e10cSrcweir 	}
3193*cdf0e10cSrcweir 
3194*cdf0e10cSrcweir 	return !rBmpEx.IsEmpty();
3195*cdf0e10cSrcweir }
3196