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