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