LibreOffice Module vcl (master)  1
gdimtf.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <cstdlib>
21 #include <memory>
22 #include <sal/log.hxx>
23 #include <osl/diagnose.h>
24 #include <tools/diagnose_ex.h>
25 #include <tools/helpers.hxx>
26 #include <tools/stream.hxx>
27 #include <tools/vcompat.hxx>
28 #include <tools/fract.hxx>
29 #include <vcl/BitmapPalette.hxx>
30 #include <vcl/metaact.hxx>
31 #include <vcl/outdev.hxx>
32 #include <vcl/window.hxx>
33 #include <vcl/virdev.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/gdimtf.hxx>
36 #include <vcl/graphictools.hxx>
38 #include <vcl/canvastools.hxx>
39 #include <vcl/mtfxmldump.hxx>
40 
41 #include <svmconverter.hxx>
42 #include <TypeSerializer.hxx>
43 
44 #include <com/sun/star/beans/XFastPropertySet.hpp>
45 #include <com/sun/star/rendering/MtfRenderer.hpp>
46 #include <com/sun/star/rendering/XBitmapCanvas.hpp>
47 #include <com/sun/star/rendering/XCanvas.hpp>
49 
50 using namespace com::sun::star;
51 
52 #define GAMMA( _def_cVal, _def_InvGamma ) (static_cast<sal_uInt8>(MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0,255)))
53 
54 namespace {
55 
56 struct ImplColAdjustParam
57 {
58  std::unique_ptr<sal_uInt8[]> pMapR;
59  std::unique_ptr<sal_uInt8[]> pMapG;
60  std::unique_ptr<sal_uInt8[]> pMapB;
61 };
62 
63 struct ImplBmpAdjustParam
64 {
65  short nLuminancePercent;
66  short nContrastPercent;
67  short nChannelRPercent;
68  short nChannelGPercent;
69  short nChannelBPercent;
70  double fGamma;
71  bool bInvert;
72 };
73 
74 struct ImplColConvertParam
75 {
76  MtfConversion eConversion;
77 };
78 
79 struct ImplBmpConvertParam
80 {
81  BmpConversion eConversion;
82 };
83 
84 struct ImplColMonoParam
85 {
86  Color aColor;
87 };
88 
89 struct ImplBmpMonoParam
90 {
91  Color aColor;
92 };
93 
94 struct ImplColReplaceParam
95 {
96  std::unique_ptr<sal_uLong[]> pMinR;
97  std::unique_ptr<sal_uLong[]> pMaxR;
98  std::unique_ptr<sal_uLong[]> pMinG;
99  std::unique_ptr<sal_uLong[]> pMaxG;
100  std::unique_ptr<sal_uLong[]> pMinB;
101  std::unique_ptr<sal_uLong[]> pMaxB;
102  const Color * pDstCols;
104 };
105 
106 struct ImplBmpReplaceParam
107 {
108  const Color* pSrcCols;
109  const Color* pDstCols;
111 };
112 
113 }
114 
116  m_nCurrentActionElement( 0 ),
117  m_aPrefSize ( 1, 1 ),
118  m_pPrev ( nullptr ),
119  m_pNext ( nullptr ),
120  m_pOutDev ( nullptr ),
121  m_bPause ( false ),
122  m_bRecord ( false ),
123  m_bUseCanvas ( false )
124 {
125 }
126 
128  m_nCurrentActionElement( rMtf.m_nCurrentActionElement ),
129  m_aPrefMapMode ( rMtf.m_aPrefMapMode ),
130  m_aPrefSize ( rMtf.m_aPrefSize ),
131  m_pPrev ( rMtf.m_pPrev ),
132  m_pNext ( rMtf.m_pNext ),
133  m_pOutDev ( nullptr ),
134  m_bPause ( false ),
135  m_bRecord ( false ),
136  m_bUseCanvas ( rMtf.m_bUseCanvas )
137 {
138  for( size_t i = 0, n = rMtf.GetActionSize(); i < n; ++i )
139  {
140  m_aList.push_back( rMtf.GetAction( i ) );
141  }
142 
143  if( rMtf.m_bRecord )
144  {
145  Record( rMtf.m_pOutDev );
146 
147  if ( rMtf.m_bPause )
148  Pause( true );
149  }
150 }
151 
153 {
154  Clear();
155 }
156 
158 {
159  return m_aList.size();
160 }
161 
162 MetaAction* GDIMetaFile::GetAction( size_t nAction ) const
163 {
164  return (nAction < m_aList.size()) ? m_aList[ nAction ].get() : nullptr;
165 }
166 
168 {
170  return m_aList.empty() ? nullptr : m_aList[ 0 ].get();
171 }
172 
174 {
175  return ( m_nCurrentActionElement + 1 < m_aList.size() ) ? m_aList[ ++m_nCurrentActionElement ].get() : nullptr;
176 }
177 
179 {
180  if ( nAction >= m_aList.size() )
181  {
182  return;
183  }
184  //fdo#39995 This doesn't increment the incoming action ref-count nor does it
185  //decrement the outgoing action ref-count
186  std::swap(pAction, m_aList[nAction]);
187 }
188 
190 {
191  if( this != &rMtf )
192  {
193  Clear();
194 
195  // Increment RefCount of MetaActions
196  for( size_t i = 0, n = rMtf.GetActionSize(); i < n; ++i )
197  {
198  m_aList.push_back( rMtf.GetAction( i ) );
199  }
200 
202  m_aPrefSize = rMtf.m_aPrefSize;
203  m_pPrev = rMtf.m_pPrev;
204  m_pNext = rMtf.m_pNext;
205  m_pOutDev = nullptr;
206  m_bPause = false;
207  m_bRecord = false;
208  m_bUseCanvas = rMtf.m_bUseCanvas;
209 
210  if( rMtf.m_bRecord )
211  {
212  Record( rMtf.m_pOutDev );
213 
214  if( rMtf.m_bPause )
215  Pause( true );
216  }
217  }
218 
219  return *this;
220 }
221 
222 bool GDIMetaFile::operator==( const GDIMetaFile& rMtf ) const
223 {
224  const size_t nObjCount = m_aList.size();
225  bool bRet = false;
226 
227  if( this == &rMtf )
228  bRet = true;
229  else if( rMtf.GetActionSize() == nObjCount &&
230  rMtf.GetPrefSize() == m_aPrefSize &&
231  rMtf.GetPrefMapMode() == m_aPrefMapMode )
232  {
233  bRet = true;
234 
235  for( size_t n = 0; n < nObjCount; n++ )
236  {
237  if( m_aList[ n ] != rMtf.GetAction( n ) )
238  {
239  bRet = false;
240  break;
241  }
242  }
243  }
244 
245  return bRet;
246 }
247 
249 {
250  if( m_bRecord )
251  Stop();
252 
253  m_aList.clear();
254 }
255 
256 void GDIMetaFile::Linker( OutputDevice* pOut, bool bLink )
257 {
258  if( bLink )
259  {
260  m_pNext = nullptr;
261  m_pPrev = pOut->GetConnectMetaFile();
262  pOut->SetConnectMetaFile( this );
263 
264  if( m_pPrev )
265  m_pPrev->m_pNext = this;
266  }
267  else
268  {
269  if( m_pNext )
270  {
272 
273  if( m_pPrev )
275  }
276  else
277  {
278  if( m_pPrev )
279  m_pPrev->m_pNext = nullptr;
280 
281  pOut->SetConnectMetaFile( m_pPrev );
282  }
283 
284  m_pPrev = nullptr;
285  m_pNext = nullptr;
286  }
287 }
288 
290 {
291  if( m_bRecord )
292  Stop();
293 
294  m_nCurrentActionElement = m_aList.empty() ? 0 : (m_aList.size() - 1);
295  m_pOutDev = pOut;
296  m_bRecord = true;
297  Linker( pOut, true );
298 }
299 
301 {
302  if ( !m_bRecord && !rMtf.m_bRecord )
303  {
304  MetaAction* pAction = GetCurAction();
305  const size_t nObjCount = m_aList.size();
306 
307  rMtf.UseCanvas( rMtf.GetUseCanvas() || m_bUseCanvas );
308 
309  for( size_t nCurPos = m_nCurrentActionElement; nCurPos < nObjCount; nCurPos++ )
310  {
311  if( pAction )
312  {
313  rMtf.AddAction( pAction );
314  }
315 
316  pAction = NextAction();
317  }
318  }
319 }
320 
321 void GDIMetaFile::Play( OutputDevice* pOut, size_t nPos )
322 {
323  if( !m_bRecord )
324  {
325  MetaAction* pAction = GetCurAction();
326  const size_t nObjCount = m_aList.size();
327  size_t nSyncCount = ( pOut->GetOutDevType() == OUTDEV_WINDOW ) ? 0x000000ff : 0xffffffff;
328 
329  if( nPos > nObjCount )
330  nPos = nObjCount;
331 
332  // #i23407# Set backwards-compatible text language and layout mode
333  // This is necessary, since old metafiles don't even know of these
334  // recent add-ons. Newer metafiles must of course explicitly set
335  // those states.
339 
340  SAL_INFO( "vcl.gdi", "GDIMetaFile::Play on device of size: " << pOut->GetOutputSizePixel().Width() << " " << pOut->GetOutputSizePixel().Height());
341 
342  if( !ImplPlayWithRenderer( pOut, Point(0,0), pOut->GetOutputSize() ) ) {
343  size_t i = 0;
344  for( size_t nCurPos = m_nCurrentActionElement; nCurPos < nPos; nCurPos++ )
345  {
346  if( pAction )
347  {
348  pAction->Execute( pOut );
349 
350  // flush output from time to time
351  if( i++ > nSyncCount )
352  {
353  static_cast<vcl::Window*>( pOut )->Flush();
354  i = 0;
355  }
356  }
357 
358  pAction = NextAction();
359  }
360  }
361  pOut->Pop();
362  }
363 }
364 
365 bool GDIMetaFile::ImplPlayWithRenderer( OutputDevice* pOut, const Point& rPos, Size rLogicDestSize )
366 {
367  if (!m_bUseCanvas)
368  return false;
369 
370  Size rDestSize( pOut->LogicToPixel( rLogicDestSize ) );
371 
372  const vcl::Window* win = dynamic_cast <vcl::Window*> ( pOut );
373 
374  if (!win)
376  if (!win)
378 
379  if (!win)
380  return false;
381 
382  try
383  {
384  uno::Reference<rendering::XCanvas> xCanvas = win->GetCanvas ();
385 
386  if (!xCanvas.is())
387  return false;
388 
389  Size aSize (rDestSize.Width () + 1, rDestSize.Height () + 1);
390  uno::Reference<rendering::XBitmap> xBitmap = xCanvas->getDevice ()->createCompatibleAlphaBitmap (vcl::unotools::integerSize2DFromSize( aSize));
391  if( xBitmap.is () )
392  {
393  uno::Reference< rendering::XBitmapCanvas > xBitmapCanvas( xBitmap, uno::UNO_QUERY );
394  if( xBitmapCanvas.is() )
395  {
396  uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
397  uno::Reference< rendering::XMtfRenderer > xMtfRenderer = rendering::MtfRenderer::createWithBitmapCanvas( xContext, xBitmapCanvas );
398 
399  xBitmapCanvas->clear();
400  uno::Reference< beans::XFastPropertySet > xMtfFastPropertySet( xMtfRenderer, uno::UNO_QUERY );
401  if( xMtfFastPropertySet.is() )
402  // set this metafile to the renderer to
403  // speedup things (instead of copying data to
404  // sequence of bytes passed to renderer)
405  xMtfFastPropertySet->setFastPropertyValue( 0, uno::Any( reinterpret_cast<sal_Int64>( this ) ) );
406 
407  xMtfRenderer->draw( rDestSize.Width(), rDestSize.Height() );
408 
409  BitmapEx aBitmapEx;
410  if( aBitmapEx.Create( xBitmapCanvas, aSize ) )
411  {
412  if (pOut->GetMapMode().GetMapUnit() == MapUnit::MapPixel)
413  pOut->DrawBitmapEx( rPos, aBitmapEx );
414  else
415  pOut->DrawBitmapEx( rPos, rLogicDestSize, aBitmapEx );
416  return true;
417  }
418  }
419  }
420  }
421  catch (const uno::RuntimeException& )
422  {
423  throw; // runtime errors are fatal
424  }
425  catch (const uno::Exception&)
426  {
427  // ignore errors, no way of reporting them here
428  TOOLS_WARN_EXCEPTION("vcl.gdi", "GDIMetaFile::ImplPlayWithRenderer");
429  }
430 
431  return false;
432 }
433 
434 void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos,
435  const Size& rSize )
436 {
437  vcl::Region aDrawClipRegion;
438  MapMode aDrawMap( GetPrefMapMode() );
439  Size aDestSize( pOut->LogicToPixel( rSize ) );
440 
441  if( !aDestSize.Width() || !aDestSize.Height() )
442  return;
443 
444  GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
445 
446  if( ImplPlayWithRenderer( pOut, rPos, rSize ) )
447  return;
448 
449  Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) );
450 
451  if( !aTmpPrefSize.Width() )
452  aTmpPrefSize.setWidth( aDestSize.Width() );
453 
454  if( !aTmpPrefSize.Height() )
455  aTmpPrefSize.setHeight( aDestSize.Height() );
456 
457  Fraction aScaleX( aDestSize.Width(), aTmpPrefSize.Width() );
458  Fraction aScaleY( aDestSize.Height(), aTmpPrefSize.Height() );
459 
460  aScaleX *= aDrawMap.GetScaleX(); aDrawMap.SetScaleX( aScaleX );
461  aScaleY *= aDrawMap.GetScaleY(); aDrawMap.SetScaleY( aScaleY );
462 
463  // #i47260# Convert logical output position to offset within
464  // the metafile's mapmode. Therefore, disable pixel offset on
465  // outdev, it's inverse mnOutOffLogicX/Y is calculated for a
466  // different mapmode (the one currently set on pOut, that is)
467  // - thus, aDrawMap's origin would generally be wrong. And
468  // even _if_ aDrawMap is similar to pOutDev's current mapmode,
469  // it's _still_ undesirable to have pixel offset unequal zero,
470  // because one would still get round-off errors (the
471  // round-trip error for LogicToPixel( PixelToLogic() ) was the
472  // reason for having pixel offset in the first place).
473  const Size& rOldOffset( pOut->GetPixelOffset() );
474  const Size aEmptySize;
475  pOut->SetPixelOffset( aEmptySize );
476  aDrawMap.SetOrigin( pOut->PixelToLogic( pOut->LogicToPixel( rPos ), aDrawMap ) );
477  pOut->SetPixelOffset( rOldOffset );
478 
479  pOut->Push();
480 
481  if ( pMtf && pMtf->IsRecord() && ( pOut->GetOutDevType() != OUTDEV_PRINTER ) )
482  pOut->SetRelativeMapMode( aDrawMap );
483  else
484  pOut->SetMapMode( aDrawMap );
485 
486  // #i23407# Set backwards-compatible text language and layout mode
487  // This is necessary, since old metafiles don't even know of these
488  // recent add-ons. Newer metafiles must of course explicitly set
489  // those states.
492 
493  Play( pOut );
494 
495  pOut->Pop();
496 
497 }
498 
499 void GDIMetaFile::Pause( bool _bPause )
500 {
501  if( m_bRecord )
502  {
503  if( _bPause )
504  {
505  if( !m_bPause )
506  Linker( m_pOutDev, false );
507  }
508  else
509  {
510  if( m_bPause )
511  Linker( m_pOutDev, true );
512  }
513 
514  m_bPause = _bPause;
515  }
516 }
517 
519 {
520  if( m_bRecord )
521  {
522  m_bRecord = false;
523 
524  if( !m_bPause )
525  Linker( m_pOutDev, false );
526  else
527  m_bPause = false;
528  }
529 }
530 
532 {
533  if( !m_bRecord )
535 }
536 
538 {
539  if( !m_bRecord )
540  if ( m_nCurrentActionElement > 0 )
542 }
543 
545 {
546  m_aList.push_back( pAction );
547 
548  if( m_pPrev )
549  {
550  m_pPrev->AddAction( pAction );
551  }
552 }
553 
554 void GDIMetaFile::AddAction(const rtl::Reference<MetaAction>& pAction, size_t nPos)
555 {
556  if ( nPos < m_aList.size() )
557  {
558  m_aList.insert( m_aList.begin() + nPos, pAction );
559  }
560  else
561  {
562  m_aList.push_back( pAction );
563  }
564 
565  if( m_pPrev )
566  {
567  m_pPrev->AddAction( pAction, nPos );
568  }
569 }
570 
572 {
573  m_aList.push_back( pAction );
574 }
575 
577 {
578  const Size aOldPrefSize( GetPrefSize() );
579  long nMoveX, nMoveY;
580  double fScaleX, fScaleY;
581 
582  if( nMirrorFlags & BmpMirrorFlags::Horizontal )
583  {
584  nMoveX = std::abs( aOldPrefSize.Width() ) - 1;
585  fScaleX = -1.0;
586  }
587  else
588  {
589  nMoveX = 0;
590  fScaleX = 1.0;
591  }
592 
593  if( nMirrorFlags & BmpMirrorFlags::Vertical )
594  {
595  nMoveY = std::abs( aOldPrefSize.Height() ) - 1;
596  fScaleY = -1.0;
597  }
598  else
599  {
600  nMoveY = 0;
601  fScaleY = 1.0;
602  }
603 
604  if( ( fScaleX != 1.0 ) || ( fScaleY != 1.0 ) )
605  {
606  Scale( fScaleX, fScaleY );
607  Move( nMoveX, nMoveY );
608  SetPrefSize( aOldPrefSize );
609  }
610 }
611 
612 void GDIMetaFile::Move( long nX, long nY )
613 {
614  const Size aBaseOffset( nX, nY );
615  Size aOffset( aBaseOffset );
617 
618  aMapVDev->EnableOutput( false );
619  aMapVDev->SetMapMode( GetPrefMapMode() );
620 
621  for( MetaAction* pAct = FirstAction(); pAct; pAct = NextAction() )
622  {
623  const MetaActionType nType = pAct->GetType();
624  MetaAction* pModAct;
625 
626  if( pAct->GetRefCount() > 1 )
627  {
628  m_aList[ m_nCurrentActionElement ] = pAct->Clone();
629  pModAct = m_aList[ m_nCurrentActionElement ].get();
630  }
631  else
632  pModAct = pAct;
633 
634  if( ( MetaActionType::MAPMODE == nType ) ||
635  ( MetaActionType::PUSH == nType ) ||
636  ( MetaActionType::POP == nType ) )
637  {
638  pModAct->Execute( aMapVDev.get() );
639  aOffset = OutputDevice::LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev->GetMapMode() );
640  }
641 
642  pModAct->Move( aOffset.Width(), aOffset.Height() );
643  }
644 }
645 
646 void GDIMetaFile::Move( long nX, long nY, long nDPIX, long nDPIY )
647 {
648  const Size aBaseOffset( nX, nY );
649  Size aOffset( aBaseOffset );
651 
652  aMapVDev->EnableOutput( false );
653  aMapVDev->SetReferenceDevice( nDPIX, nDPIY );
654  aMapVDev->SetMapMode( GetPrefMapMode() );
655 
656  for( MetaAction* pAct = FirstAction(); pAct; pAct = NextAction() )
657  {
658  const MetaActionType nType = pAct->GetType();
659  MetaAction* pModAct;
660 
661  if( pAct->GetRefCount() > 1 )
662  {
663  m_aList[ m_nCurrentActionElement ] = pAct->Clone();
664  pModAct = m_aList[ m_nCurrentActionElement ].get();
665  }
666  else
667  pModAct = pAct;
668 
669  if( ( MetaActionType::MAPMODE == nType ) ||
670  ( MetaActionType::PUSH == nType ) ||
671  ( MetaActionType::POP == nType ) )
672  {
673  pModAct->Execute( aMapVDev.get() );
674  if( aMapVDev->GetMapMode().GetMapUnit() == MapUnit::MapPixel )
675  {
676  aOffset = aMapVDev->LogicToPixel( aBaseOffset, GetPrefMapMode() );
677  MapMode aMap( aMapVDev->GetMapMode() );
678  aOffset.setWidth( static_cast<long>(aOffset.Width() * static_cast<double>(aMap.GetScaleX())) );
679  aOffset.setHeight( static_cast<long>(aOffset.Height() * static_cast<double>(aMap.GetScaleY())) );
680  }
681  else
682  aOffset = OutputDevice::LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev->GetMapMode() );
683  }
684 
685  pModAct->Move( aOffset.Width(), aOffset.Height() );
686  }
687 }
688 
689 void GDIMetaFile::Scale( double fScaleX, double fScaleY )
690 {
691  for( MetaAction* pAct = FirstAction(); pAct; pAct = NextAction() )
692  {
693  MetaAction* pModAct;
694 
695  if( pAct->GetRefCount() > 1 )
696  {
697  m_aList[ m_nCurrentActionElement ] = pAct->Clone();
698  pModAct = m_aList[ m_nCurrentActionElement ].get();
699  }
700  else
701  pModAct = pAct;
702 
703  pModAct->Scale( fScaleX, fScaleY );
704  }
705 
706  m_aPrefSize.setWidth( FRound( m_aPrefSize.Width() * fScaleX ) );
707  m_aPrefSize.setHeight( FRound( m_aPrefSize.Height() * fScaleY ) );
708 }
709 
710 void GDIMetaFile::Scale( const Fraction& rScaleX, const Fraction& rScaleY )
711 {
712  Scale( static_cast<double>(rScaleX), static_cast<double>(rScaleY) );
713 }
714 
715 void GDIMetaFile::Clip( const tools::Rectangle& i_rClipRect )
716 {
717  tools::Rectangle aCurRect( i_rClipRect );
719 
720  aMapVDev->EnableOutput( false );
721  aMapVDev->SetMapMode( GetPrefMapMode() );
722 
723  for( MetaAction* pAct = FirstAction(); pAct; pAct = NextAction() )
724  {
725  const MetaActionType nType = pAct->GetType();
726 
727  if( ( MetaActionType::MAPMODE == nType ) ||
728  ( MetaActionType::PUSH == nType ) ||
729  ( MetaActionType::POP == nType ) )
730  {
731  pAct->Execute( aMapVDev.get() );
732  aCurRect = OutputDevice::LogicToLogic( i_rClipRect, GetPrefMapMode(), aMapVDev->GetMapMode() );
733  }
734  else if( nType == MetaActionType::CLIPREGION )
735  {
736  MetaClipRegionAction* pOldAct = static_cast<MetaClipRegionAction*>(pAct);
737  vcl::Region aNewReg( aCurRect );
738  if( pOldAct->IsClipping() )
739  aNewReg.Intersect( pOldAct->GetRegion() );
740  MetaClipRegionAction* pNewAct = new MetaClipRegionAction( aNewReg, true );
741  m_aList[ m_nCurrentActionElement ] = pNewAct;
742  }
743  }
744 }
745 
746 Point GDIMetaFile::ImplGetRotatedPoint( const Point& rPt, const Point& rRotatePt,
747  const Size& rOffset, double fSin, double fCos )
748 {
749  const long nX = rPt.X() - rRotatePt.X();
750  const long nY = rPt.Y() - rRotatePt.Y();
751 
752  return Point( FRound( fCos * nX + fSin * nY ) + rRotatePt.X() + rOffset.Width(),
753  -FRound( fSin * nX - fCos * nY ) + rRotatePt.Y() + rOffset.Height() );
754 }
755 
757  const Size& rOffset, double fSin, double fCos )
758 {
759  tools::Polygon aRet( rPoly );
760 
761  aRet.Rotate( rRotatePt, fSin, fCos );
762  aRet.Move( rOffset.Width(), rOffset.Height() );
763 
764  return aRet;
765 }
766 
768  const Size& rOffset, double fSin, double fCos )
769 {
770  tools::PolyPolygon aRet( rPolyPoly );
771 
772  aRet.Rotate( rRotatePt, fSin, fCos );
773  aRet.Move( rOffset.Width(), rOffset.Height() );
774 
775  return aRet;
776 }
777 
779  const OutputDevice& rMapDev,
780  const tools::PolyPolygon& rPolyPoly,
781  const Gradient& rGrad )
782 {
783  // Generate comment, GradientEx and Gradient actions (within DrawGradient)
785  aVDev->EnableOutput( false );
786  GDIMetaFile aGradMtf;
787 
788  aGradMtf.Record( aVDev.get() );
789  aVDev->DrawGradient( rPolyPoly, rGrad );
790  aGradMtf.Stop();
791 
792  size_t i, nAct( aGradMtf.GetActionSize() );
793  for( i=0; i < nAct; ++i )
794  {
795  MetaAction* pMetaAct = aGradMtf.GetAction( i );
796  rMtf.AddAction( pMetaAct );
797  }
798 }
799 
800 void GDIMetaFile::Rotate( long nAngle10 )
801 {
802  nAngle10 %= 3600;
803  nAngle10 = ( nAngle10 < 0 ) ? ( 3599 + nAngle10 ) : nAngle10;
804 
805  if( !nAngle10 )
806  return;
807 
808  GDIMetaFile aMtf;
810  const double fAngle = F_PI1800 * nAngle10;
811  const double fSin = sin( fAngle );
812  const double fCos = cos( fAngle );
813  tools::Rectangle aRect( Point(), GetPrefSize() );
814  tools::Polygon aPoly( aRect );
815 
816  aPoly.Rotate( Point(), fSin, fCos );
817 
818  aMapVDev->EnableOutput( false );
819  aMapVDev->SetMapMode( GetPrefMapMode() );
820 
821  const tools::Rectangle aNewBound( aPoly.GetBoundRect() );
822 
823  const Point aOrigin( GetPrefMapMode().GetOrigin().X(), GetPrefMapMode().GetOrigin().Y() );
824  const Size aOffset( -aNewBound.Left(), -aNewBound.Top() );
825 
826  Point aRotAnchor( aOrigin );
827  Size aRotOffset( aOffset );
828 
829  for( MetaAction* pAction = FirstAction(); pAction; pAction = NextAction() )
830  {
831  const MetaActionType nActionType = pAction->GetType();
832 
833  switch( nActionType )
834  {
836  {
837  MetaPixelAction* pAct = static_cast<MetaPixelAction*>(pAction);
838  aMtf.AddAction( new MetaPixelAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
839  pAct->GetColor() ) );
840  }
841  break;
842 
844  {
845  MetaPointAction* pAct = static_cast<MetaPointAction*>(pAction);
846  aMtf.AddAction( new MetaPointAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
847  }
848  break;
849 
851  {
852  MetaLineAction* pAct = static_cast<MetaLineAction*>(pAction);
853  aMtf.AddAction( new MetaLineAction( ImplGetRotatedPoint( pAct->GetStartPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
854  ImplGetRotatedPoint( pAct->GetEndPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
855  pAct->GetLineInfo() ) );
856  }
857  break;
858 
860  {
861  MetaRectAction* pAct = static_cast<MetaRectAction*>(pAction);
862  aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
863  }
864  break;
865 
867  {
868  MetaRoundRectAction* pAct = static_cast<MetaRoundRectAction*>(pAction);
869  const tools::Polygon aRoundRectPoly( pAct->GetRect(), pAct->GetHorzRound(), pAct->GetVertRound() );
870 
871  aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aRoundRectPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
872  }
873  break;
874 
876  {
877  MetaEllipseAction* pAct = static_cast<MetaEllipseAction*>(pAction);
878  const tools::Polygon aEllipsePoly( pAct->GetRect().Center(), pAct->GetRect().GetWidth() >> 1, pAct->GetRect().GetHeight() >> 1 );
879 
880  aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aEllipsePoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
881  }
882  break;
883 
884  case MetaActionType::ARC:
885  {
886  MetaArcAction* pAct = static_cast<MetaArcAction*>(pAction);
887  const tools::Polygon aArcPoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), PolyStyle::Arc );
888 
889  aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aArcPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
890  }
891  break;
892 
893  case MetaActionType::PIE:
894  {
895  MetaPieAction* pAct = static_cast<MetaPieAction*>(pAction);
896  const tools::Polygon aPiePoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), PolyStyle::Pie );
897 
898  aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aPiePoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
899  }
900  break;
901 
903  {
904  MetaChordAction* pAct = static_cast<MetaChordAction*>(pAction);
905  const tools::Polygon aChordPoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), PolyStyle::Chord );
906 
907  aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aChordPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) );
908  }
909  break;
910 
912  {
913  MetaPolyLineAction* pAct = static_cast<MetaPolyLineAction*>(pAction);
914  aMtf.AddAction( new MetaPolyLineAction( ImplGetRotatedPolygon( pAct->GetPolygon(), aRotAnchor, aRotOffset, fSin, fCos ), pAct->GetLineInfo() ) );
915  }
916  break;
917 
919  {
920  MetaPolygonAction* pAct = static_cast<MetaPolygonAction*>(pAction);
921  aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct->GetPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
922  }
923  break;
924 
926  {
927  MetaPolyPolygonAction* pAct = static_cast<MetaPolyPolygonAction*>(pAction);
928  aMtf.AddAction( new MetaPolyPolygonAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) );
929  }
930  break;
931 
933  {
934  MetaTextAction* pAct = static_cast<MetaTextAction*>(pAction);
935  aMtf.AddAction( new MetaTextAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
936  pAct->GetText(), pAct->GetIndex(), pAct->GetLen() ) );
937  }
938  break;
939 
941  {
942  MetaTextArrayAction* pAct = static_cast<MetaTextArrayAction*>(pAction);
943  aMtf.AddAction( new MetaTextArrayAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
944  pAct->GetText(), pAct->GetDXArray(), pAct->GetIndex(), pAct->GetLen() ) );
945  }
946  break;
947 
949  {
950  MetaStretchTextAction* pAct = static_cast<MetaStretchTextAction*>(pAction);
951  aMtf.AddAction( new MetaStretchTextAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
952  pAct->GetWidth(), pAct->GetText(), pAct->GetIndex(), pAct->GetLen() ) );
953  }
954  break;
955 
957  {
958  MetaTextLineAction* pAct = static_cast<MetaTextLineAction*>(pAction);
959  aMtf.AddAction( new MetaTextLineAction( ImplGetRotatedPoint( pAct->GetStartPoint(), aRotAnchor, aRotOffset, fSin, fCos ),
960  pAct->GetWidth(), pAct->GetStrikeout(), pAct->GetUnderline(), pAct->GetOverline() ) );
961  }
962  break;
963 
965  {
966  MetaBmpScaleAction* pAct = static_cast<MetaBmpScaleAction*>(pAction);
967  tools::Polygon aBmpPoly( ImplGetRotatedPolygon( tools::Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
968  tools::Rectangle aBmpRect( aBmpPoly.GetBoundRect() );
969  BitmapEx aBmpEx( pAct->GetBitmap() );
970 
971  aBmpEx.Rotate( nAngle10, COL_TRANSPARENT );
972  aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(),
973  aBmpEx ) );
974  }
975  break;
976 
978  {
979  MetaBmpScalePartAction* pAct = static_cast<MetaBmpScalePartAction*>(pAction);
980  tools::Polygon aBmpPoly( ImplGetRotatedPolygon( tools::Rectangle( pAct->GetDestPoint(), pAct->GetDestSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
981  tools::Rectangle aBmpRect( aBmpPoly.GetBoundRect() );
982  BitmapEx aBmpEx( pAct->GetBitmap() );
983 
984  aBmpEx.Crop( tools::Rectangle( pAct->GetSrcPoint(), pAct->GetSrcSize() ) );
985  aBmpEx.Rotate( nAngle10, COL_TRANSPARENT );
986 
987  aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) );
988  }
989  break;
990 
992  {
993  MetaBmpExScaleAction* pAct = static_cast<MetaBmpExScaleAction*>(pAction);
994  tools::Polygon aBmpPoly( ImplGetRotatedPolygon( tools::Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
995  tools::Rectangle aBmpRect( aBmpPoly.GetBoundRect() );
996  BitmapEx aBmpEx( pAct->GetBitmapEx() );
997 
998  aBmpEx.Rotate( nAngle10, COL_TRANSPARENT );
999 
1000  aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) );
1001  }
1002  break;
1003 
1005  {
1006  MetaBmpExScalePartAction* pAct = static_cast<MetaBmpExScalePartAction*>(pAction);
1007  tools::Polygon aBmpPoly( ImplGetRotatedPolygon( tools::Rectangle( pAct->GetDestPoint(), pAct->GetDestSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1008  tools::Rectangle aBmpRect( aBmpPoly.GetBoundRect() );
1009  BitmapEx aBmpEx( pAct->GetBitmapEx() );
1010 
1011  aBmpEx.Crop( tools::Rectangle( pAct->GetSrcPoint(), pAct->GetSrcSize() ) );
1012  aBmpEx.Rotate( nAngle10, COL_TRANSPARENT );
1013 
1014  aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) );
1015  }
1016  break;
1017 
1019  {
1020  MetaGradientAction* pAct = static_cast<MetaGradientAction*>(pAction);
1021 
1022  ImplAddGradientEx( aMtf, *aMapVDev,
1023  ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ),
1024  pAct->GetGradient() );
1025  }
1026  break;
1027 
1029  {
1030  MetaGradientExAction* pAct = static_cast<MetaGradientExAction*>(pAction);
1031  aMtf.AddAction( new MetaGradientExAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1032  pAct->GetGradient() ) );
1033  }
1034  break;
1035 
1036  // Handle gradientex comment block correctly
1038  {
1039  MetaCommentAction* pCommentAct = static_cast<MetaCommentAction*>(pAction);
1040  if( pCommentAct->GetComment() == "XGRAD_SEQ_BEGIN" )
1041  {
1042  int nBeginComments( 1 );
1043  pAction = NextAction();
1044 
1045  // skip everything, except gradientex action
1046  while( pAction )
1047  {
1048  const MetaActionType nType = pAction->GetType();
1049 
1050  if( MetaActionType::GRADIENTEX == nType )
1051  {
1052  // Add rotated gradientex
1053  MetaGradientExAction* pAct = static_cast<MetaGradientExAction*>(pAction);
1054  ImplAddGradientEx( aMtf, *aMapVDev,
1055  ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1056  pAct->GetGradient() );
1057  }
1058  else if( MetaActionType::COMMENT == nType)
1059  {
1060  MetaCommentAction* pAct = static_cast<MetaCommentAction*>(pAction);
1061  if( pAct->GetComment() == "XGRAD_SEQ_END" )
1062  {
1063  // handle nested blocks
1064  --nBeginComments;
1065 
1066  // gradientex comment block: end reached, done.
1067  if( !nBeginComments )
1068  break;
1069  }
1070  else if( pAct->GetComment() == "XGRAD_SEQ_BEGIN" )
1071  {
1072  // handle nested blocks
1073  ++nBeginComments;
1074  }
1075 
1076  }
1077 
1078  pAction =NextAction();
1079  }
1080  }
1081  else
1082  {
1083  bool bPathStroke = (pCommentAct->GetComment() == "XPATHSTROKE_SEQ_BEGIN");
1084  if ( bPathStroke || pCommentAct->GetComment() == "XPATHFILL_SEQ_BEGIN" )
1085  {
1086  if ( pCommentAct->GetDataSize() )
1087  {
1088  SvMemoryStream aMemStm( const_cast<sal_uInt8 *>(pCommentAct->GetData()), pCommentAct->GetDataSize(), StreamMode::READ );
1089  SvMemoryStream aDest;
1090  if ( bPathStroke )
1091  {
1092  SvtGraphicStroke aStroke;
1093  ReadSvtGraphicStroke( aMemStm, aStroke );
1094  tools::Polygon aPath;
1095  aStroke.getPath( aPath );
1096  aStroke.setPath( ImplGetRotatedPolygon( aPath, aRotAnchor, aRotOffset, fSin, fCos ) );
1097  WriteSvtGraphicStroke( aDest, aStroke );
1098  aMtf.AddAction( new MetaCommentAction( "XPATHSTROKE_SEQ_BEGIN", 0,
1099  static_cast<const sal_uInt8*>( aDest.GetData()), aDest.Tell() ) );
1100  }
1101  else
1102  {
1103  SvtGraphicFill aFill;
1104  ReadSvtGraphicFill( aMemStm, aFill );
1105  tools::PolyPolygon aPath;
1106  aFill.getPath( aPath );
1107  aFill.setPath( ImplGetRotatedPolyPolygon( aPath, aRotAnchor, aRotOffset, fSin, fCos ) );
1108  WriteSvtGraphicFill( aDest, aFill );
1109  aMtf.AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
1110  static_cast<const sal_uInt8*>( aDest.GetData()), aDest.Tell() ) );
1111  }
1112  }
1113  }
1114  else if ( pCommentAct->GetComment() == "XPATHSTROKE_SEQ_END"
1115  || pCommentAct->GetComment() == "XPATHFILL_SEQ_END" )
1116  {
1117  pAction->Execute( aMapVDev.get() );
1118  aMtf.AddAction( pAction );
1119  }
1120  }
1121  }
1122  break;
1123 
1124  case MetaActionType::HATCH:
1125  {
1126  MetaHatchAction* pAct = static_cast<MetaHatchAction*>(pAction);
1127  Hatch aHatch( pAct->GetHatch() );
1128 
1129  aHatch.SetAngle( aHatch.GetAngle() + static_cast<sal_uInt16>(nAngle10) );
1130  aMtf.AddAction( new MetaHatchAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1131  aHatch ) );
1132  }
1133  break;
1134 
1136  {
1137  MetaTransparentAction* pAct = static_cast<MetaTransparentAction*>(pAction);
1138  aMtf.AddAction( new MetaTransparentAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ),
1139  pAct->GetTransparence() ) );
1140  }
1141  break;
1142 
1144  {
1145  MetaFloatTransparentAction* pAct = static_cast<MetaFloatTransparentAction*>(pAction);
1146  GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() );
1147  tools::Polygon aMtfPoly( ImplGetRotatedPolygon( tools::Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1148  tools::Rectangle aMtfRect( aMtfPoly.GetBoundRect() );
1149 
1150  aTransMtf.Rotate( nAngle10 );
1151  aMtf.AddAction( new MetaFloatTransparentAction( aTransMtf, aMtfRect.TopLeft(), aMtfRect.GetSize(),
1152  pAct->GetGradient() ) );
1153  }
1154  break;
1155 
1156  case MetaActionType::EPS:
1157  {
1158  MetaEPSAction* pAct = static_cast<MetaEPSAction*>(pAction);
1159  GDIMetaFile aEPSMtf( pAct->GetSubstitute() );
1160  tools::Polygon aEPSPoly( ImplGetRotatedPolygon( tools::Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) );
1161  tools::Rectangle aEPSRect( aEPSPoly.GetBoundRect() );
1162 
1163  aEPSMtf.Rotate( nAngle10 );
1164  aMtf.AddAction( new MetaEPSAction( aEPSRect.TopLeft(), aEPSRect.GetSize(),
1165  pAct->GetLink(), aEPSMtf ) );
1166  }
1167  break;
1168 
1170  {
1171  MetaClipRegionAction* pAct = static_cast<MetaClipRegionAction*>(pAction);
1172 
1173  if( pAct->IsClipping() && pAct->GetRegion().HasPolyPolygonOrB2DPolyPolygon() )
1174  aMtf.AddAction( new MetaClipRegionAction( vcl::Region( ImplGetRotatedPolyPolygon( pAct->GetRegion().GetAsPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ), true ) );
1175  else
1176  {
1177  aMtf.AddAction( pAction );
1178  }
1179  }
1180  break;
1181 
1183  {
1184  MetaISectRectClipRegionAction* pAct = static_cast<MetaISectRectClipRegionAction*>(pAction);
1186  ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor,
1187  aRotOffset, fSin, fCos )) ) );
1188  }
1189  break;
1190 
1192  {
1194  const vcl::Region& rRegion = pAct->GetRegion();
1195 
1196  if( rRegion.HasPolyPolygonOrB2DPolyPolygon() )
1197  aMtf.AddAction( new MetaISectRegionClipRegionAction( vcl::Region( ImplGetRotatedPolyPolygon( rRegion.GetAsPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) ) );
1198  else
1199  {
1200  aMtf.AddAction( pAction );
1201  }
1202  }
1203  break;
1204 
1206  {
1207  MetaRefPointAction* pAct = static_cast<MetaRefPointAction*>(pAction);
1208  aMtf.AddAction( new MetaRefPointAction( ImplGetRotatedPoint( pAct->GetRefPoint(), aRotAnchor, aRotOffset, fSin, fCos ), pAct->IsSetting() ) );
1209  }
1210  break;
1211 
1212  case MetaActionType::FONT:
1213  {
1214  MetaFontAction* pAct = static_cast<MetaFontAction*>(pAction);
1215  vcl::Font aFont( pAct->GetFont() );
1216 
1217  aFont.SetOrientation( aFont.GetOrientation() + static_cast<sal_uInt16>(nAngle10) );
1218  aMtf.AddAction( new MetaFontAction( aFont ) );
1219  }
1220  break;
1221 
1222  case MetaActionType::BMP:
1223  case MetaActionType::BMPEX:
1224  case MetaActionType::MASK:
1230  {
1231  OSL_FAIL( "GDIMetaFile::Rotate(): unsupported action" );
1232  }
1233  break;
1234 
1235  default:
1236  {
1237  pAction->Execute( aMapVDev.get() );
1238  aMtf.AddAction( pAction );
1239 
1240  // update rotation point and offset, if necessary
1241  if( ( MetaActionType::MAPMODE == nActionType ) ||
1242  ( MetaActionType::PUSH == nActionType ) ||
1243  ( MetaActionType::POP == nActionType ) )
1244  {
1245  aRotAnchor = OutputDevice::LogicToLogic( aOrigin, m_aPrefMapMode, aMapVDev->GetMapMode() );
1246  aRotOffset = OutputDevice::LogicToLogic( aOffset, m_aPrefMapMode, aMapVDev->GetMapMode() );
1247  }
1248  }
1249  break;
1250  }
1251  }
1252 
1254  aMtf.m_aPrefSize = aNewBound.GetSize();
1255 
1256  *this = aMtf;
1257 
1258 }
1259 
1260 static void ImplActionBounds( tools::Rectangle& o_rOutBounds,
1261  const tools::Rectangle& i_rInBounds,
1262  const std::vector<tools::Rectangle>& i_rClipStack,
1263  tools::Rectangle* o_pHairline )
1264 {
1265  tools::Rectangle aBounds( i_rInBounds );
1266  if( ! i_rInBounds.IsEmpty() && ! i_rClipStack.empty() && ! i_rClipStack.back().IsEmpty() )
1267  aBounds.Intersection( i_rClipStack.back() );
1268  if( ! aBounds.IsEmpty() )
1269  {
1270  if( ! o_rOutBounds.IsEmpty() )
1271  o_rOutBounds.Union( aBounds );
1272  else
1273  o_rOutBounds = aBounds;
1274 
1275  if(o_pHairline)
1276  {
1277  if( ! o_pHairline->IsEmpty() )
1278  o_pHairline->Union( aBounds );
1279  else
1280  *o_pHairline = aBounds;
1281  }
1282  }
1283 }
1284 
1286 {
1287  GDIMetaFile aMtf;
1288  ScopedVclPtrInstance< VirtualDevice > aMapVDev( i_rReference );
1289 
1290  aMapVDev->EnableOutput( false );
1291  aMapVDev->SetMapMode( GetPrefMapMode() );
1292 
1293  std::vector<tools::Rectangle> aClipStack( 1, tools::Rectangle() );
1294  std::vector<PushFlags> aPushFlagStack;
1295 
1296  tools::Rectangle aBound;
1297 
1298  if(pHairline)
1299  *pHairline = tools::Rectangle();
1300 
1301  const sal_uLong nCount(GetActionSize());
1302 
1303  for(sal_uLong a(0); a < nCount; a++)
1304  {
1305  MetaAction* pAction = GetAction(a);
1306  const MetaActionType nActionType = pAction->GetType();
1307  tools::Rectangle* pUseHairline = (pHairline && aMapVDev->IsLineColor()) ? pHairline : nullptr;
1308 
1309  switch( nActionType )
1310  {
1311  case MetaActionType::PIXEL:
1312  {
1313  MetaPixelAction* pAct = static_cast<MetaPixelAction*>(pAction);
1314  ImplActionBounds( aBound,
1315  tools::Rectangle( OutputDevice::LogicToLogic( pAct->GetPoint(), aMapVDev->GetMapMode(), GetPrefMapMode() ),
1316  aMapVDev->PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
1317  aClipStack, pUseHairline );
1318  }
1319  break;
1320 
1321  case MetaActionType::POINT:
1322  {
1323  MetaPointAction* pAct = static_cast<MetaPointAction*>(pAction);
1324  ImplActionBounds( aBound,
1325  tools::Rectangle( OutputDevice::LogicToLogic( pAct->GetPoint(), aMapVDev->GetMapMode(), GetPrefMapMode() ),
1326  aMapVDev->PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
1327  aClipStack, pUseHairline );
1328  }
1329  break;
1330 
1331  case MetaActionType::LINE:
1332  {
1333  MetaLineAction* pAct = static_cast<MetaLineAction*>(pAction);
1334  Point aP1( pAct->GetStartPoint() ), aP2( pAct->GetEndPoint() );
1335  tools::Rectangle aRect( aP1, aP2 );
1336  aRect.Justify();
1337 
1338  if(pUseHairline)
1339  {
1340  const LineInfo& rLineInfo = pAct->GetLineInfo();
1341 
1342  if(0 != rLineInfo.GetWidth())
1343  pUseHairline = nullptr;
1344  }
1345 
1346  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1347  }
1348  break;
1349 
1350  case MetaActionType::RECT:
1351  {
1352  MetaRectAction* pAct = static_cast<MetaRectAction*>(pAction);
1353  ImplActionBounds( aBound, OutputDevice::LogicToLogic( pAct->GetRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1354  }
1355  break;
1356 
1358  {
1359  MetaRoundRectAction* pAct = static_cast<MetaRoundRectAction*>(pAction);
1360  ImplActionBounds( aBound, OutputDevice::LogicToLogic( pAct->GetRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1361  }
1362  break;
1363 
1365  {
1366  MetaEllipseAction* pAct = static_cast<MetaEllipseAction*>(pAction);
1367  ImplActionBounds( aBound, OutputDevice::LogicToLogic( pAct->GetRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1368  }
1369  break;
1370 
1371  case MetaActionType::ARC:
1372  {
1373  MetaArcAction* pAct = static_cast<MetaArcAction*>(pAction);
1374  // FIXME: this is imprecise
1375  // e.g. for small arcs the whole rectangle is WAY too large
1376  ImplActionBounds( aBound, OutputDevice::LogicToLogic( pAct->GetRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1377  }
1378  break;
1379 
1380  case MetaActionType::PIE:
1381  {
1382  MetaPieAction* pAct = static_cast<MetaPieAction*>(pAction);
1383  // FIXME: this is imprecise
1384  // e.g. for small arcs the whole rectangle is WAY too large
1385  ImplActionBounds( aBound, OutputDevice::LogicToLogic( pAct->GetRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1386  }
1387  break;
1388 
1389  case MetaActionType::CHORD:
1390  {
1391  MetaChordAction* pAct = static_cast<MetaChordAction*>(pAction);
1392  // FIXME: this is imprecise
1393  // e.g. for small arcs the whole rectangle is WAY too large
1394  ImplActionBounds( aBound, OutputDevice::LogicToLogic( pAct->GetRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1395  }
1396  break;
1397 
1399  {
1400  MetaPolyLineAction* pAct = static_cast<MetaPolyLineAction*>(pAction);
1401  tools::Rectangle aRect( pAct->GetPolygon().GetBoundRect() );
1402 
1403  if(pUseHairline)
1404  {
1405  const LineInfo& rLineInfo = pAct->GetLineInfo();
1406 
1407  if(0 != rLineInfo.GetWidth())
1408  pUseHairline = nullptr;
1409  }
1410 
1411  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1412  }
1413  break;
1414 
1416  {
1417  MetaPolygonAction* pAct = static_cast<MetaPolygonAction*>(pAction);
1418  tools::Rectangle aRect( pAct->GetPolygon().GetBoundRect() );
1419  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1420  }
1421  break;
1422 
1424  {
1425  MetaPolyPolygonAction* pAct = static_cast<MetaPolyPolygonAction*>(pAction);
1426  tools::Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1427  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, pUseHairline );
1428  }
1429  break;
1430 
1431  case MetaActionType::TEXT:
1432  {
1433  MetaTextAction* pAct = static_cast<MetaTextAction*>(pAction);
1434  tools::Rectangle aRect;
1435  // hdu said base = index
1436  aMapVDev->GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen() );
1437  Point aPt( pAct->GetPoint() );
1438  aRect.Move( aPt.X(), aPt.Y() );
1439  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1440  }
1441  break;
1442 
1444  {
1445  MetaTextArrayAction* pAct = static_cast<MetaTextArrayAction*>(pAction);
1446  tools::Rectangle aRect;
1447  // hdu said base = index
1448  aMapVDev->GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(),
1449  0, pAct->GetDXArray() );
1450  Point aPt( pAct->GetPoint() );
1451  aRect.Move( aPt.X(), aPt.Y() );
1452  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1453  }
1454  break;
1455 
1457  {
1458  MetaStretchTextAction* pAct = static_cast<MetaStretchTextAction*>(pAction);
1459  tools::Rectangle aRect;
1460  // hdu said base = index
1461  aMapVDev->GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(),
1462  pAct->GetWidth() );
1463  Point aPt( pAct->GetPoint() );
1464  aRect.Move( aPt.X(), aPt.Y() );
1465  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1466  }
1467  break;
1468 
1470  {
1471  MetaTextLineAction* pAct = static_cast<MetaTextLineAction*>(pAction);
1472  // measure a test string to get ascend and descent right
1473  static const sal_Unicode pStr[] = { 0xc4, 0x67, 0 };
1474  OUString aStr( pStr );
1475 
1476  tools::Rectangle aRect;
1477  aMapVDev->GetTextBoundRect( aRect, aStr, 0, 0, aStr.getLength() );
1478  Point aPt( pAct->GetStartPoint() );
1479  aRect.Move( aPt.X(), aPt.Y() );
1480  aRect.SetRight( aRect.Left() + pAct->GetWidth() );
1481  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1482  }
1483  break;
1484 
1486  {
1487  MetaBmpScaleAction* pAct = static_cast<MetaBmpScaleAction*>(pAction);
1488  tools::Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1489  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1490  }
1491  break;
1492 
1494  {
1495  MetaBmpScalePartAction* pAct = static_cast<MetaBmpScalePartAction*>(pAction);
1496  tools::Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1497  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1498  }
1499  break;
1500 
1502  {
1503  MetaBmpExScaleAction* pAct = static_cast<MetaBmpExScaleAction*>(pAction);
1504  tools::Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1505  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1506  }
1507  break;
1508 
1510  {
1511  MetaBmpExScalePartAction* pAct = static_cast<MetaBmpExScalePartAction*>(pAction);
1512  tools::Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1513  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1514  }
1515  break;
1516 
1518  {
1519  MetaGradientAction* pAct = static_cast<MetaGradientAction*>(pAction);
1520  tools::Rectangle aRect( pAct->GetRect() );
1521  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1522  }
1523  break;
1524 
1526  {
1527  MetaGradientExAction* pAct = static_cast<MetaGradientExAction*>(pAction);
1528  tools::Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1529  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1530  }
1531  break;
1532 
1534  {
1535  // nothing to do
1536  };
1537  break;
1538 
1539  case MetaActionType::HATCH:
1540  {
1541  MetaHatchAction* pAct = static_cast<MetaHatchAction*>(pAction);
1542  tools::Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1543  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1544  }
1545  break;
1546 
1548  {
1549  MetaTransparentAction* pAct = static_cast<MetaTransparentAction*>(pAction);
1550  tools::Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
1551  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1552  }
1553  break;
1554 
1556  {
1557  MetaFloatTransparentAction* pAct = static_cast<MetaFloatTransparentAction*>(pAction);
1558  // MetaFloatTransparentAction is defined limiting its content Metafile
1559  // to its geometry definition(Point, Size), so use these directly
1560  const tools::Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1561  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1562  }
1563  break;
1564 
1565  case MetaActionType::EPS:
1566  {
1567  MetaEPSAction* pAct = static_cast<MetaEPSAction*>(pAction);
1568  tools::Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
1569  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1570  }
1571  break;
1572 
1574  {
1575  MetaClipRegionAction* pAct = static_cast<MetaClipRegionAction*>(pAction);
1576  if( pAct->IsClipping() )
1577  aClipStack.back() = OutputDevice::LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev->GetMapMode(), GetPrefMapMode() );
1578  else
1579  aClipStack.back() = tools::Rectangle();
1580  }
1581  break;
1582 
1584  {
1585  MetaISectRectClipRegionAction* pAct = static_cast<MetaISectRectClipRegionAction*>(pAction);
1586  tools::Rectangle aRect( OutputDevice::LogicToLogic( pAct->GetRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ) );
1587  if( aClipStack.back().IsEmpty() )
1588  aClipStack.back() = aRect;
1589  else
1590  aClipStack.back().Intersection( aRect );
1591  }
1592  break;
1593 
1595  {
1597  tools::Rectangle aRect( OutputDevice::LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev->GetMapMode(), GetPrefMapMode() ) );
1598  if( aClipStack.back().IsEmpty() )
1599  aClipStack.back() = aRect;
1600  else
1601  aClipStack.back().Intersection( aRect );
1602  }
1603  break;
1604 
1605  case MetaActionType::BMP:
1606  {
1607  MetaBmpAction* pAct = static_cast<MetaBmpAction*>(pAction);
1608  tools::Rectangle aRect( pAct->GetPoint(), aMapVDev->PixelToLogic( pAct->GetBitmap().GetSizePixel() ) );
1609  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1610  }
1611  break;
1612 
1613  case MetaActionType::BMPEX:
1614  {
1615  MetaBmpExAction* pAct = static_cast<MetaBmpExAction*>(pAction);
1616  tools::Rectangle aRect( pAct->GetPoint(), aMapVDev->PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) );
1617  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1618  }
1619  break;
1620 
1621  case MetaActionType::MASK:
1622  {
1623  MetaMaskAction* pAct = static_cast<MetaMaskAction*>(pAction);
1624  tools::Rectangle aRect( pAct->GetPoint(), aMapVDev->PixelToLogic( pAct->GetBitmap().GetSizePixel() ) );
1625  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1626  }
1627  break;
1628 
1630  {
1631  MetaMaskScalePartAction* pAct = static_cast<MetaMaskScalePartAction*>(pAction);
1632  tools::Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1633  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1634  }
1635  break;
1636 
1638  {
1639  MetaMaskScalePartAction* pAct = static_cast<MetaMaskScalePartAction*>(pAction);
1640  tools::Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
1641  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1642  }
1643  break;
1644 
1646  {
1647  MetaWallpaperAction* pAct = static_cast<MetaWallpaperAction*>(pAction);
1648  tools::Rectangle aRect( pAct->GetRect() );
1649  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1650  }
1651  break;
1652 
1654  {
1655  MetaTextRectAction* pAct = static_cast<MetaTextRectAction*>(pAction);
1656  tools::Rectangle aRect( pAct->GetRect() );
1657  ImplActionBounds( aBound, OutputDevice::LogicToLogic( aRect, aMapVDev->GetMapMode(), GetPrefMapMode() ), aClipStack, nullptr );
1658  }
1659  break;
1660 
1662  {
1663  MetaMoveClipRegionAction* pAct = static_cast<MetaMoveClipRegionAction*>(pAction);
1664  if( ! aClipStack.back().IsEmpty() )
1665  {
1666  Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() );
1667  aDelta = OutputDevice::LogicToLogic( aDelta, aMapVDev->GetMapMode(), GetPrefMapMode() );
1668  aClipStack.back().Move( aDelta.Width(), aDelta.Width() );
1669  }
1670  }
1671  break;
1672 
1673  default:
1674  {
1675  pAction->Execute( aMapVDev.get() );
1676 
1677  if( nActionType == MetaActionType::PUSH )
1678  {
1679  MetaPushAction* pAct = static_cast<MetaPushAction*>(pAction);
1680  aPushFlagStack.push_back( pAct->GetFlags() );
1681  if( aPushFlagStack.back() & PushFlags::CLIPREGION )
1682  {
1683  tools::Rectangle aRect( aClipStack.back() );
1684  aClipStack.push_back( aRect );
1685  }
1686  }
1687  else if( nActionType == MetaActionType::POP )
1688  {
1689  // sanity check
1690  if( ! aPushFlagStack.empty() )
1691  {
1692  if( aPushFlagStack.back() & PushFlags::CLIPREGION )
1693  {
1694  if( aClipStack.size() > 1 )
1695  aClipStack.pop_back();
1696  }
1697  aPushFlagStack.pop_back();
1698  }
1699  }
1700  }
1701  break;
1702  }
1703  }
1704  return aBound;
1705 }
1706 
1707 Color GDIMetaFile::ImplColAdjustFnc( const Color& rColor, const void* pColParam )
1708 {
1709  return Color( rColor.GetTransparency(),
1710  static_cast<const ImplColAdjustParam*>(pColParam)->pMapR[ rColor.GetRed() ],
1711  static_cast<const ImplColAdjustParam*>(pColParam)->pMapG[ rColor.GetGreen() ],
1712  static_cast<const ImplColAdjustParam*>(pColParam)->pMapB[ rColor.GetBlue() ] );
1713 
1714 }
1715 
1716 BitmapEx GDIMetaFile::ImplBmpAdjustFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
1717 {
1718  const ImplBmpAdjustParam* p = static_cast<const ImplBmpAdjustParam*>(pBmpParam);
1719  BitmapEx aRet( rBmpEx );
1720 
1721  aRet.Adjust( p->nLuminancePercent, p->nContrastPercent,
1722  p->nChannelRPercent, p->nChannelGPercent, p->nChannelBPercent,
1723  p->fGamma, p->bInvert );
1724 
1725  return aRet;
1726 }
1727 
1728 Color GDIMetaFile::ImplColConvertFnc( const Color& rColor, const void* pColParam )
1729 {
1730  sal_uInt8 cLum = rColor.GetLuminance();
1731 
1732  if( MtfConversion::N1BitThreshold == static_cast<const ImplColConvertParam*>(pColParam)->eConversion )
1733  cLum = ( cLum < 128 ) ? 0 : 255;
1734 
1735  return Color( rColor.GetTransparency(), cLum, cLum, cLum );
1736 }
1737 
1738 BitmapEx GDIMetaFile::ImplBmpConvertFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
1739 {
1740  BitmapEx aRet( rBmpEx );
1741 
1742  aRet.Convert( static_cast<const ImplBmpConvertParam*>(pBmpParam)->eConversion );
1743 
1744  return aRet;
1745 }
1746 
1747 Color GDIMetaFile::ImplColMonoFnc( const Color&, const void* pColParam )
1748 {
1749  return static_cast<const ImplColMonoParam*>(pColParam)->aColor;
1750 }
1751 
1752 BitmapEx GDIMetaFile::ImplBmpMonoFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
1753 {
1754  BitmapPalette aPal( 3 );
1755 
1756  aPal[ 0 ] = COL_BLACK;
1757  aPal[ 1 ] = COL_WHITE;
1758  aPal[ 2 ] = static_cast<const ImplBmpMonoParam*>(pBmpParam)->aColor;
1759 
1760  Bitmap aBmp( rBmpEx.GetSizePixel(), 4, &aPal );
1761  aBmp.Erase( static_cast<const ImplBmpMonoParam*>(pBmpParam)->aColor );
1762 
1763  if( rBmpEx.IsAlpha() )
1764  return BitmapEx( aBmp, rBmpEx.GetAlpha() );
1765  else if( rBmpEx.IsTransparent() )
1766  return BitmapEx( aBmp, rBmpEx.GetMask() );
1767  else
1768  return BitmapEx( aBmp );
1769 }
1770 
1771 Color GDIMetaFile::ImplColReplaceFnc( const Color& rColor, const void* pColParam )
1772 {
1773  const sal_uLong nR = rColor.GetRed(), nG = rColor.GetGreen(), nB = rColor.GetBlue();
1774 
1775  for( sal_uLong i = 0; i < static_cast<const ImplColReplaceParam*>(pColParam)->nCount; i++ )
1776  {
1777  if( ( static_cast<const ImplColReplaceParam*>(pColParam)->pMinR[ i ] <= nR ) &&
1778  ( static_cast<const ImplColReplaceParam*>(pColParam)->pMaxR[ i ] >= nR ) &&
1779  ( static_cast<const ImplColReplaceParam*>(pColParam)->pMinG[ i ] <= nG ) &&
1780  ( static_cast<const ImplColReplaceParam*>(pColParam)->pMaxG[ i ] >= nG ) &&
1781  ( static_cast<const ImplColReplaceParam*>(pColParam)->pMinB[ i ] <= nB ) &&
1782  ( static_cast<const ImplColReplaceParam*>(pColParam)->pMaxB[ i ] >= nB ) )
1783  {
1784  return static_cast<const ImplColReplaceParam*>(pColParam)->pDstCols[ i ];
1785  }
1786  }
1787 
1788  return rColor;
1789 }
1790 
1791 BitmapEx GDIMetaFile::ImplBmpReplaceFnc( const BitmapEx& rBmpEx, const void* pBmpParam )
1792 {
1793  const ImplBmpReplaceParam* p = static_cast<const ImplBmpReplaceParam*>(pBmpParam);
1794  BitmapEx aRet( rBmpEx );
1795 
1796  aRet.Replace( p->pSrcCols, p->pDstCols, p->nCount );
1797 
1798  return aRet;
1799 }
1800 
1801 void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pColParam,
1802  BmpExchangeFnc pFncBmp, const void* pBmpParam )
1803 {
1804  GDIMetaFile aMtf;
1805 
1806  aMtf.m_aPrefSize = m_aPrefSize;
1808  aMtf.m_bUseCanvas = m_bUseCanvas;
1809 
1810  for( MetaAction* pAction = FirstAction(); pAction; pAction = NextAction() )
1811  {
1812  const MetaActionType nType = pAction->GetType();
1813 
1814  switch( nType )
1815  {
1816  case MetaActionType::PIXEL:
1817  {
1818  MetaPixelAction* pAct = static_cast<MetaPixelAction*>(pAction);
1819  aMtf.push_back( new MetaPixelAction( pAct->GetPoint(), pFncCol( pAct->GetColor(), pColParam ) ) );
1820  }
1821  break;
1822 
1824  {
1825  MetaLineColorAction* pAct = static_cast<MetaLineColorAction*>(pAction);
1826 
1827  if( pAct->IsSetting() )
1828  pAct = new MetaLineColorAction( pFncCol( pAct->GetColor(), pColParam ), true );
1829 
1830  aMtf.push_back( pAct );
1831  }
1832  break;
1833 
1835  {
1836  MetaFillColorAction* pAct = static_cast<MetaFillColorAction*>(pAction);
1837 
1838  if( pAct->IsSetting() )
1839  pAct = new MetaFillColorAction( pFncCol( pAct->GetColor(), pColParam ), true );
1840 
1841  aMtf.push_back( pAct );
1842  }
1843  break;
1844 
1846  {
1847  MetaTextColorAction* pAct = static_cast<MetaTextColorAction*>(pAction);
1848  aMtf.push_back( new MetaTextColorAction( pFncCol( pAct->GetColor(), pColParam ) ) );
1849  }
1850  break;
1851 
1853  {
1854  MetaTextFillColorAction* pAct = static_cast<MetaTextFillColorAction*>(pAction);
1855 
1856  if( pAct->IsSetting() )
1857  pAct = new MetaTextFillColorAction( pFncCol( pAct->GetColor(), pColParam ), true );
1858 
1859  aMtf.push_back( pAct );
1860  }
1861  break;
1862 
1864  {
1865  MetaTextLineColorAction* pAct = static_cast<MetaTextLineColorAction*>(pAction);
1866 
1867  if( pAct->IsSetting() )
1868  pAct = new MetaTextLineColorAction( pFncCol( pAct->GetColor(), pColParam ), true );
1869 
1870  aMtf.push_back( pAct );
1871  }
1872  break;
1873 
1875  {
1876  MetaOverlineColorAction* pAct = static_cast<MetaOverlineColorAction*>(pAction);
1877 
1878  if( pAct->IsSetting() )
1879  pAct = new MetaOverlineColorAction( pFncCol( pAct->GetColor(), pColParam ), true );
1880 
1881  aMtf.push_back( pAct );
1882  }
1883  break;
1884 
1885  case MetaActionType::FONT:
1886  {
1887  MetaFontAction* pAct = static_cast<MetaFontAction*>(pAction);
1888  vcl::Font aFont( pAct->GetFont() );
1889 
1890  aFont.SetColor( pFncCol( aFont.GetColor(), pColParam ) );
1891  aFont.SetFillColor( pFncCol( aFont.GetFillColor(), pColParam ) );
1892  aMtf.push_back( new MetaFontAction( aFont ) );
1893  }
1894  break;
1895 
1897  {
1898  MetaWallpaperAction* pAct = static_cast<MetaWallpaperAction*>(pAction);
1899  Wallpaper aWall( pAct->GetWallpaper() );
1900  const tools::Rectangle& rRect = pAct->GetRect();
1901 
1902  aWall.SetColor( pFncCol( aWall.GetColor(), pColParam ) );
1903 
1904  if( aWall.IsBitmap() )
1905  aWall.SetBitmap( pFncBmp( aWall.GetBitmap(), pBmpParam ) );
1906 
1907  if( aWall.IsGradient() )
1908  {
1909  Gradient aGradient( aWall.GetGradient() );
1910 
1911  aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
1912  aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
1913  aWall.SetGradient( aGradient );
1914  }
1915 
1916  aMtf.push_back( new MetaWallpaperAction( rRect, aWall ) );
1917  }
1918  break;
1919 
1920  case MetaActionType::BMP:
1921  case MetaActionType::BMPEX:
1922  case MetaActionType::MASK:
1923  {
1924  OSL_FAIL( "Don't use bitmap actions of this type in metafiles!" );
1925  }
1926  break;
1927 
1929  {
1930  MetaBmpScaleAction* pAct = static_cast<MetaBmpScaleAction*>(pAction);
1931  aMtf.push_back( new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(),
1932  pFncBmp( BitmapEx(pAct->GetBitmap()), pBmpParam ).GetBitmap() ) );
1933  }
1934  break;
1935 
1937  {
1938  MetaBmpScalePartAction* pAct = static_cast<MetaBmpScalePartAction*>(pAction);
1939  aMtf.push_back( new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
1940  pAct->GetSrcPoint(), pAct->GetSrcSize(),
1941  pFncBmp( BitmapEx(pAct->GetBitmap()), pBmpParam ).GetBitmap() )
1942  );
1943  }
1944  break;
1945 
1947  {
1948  MetaBmpExScaleAction* pAct = static_cast<MetaBmpExScaleAction*>(pAction);
1949  aMtf.push_back( new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(),
1950  pFncBmp( pAct->GetBitmapEx(), pBmpParam ) )
1951  );
1952  }
1953  break;
1954 
1956  {
1957  MetaBmpExScalePartAction* pAct = static_cast<MetaBmpExScalePartAction*>(pAction);
1958  aMtf.push_back( new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
1959  pAct->GetSrcPoint(), pAct->GetSrcSize(),
1960  pFncBmp( pAct->GetBitmapEx(), pBmpParam ) )
1961  );
1962  }
1963  break;
1964 
1966  {
1967  MetaMaskScaleAction* pAct = static_cast<MetaMaskScaleAction*>(pAction);
1968  aMtf.push_back( new MetaMaskScaleAction( pAct->GetPoint(), pAct->GetSize(),
1969  pAct->GetBitmap(),
1970  pFncCol( pAct->GetColor(), pColParam ) )
1971  );
1972  }
1973  break;
1974 
1976  {
1977  MetaMaskScalePartAction* pAct = static_cast<MetaMaskScalePartAction*>(pAction);
1978  aMtf.push_back( new MetaMaskScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(),
1979  pAct->GetSrcPoint(), pAct->GetSrcSize(),
1980  pAct->GetBitmap(),
1981  pFncCol( pAct->GetColor(), pColParam ) )
1982  );
1983  }
1984  break;
1985 
1987  {
1988  MetaGradientAction* pAct = static_cast<MetaGradientAction*>(pAction);
1989  Gradient aGradient( pAct->GetGradient() );
1990 
1991  aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
1992  aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
1993  aMtf.push_back( new MetaGradientAction( pAct->GetRect(), aGradient ) );
1994  }
1995  break;
1996 
1998  {
1999  MetaGradientExAction* pAct = static_cast<MetaGradientExAction*>(pAction);
2000  Gradient aGradient( pAct->GetGradient() );
2001 
2002  aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) );
2003  aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) );
2004  aMtf.push_back( new MetaGradientExAction( pAct->GetPolyPolygon(), aGradient ) );
2005  }
2006  break;
2007 
2008  case MetaActionType::HATCH:
2009  {
2010  MetaHatchAction* pAct = static_cast<MetaHatchAction*>(pAction);
2011  Hatch aHatch( pAct->GetHatch() );
2012 
2013  aHatch.SetColor( pFncCol( aHatch.GetColor(), pColParam ) );
2014  aMtf.push_back( new MetaHatchAction( pAct->GetPolyPolygon(), aHatch ) );
2015  }
2016  break;
2017 
2019  {
2020  MetaFloatTransparentAction* pAct = static_cast<MetaFloatTransparentAction*>(pAction);
2021  GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() );
2022 
2023  aTransMtf.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam );
2024  aMtf.push_back( new MetaFloatTransparentAction( aTransMtf,
2025  pAct->GetPoint(), pAct->GetSize(),
2026  pAct->GetGradient() )
2027  );
2028  }
2029  break;
2030 
2031  case MetaActionType::EPS:
2032  {
2033  MetaEPSAction* pAct = static_cast<MetaEPSAction*>(pAction);
2034  GDIMetaFile aSubst( pAct->GetSubstitute() );
2035 
2036  aSubst.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam );
2037  aMtf.push_back( new MetaEPSAction( pAct->GetPoint(), pAct->GetSize(),
2038  pAct->GetLink(), aSubst )
2039  );
2040  }
2041  break;
2042 
2043  default:
2044  {
2045  aMtf.push_back( pAction );
2046  }
2047  break;
2048  }
2049  }
2050 
2051  *this = aMtf;
2052 }
2053 
2054 void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
2055  short nChannelRPercent, short nChannelGPercent,
2056  short nChannelBPercent, double fGamma, bool bInvert, bool msoBrightness )
2057 {
2058  // nothing to do? => return quickly
2059  if( !(nLuminancePercent || nContrastPercent ||
2060  nChannelRPercent || nChannelGPercent || nChannelBPercent ||
2061  ( fGamma != 1.0 ) || bInvert) )
2062  return;
2063 
2064  double fM, fROff, fGOff, fBOff, fOff;
2065  ImplColAdjustParam aColParam;
2066  ImplBmpAdjustParam aBmpParam;
2067 
2068  aColParam.pMapR.reset(new sal_uInt8[ 256 ]);
2069  aColParam.pMapG.reset(new sal_uInt8[ 256 ]);
2070  aColParam.pMapB.reset(new sal_uInt8[ 256 ]);
2071 
2072  // calculate slope
2073  if( nContrastPercent >= 0 )
2074  fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0, 100 ) );
2075  else
2076  fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100, 0 ) ) / 128.0;
2077 
2078  if(!msoBrightness)
2079  // total offset = luminance offset + contrast offset
2080  fOff = MinMax( nLuminancePercent, -100, 100 ) * 2.55 + 128.0 - fM * 128.0;
2081  else
2082  fOff = MinMax( nLuminancePercent, -100, 100 ) * 2.55;
2083 
2084  // channel offset = channel offset + total offset
2085  fROff = nChannelRPercent * 2.55 + fOff;
2086  fGOff = nChannelGPercent * 2.55 + fOff;
2087  fBOff = nChannelBPercent * 2.55 + fOff;
2088 
2089  // calculate gamma value
2090  fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma );
2091  const bool bGamma = ( fGamma != 1.0 );
2092 
2093  // create mapping table
2094  for( long nX = 0; nX < 256; nX++ )
2095  {
2096  if(!msoBrightness)
2097  {
2098  aColParam.pMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fROff ), 0, 255 ));
2099  aColParam.pMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fGOff ), 0, 255 ));
2100  aColParam.pMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fBOff ), 0, 255 ));
2101  }
2102  else
2103  {
2104  aColParam.pMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fROff/2-128) * fM + 128 + fROff/2 ), 0, 255 ));
2105  aColParam.pMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fGOff/2-128) * fM + 128 + fGOff/2 ), 0, 255 ));
2106  aColParam.pMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fBOff/2-128) * fM + 128 + fBOff/2 ), 0, 255 ));
2107  }
2108  if( bGamma )
2109  {
2110  aColParam.pMapR[ nX ] = GAMMA( aColParam.pMapR[ nX ], fGamma );
2111  aColParam.pMapG[ nX ] = GAMMA( aColParam.pMapG[ nX ], fGamma );
2112  aColParam.pMapB[ nX ] = GAMMA( aColParam.pMapB[ nX ], fGamma );
2113  }
2114 
2115  if( bInvert )
2116  {
2117  aColParam.pMapR[ nX ] = ~aColParam.pMapR[ nX ];
2118  aColParam.pMapG[ nX ] = ~aColParam.pMapG[ nX ];
2119  aColParam.pMapB[ nX ] = ~aColParam.pMapB[ nX ];
2120  }
2121  }
2122 
2123  aBmpParam.nLuminancePercent = nLuminancePercent;
2124  aBmpParam.nContrastPercent = nContrastPercent;
2125  aBmpParam.nChannelRPercent = nChannelRPercent;
2126  aBmpParam.nChannelGPercent = nChannelGPercent;
2127  aBmpParam.nChannelBPercent = nChannelBPercent;
2128  aBmpParam.fGamma = fGamma;
2129  aBmpParam.bInvert = bInvert;
2130 
2131  // do color adjustment
2132  ImplExchangeColors( ImplColAdjustFnc, &aColParam, ImplBmpAdjustFnc, &aBmpParam );
2133 }
2134 
2136 {
2137  ImplColConvertParam aColParam;
2138  ImplBmpConvertParam aBmpParam;
2139 
2140  aColParam.eConversion = eConversion;
2141  aBmpParam.eConversion = ( MtfConversion::N1BitThreshold == eConversion ) ? BmpConversion::N1BitThreshold : BmpConversion::N8BitGreys;
2142 
2143  ImplExchangeColors( ImplColConvertFnc, &aColParam, ImplBmpConvertFnc, &aBmpParam );
2144 }
2145 
2146 void GDIMetaFile::ReplaceColors( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount )
2147 {
2148  ImplColReplaceParam aColParam;
2149  ImplBmpReplaceParam aBmpParam;
2150 
2151  aColParam.pMinR.reset(new sal_uLong[ nColorCount ]);
2152  aColParam.pMaxR.reset(new sal_uLong[ nColorCount ]);
2153  aColParam.pMinG.reset(new sal_uLong[ nColorCount ]);
2154  aColParam.pMaxG.reset(new sal_uLong[ nColorCount ]);
2155  aColParam.pMinB.reset(new sal_uLong[ nColorCount ]);
2156  aColParam.pMaxB.reset(new sal_uLong[ nColorCount ]);
2157 
2158  for( sal_uLong i = 0; i < nColorCount; i++ )
2159  {
2160  long nVal;
2161 
2162  nVal = pSearchColors[ i ].GetRed();
2163  aColParam.pMinR[ i ] = static_cast<sal_uLong>(std::max( nVal, 0L ));
2164  aColParam.pMaxR[ i ] = static_cast<sal_uLong>(std::min( nVal, 255L ));
2165 
2166  nVal = pSearchColors[ i ].GetGreen();
2167  aColParam.pMinG[ i ] = static_cast<sal_uLong>(std::max( nVal, 0L ));
2168  aColParam.pMaxG[ i ] = static_cast<sal_uLong>(std::min( nVal, 255L ));
2169 
2170  nVal = pSearchColors[ i ].GetBlue();
2171  aColParam.pMinB[ i ] = static_cast<sal_uLong>(std::max( nVal, 0L ));
2172  aColParam.pMaxB[ i ] = static_cast<sal_uLong>(std::min( nVal, 255L ));
2173  }
2174 
2175  aColParam.pDstCols = pReplaceColors;
2176  aColParam.nCount = nColorCount;
2177 
2178  aBmpParam.pSrcCols = pSearchColors;
2179  aBmpParam.pDstCols = pReplaceColors;
2180  aBmpParam.nCount = nColorCount;
2181 
2182  ImplExchangeColors( ImplColReplaceFnc, &aColParam, ImplBmpReplaceFnc, &aBmpParam );
2183 };
2184 
2186 {
2187  GDIMetaFile aRet( *this );
2188 
2189  ImplColMonoParam aColParam;
2190  ImplBmpMonoParam aBmpParam;
2191 
2192  aColParam.aColor = rColor;
2193  aBmpParam.aColor = rColor;
2194 
2195  aRet.ImplExchangeColors( ImplColMonoFnc, &aColParam, ImplBmpMonoFnc, &aBmpParam );
2196 
2197  return aRet;
2198 }
2199 
2201 {
2202  GDIMetaFile aMtf;
2203  SvMemoryStream aMemStm( 65535, 65535 );
2204  ImplMetaWriteData aWriteData;
2205  SVBT16 aBT16;
2206  SVBT32 aBT32;
2208  BitmapChecksum nCrc = 0;
2209 
2210  aWriteData.meActualCharSet = aMemStm.GetStreamCharSet();
2211  for( size_t i = 0, nObjCount = GetActionSize(); i < nObjCount; i++ )
2212  {
2213  MetaAction* pAction = GetAction( i );
2214 
2215  switch( pAction->GetType() )
2216  {
2217  case MetaActionType::BMP:
2218  {
2219  MetaBmpAction* pAct = static_cast<MetaBmpAction*>(pAction);
2220 
2221  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2222  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2223 
2224  BCToBCOA( pAct->GetBitmap().GetChecksum(), aBCOA );
2225  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2226 
2227  Int32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2228  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2229 
2230  Int32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2231  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2232  }
2233  break;
2234 
2236  {
2237  MetaBmpScaleAction* pAct = static_cast<MetaBmpScaleAction*>(pAction);
2238 
2239  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2240  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2241 
2242  BCToBCOA( pAct->GetBitmap().GetChecksum(), aBCOA );
2243  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2244 
2245  Int32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2246  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2247 
2248  Int32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2249  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2250 
2251  Int32ToSVBT32( pAct->GetSize().Width(), aBT32 );
2252  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2253 
2254  Int32ToSVBT32( pAct->GetSize().Height(), aBT32 );
2255  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2256  }
2257  break;
2258 
2260  {
2261  MetaBmpScalePartAction* pAct = static_cast<MetaBmpScalePartAction*>(pAction);
2262 
2263  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2264  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2265 
2266  BCToBCOA( pAct->GetBitmap().GetChecksum(), aBCOA );
2267  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2268 
2269  Int32ToSVBT32( pAct->GetDestPoint().X(), aBT32 );
2270  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2271 
2272  Int32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
2273  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2274 
2275  Int32ToSVBT32( pAct->GetDestSize().Width(), aBT32 );
2276  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2277 
2278  Int32ToSVBT32( pAct->GetDestSize().Height(), aBT32 );
2279  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2280 
2281  Int32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
2282  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2283 
2284  Int32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
2285  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2286 
2287  Int32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
2288  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2289 
2290  Int32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
2291  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2292  }
2293  break;
2294 
2295  case MetaActionType::BMPEX:
2296  {
2297  MetaBmpExAction* pAct = static_cast<MetaBmpExAction*>(pAction);
2298 
2299  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2300  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2301 
2302  BCToBCOA( pAct->GetBitmapEx().GetChecksum(), aBCOA );
2303  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2304 
2305  Int32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2306  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2307 
2308  Int32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2309  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2310  }
2311  break;
2312 
2314  {
2315  MetaBmpExScaleAction* pAct = static_cast<MetaBmpExScaleAction*>(pAction);
2316 
2317  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2318  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2319 
2320  BCToBCOA( pAct->GetBitmapEx().GetChecksum(), aBCOA );
2321  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2322 
2323  Int32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2324  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2325 
2326  Int32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2327  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2328 
2329  Int32ToSVBT32( pAct->GetSize().Width(), aBT32 );
2330  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2331 
2332  Int32ToSVBT32( pAct->GetSize().Height(), aBT32 );
2333  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2334  }
2335  break;
2336 
2338  {
2339  MetaBmpExScalePartAction* pAct = static_cast<MetaBmpExScalePartAction*>(pAction);
2340 
2341  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2342  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2343 
2344  BCToBCOA( pAct->GetBitmapEx().GetChecksum(), aBCOA );
2345  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2346 
2347  Int32ToSVBT32( pAct->GetDestPoint().X(), aBT32 );
2348  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2349 
2350  Int32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
2351  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2352 
2353  Int32ToSVBT32( pAct->GetDestSize().Width(), aBT32 );
2354  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2355 
2356  Int32ToSVBT32( pAct->GetDestSize().Height(), aBT32 );
2357  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2358 
2359  Int32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
2360  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2361 
2362  Int32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
2363  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2364 
2365  Int32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
2366  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2367 
2368  Int32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
2369  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2370  }
2371  break;
2372 
2373  case MetaActionType::MASK:
2374  {
2375  MetaMaskAction* pAct = static_cast<MetaMaskAction*>(pAction);
2376 
2377  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2378  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2379 
2380  BCToBCOA( pAct->GetBitmap().GetChecksum(), aBCOA );
2381  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2382 
2383  UInt32ToSVBT32( sal_uInt32(pAct->GetColor()), aBT32 );
2384  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2385 
2386  Int32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2387  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2388 
2389  Int32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2390  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2391  }
2392  break;
2393 
2395  {
2396  MetaMaskScaleAction* pAct = static_cast<MetaMaskScaleAction*>(pAction);
2397 
2398  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2399  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2400 
2401  BCToBCOA( pAct->GetBitmap().GetChecksum(), aBCOA );
2402  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2403 
2404  UInt32ToSVBT32( sal_uInt32(pAct->GetColor()), aBT32 );
2405  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2406 
2407  Int32ToSVBT32( pAct->GetPoint().X(), aBT32 );
2408  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2409 
2410  Int32ToSVBT32( pAct->GetPoint().Y(), aBT32 );
2411  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2412 
2413  Int32ToSVBT32( pAct->GetSize().Width(), aBT32 );
2414  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2415 
2416  Int32ToSVBT32( pAct->GetSize().Height(), aBT32 );
2417  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2418  }
2419  break;
2420 
2422  {
2423  MetaMaskScalePartAction* pAct = static_cast<MetaMaskScalePartAction*>(pAction);
2424 
2425  ShortToSVBT16( static_cast<sal_uInt16>(pAct->GetType()), aBT16 );
2426  nCrc = vcl_get_checksum( nCrc, aBT16, 2 );
2427 
2428  BCToBCOA( pAct->GetBitmap().GetChecksum(), aBCOA );
2429  nCrc = vcl_get_checksum( nCrc, aBCOA, BITMAP_CHECKSUM_SIZE );
2430 
2431  UInt32ToSVBT32( sal_uInt32(pAct->GetColor()), aBT32 );
2432  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2433 
2434  Int32ToSVBT32( pAct->GetDestPoint().X(), aBT32 );
2435  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2436 
2437  Int32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 );
2438  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2439 
2440  Int32ToSVBT32( pAct->GetDestSize().Width(), aBT32 );
2441  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2442 
2443  Int32ToSVBT32( pAct->GetDestSize().Height(), aBT32 );
2444  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2445 
2446  Int32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 );
2447  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2448 
2449  Int32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 );
2450  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2451 
2452  Int32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 );
2453  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2454 
2455  Int32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 );
2456  nCrc = vcl_get_checksum( nCrc, aBT32, 4 );
2457  }
2458  break;
2459 
2460  case MetaActionType::EPS :
2461  {
2462  MetaEPSAction* pAct = static_cast<MetaEPSAction*>(pAction);
2463  nCrc = vcl_get_checksum( nCrc, pAct->GetLink().GetData(), pAct->GetLink().GetDataSize() );
2464  }
2465  break;
2466 
2468  {
2469  MetaClipRegionAction& rAct = static_cast<MetaClipRegionAction&>(*pAction);
2470  const vcl::Region& rRegion = rAct.GetRegion();
2471 
2472  if(rRegion.HasPolyPolygonOrB2DPolyPolygon())
2473  {
2474  // It has shown that this is a possible bottleneck for checksum calculation.
2475  // In worst case a very expensive RegionHandle representation gets created.
2476  // In this case it's cheaper to use the PolyPolygon
2477  const basegfx::B2DPolyPolygon aPolyPolygon(rRegion.GetAsB2DPolyPolygon());
2478  SVBT64 aSVBT64;
2479 
2480  for(auto const& rPolygon : aPolyPolygon)
2481  {
2482  const sal_uInt32 nPointCount(rPolygon.count());
2483  const bool bControl(rPolygon.areControlPointsUsed());
2484 
2485  for(sal_uInt32 b(0); b < nPointCount; b++)
2486  {
2487  const basegfx::B2DPoint aPoint(rPolygon.getB2DPoint(b));
2488 
2489  DoubleToSVBT64(aPoint.getX(), aSVBT64);
2490  nCrc = vcl_get_checksum(nCrc, aSVBT64, 8);
2491  DoubleToSVBT64(aPoint.getY(), aSVBT64);
2492  nCrc = vcl_get_checksum(nCrc, aSVBT64, 8);
2493 
2494  if(bControl)
2495  {
2496  if(rPolygon.isPrevControlPointUsed(b))
2497  {
2498  const basegfx::B2DPoint aCtrl(rPolygon.getPrevControlPoint(b));
2499 
2500  DoubleToSVBT64(aCtrl.getX(), aSVBT64);
2501  nCrc = vcl_get_checksum(nCrc, aSVBT64, 8);
2502  DoubleToSVBT64(aCtrl.getY(), aSVBT64);
2503  nCrc = vcl_get_checksum(nCrc, aSVBT64, 8);
2504  }
2505 
2506  if(rPolygon.isNextControlPointUsed(b))
2507  {
2508  const basegfx::B2DPoint aCtrl(rPolygon.getNextControlPoint(b));
2509 
2510  DoubleToSVBT64(aCtrl.getX(), aSVBT64);
2511  nCrc = vcl_get_checksum(nCrc, aSVBT64, 8);
2512  DoubleToSVBT64(aCtrl.getY(), aSVBT64);
2513  nCrc = vcl_get_checksum(nCrc, aSVBT64, 8);
2514  }
2515  }
2516  }
2517  }
2518 
2519  sal_uInt8 tmp = static_cast<sal_uInt8>(rAct.IsClipping());
2520  nCrc = vcl_get_checksum(nCrc, &tmp, 1);
2521  }
2522  else
2523  {
2524  pAction->Write( aMemStm, &aWriteData );
2525  nCrc = vcl_get_checksum( nCrc, aMemStm.GetData(), aMemStm.Tell() );
2526  aMemStm.Seek( 0 );
2527  }
2528  }
2529  break;
2530 
2531  default:
2532  {
2533  pAction->Write( aMemStm, &aWriteData );
2534  nCrc = vcl_get_checksum( nCrc, aMemStm.GetData(), aMemStm.Tell() );
2535  aMemStm.Seek( 0 );
2536  }
2537  break;
2538  }
2539  }
2540 
2541  return nCrc;
2542 }
2543 
2545 {
2546  sal_uLong nSizeBytes = 0;
2547 
2548  for( size_t i = 0, nObjCount = GetActionSize(); i < nObjCount; ++i )
2549  {
2550  MetaAction* pAction = GetAction( i );
2551 
2552  // default action size is set to 32 (=> not the exact value)
2553  nSizeBytes += 32;
2554 
2555  // add sizes for large action content
2556  switch( pAction->GetType() )
2557  {
2558  case MetaActionType::BMP: nSizeBytes += static_cast<MetaBmpAction*>( pAction )->GetBitmap().GetSizeBytes(); break;
2559  case MetaActionType::BMPSCALE: nSizeBytes += static_cast<MetaBmpScaleAction*>( pAction )->GetBitmap().GetSizeBytes(); break;
2560  case MetaActionType::BMPSCALEPART: nSizeBytes += static_cast<MetaBmpScalePartAction*>( pAction )->GetBitmap().GetSizeBytes(); break;
2561 
2562  case MetaActionType::BMPEX: nSizeBytes += static_cast<MetaBmpExAction*>( pAction )->GetBitmapEx().GetSizeBytes(); break;
2563  case MetaActionType::BMPEXSCALE: nSizeBytes += static_cast<MetaBmpExScaleAction*>( pAction )->GetBitmapEx().GetSizeBytes(); break;
2564  case MetaActionType::BMPEXSCALEPART: nSizeBytes += static_cast<MetaBmpExScalePartAction*>( pAction )->GetBitmapEx().GetSizeBytes(); break;
2565 
2566  case MetaActionType::MASK: nSizeBytes += static_cast<MetaMaskAction*>( pAction )->GetBitmap().GetSizeBytes(); break;
2567  case MetaActionType::MASKSCALE: nSizeBytes += static_cast<MetaMaskScaleAction*>( pAction )->GetBitmap().GetSizeBytes(); break;
2568  case MetaActionType::MASKSCALEPART: nSizeBytes += static_cast<MetaMaskScalePartAction*>( pAction )->GetBitmap().GetSizeBytes(); break;
2569 
2570  case MetaActionType::POLYLINE: nSizeBytes += static_cast<MetaPolyLineAction*>( pAction )->GetPolygon().GetSize() * sizeof( Point ); break;
2571  case MetaActionType::POLYGON: nSizeBytes += static_cast<MetaPolygonAction*>( pAction )->GetPolygon().GetSize() * sizeof( Point ); break;
2573  {
2574  const tools::PolyPolygon& rPolyPoly = static_cast<MetaPolyPolygonAction*>( pAction )->GetPolyPolygon();
2575 
2576  for( sal_uInt16 n = 0; n < rPolyPoly.Count(); ++n )
2577  nSizeBytes += ( rPolyPoly[ n ].GetSize() * sizeof( Point ) );
2578  }
2579  break;
2580 
2581  case MetaActionType::TEXT: nSizeBytes += static_cast<MetaTextAction*>( pAction )->GetText().getLength() * sizeof( sal_Unicode ); break;
2582  case MetaActionType::STRETCHTEXT: nSizeBytes += static_cast<MetaStretchTextAction*>( pAction )->GetText().getLength() * sizeof( sal_Unicode ); break;
2583  case MetaActionType::TEXTRECT: nSizeBytes += static_cast<MetaTextRectAction*>( pAction )->GetText().getLength() * sizeof( sal_Unicode ); break;
2585  {
2586  MetaTextArrayAction* pTextArrayAction = static_cast<MetaTextArrayAction*>(pAction);
2587 
2588  nSizeBytes += ( pTextArrayAction->GetText().getLength() * sizeof( sal_Unicode ) );
2589 
2590  if( pTextArrayAction->GetDXArray() )
2591  nSizeBytes += ( pTextArrayAction->GetLen() << 2 );
2592  }
2593  break;
2594  default: break;
2595  }
2596  }
2597 
2598  return nSizeBytes;
2599 }
2600 
2601 namespace
2602 {
2603  class DepthGuard
2604  {
2605  private:
2607  rtl_TextEncoding const m_eOrigCharSet;
2608  public:
2609  DepthGuard(ImplMetaReadData& rData, SvStream const & rIStm)
2610  : m_rData(rData)
2611  , m_eOrigCharSet(m_rData.meActualCharSet)
2612  {
2613  ++m_rData.mnParseDepth;
2614  m_rData.meActualCharSet = rIStm.GetStreamCharSet();
2615  }
2616  bool TooDeep() const { return m_rData.mnParseDepth > 1024; }
2617  ~DepthGuard()
2618  {
2619  --m_rData.mnParseDepth;
2620  m_rData.meActualCharSet = m_eOrigCharSet;
2621  }
2622  };
2623 }
2624 
2626 {
2627  if (rIStm.GetError())
2628  {
2629  SAL_WARN("vcl.gdi", "Stream error: " << rIStm.GetError());
2630  return rIStm;
2631  }
2632 
2633  sal_uLong nStmPos = rIStm.Tell();
2634  SvStreamEndian nOldFormat = rIStm.GetEndian();
2635 
2636  rIStm.SetEndian( SvStreamEndian::LITTLE );
2637 
2638  try
2639  {
2640  char aId[7];
2641  aId[0] = 0;
2642  aId[6] = 0;
2643  rIStm.ReadBytes( aId, 6 );
2644 
2645  if ( !strcmp( aId, "VCLMTF" ) )
2646  {
2647  // new format
2648  sal_uInt32 nStmCompressMode = 0;
2649  sal_uInt32 nCount = 0;
2650  std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rIStm, StreamMode::READ ));
2651 
2652  rIStm.ReadUInt32( nStmCompressMode );
2653  ReadMapMode( rIStm, rGDIMetaFile.m_aPrefMapMode );
2654  TypeSerializer aSerializer(rIStm);
2655  aSerializer.readSize(rGDIMetaFile.m_aPrefSize);
2656  rIStm.ReadUInt32( nCount );
2657 
2658  pCompat.reset(); // destructor writes stuff into the header
2659 
2660  std::unique_ptr<ImplMetaReadData> xReadData;
2661  if (!pData)
2662  {
2663  xReadData.reset(new ImplMetaReadData);
2664  pData = xReadData.get();
2665  }
2666  DepthGuard aDepthGuard(*pData, rIStm);
2667 
2668  if (aDepthGuard.TooDeep())
2669  throw std::runtime_error("too much recursion");
2670 
2671  for( sal_uInt32 nAction = 0; ( nAction < nCount ) && !rIStm.eof(); nAction++ )
2672  {
2673  MetaAction* pAction = MetaAction::ReadMetaAction(rIStm, pData);
2674  if( pAction )
2675  {
2676  if (pAction->GetType() == MetaActionType::COMMENT)
2677  {
2678  MetaCommentAction* pCommentAct = static_cast<MetaCommentAction*>(pAction);
2679  if ( pCommentAct->GetComment() == "EMF_PLUS" )
2680  rGDIMetaFile.UseCanvas( true );
2681  }
2682  rGDIMetaFile.AddAction( pAction );
2683  }
2684  }
2685  }
2686  else
2687  {
2688  rIStm.Seek( nStmPos );
2689  SVMConverter( rIStm, rGDIMetaFile );
2690  }
2691  }
2692  catch (...)
2693  {
2694  SAL_WARN("vcl", "GDIMetaFile exception during load");
2696  };
2697 
2698  // check for errors
2699  if( rIStm.GetError() )
2700  {
2701  rGDIMetaFile.Clear();
2702  rIStm.Seek( nStmPos );
2703  }
2704 
2705  rIStm.SetEndian( nOldFormat );
2706  return rIStm;
2707 }
2708 
2709 SvStream& WriteGDIMetaFile( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile )
2710 {
2711  if( !rOStm.GetError() )
2712  {
2713  const_cast< GDIMetaFile& >( rGDIMetaFile ).Write( rOStm );
2714  }
2715  return rOStm;
2716 }
2717 
2719 {
2720  Clear();
2721  ReadGDIMetaFile( rIStm, *this );
2722 
2723  return rIStm;
2724 }
2725 
2727 {
2728  VersionCompat* pCompat;
2729  const SvStreamCompressFlags nStmCompressMode = rOStm.GetCompressMode();
2730  SvStreamEndian nOldFormat = rOStm.GetEndian();
2731 
2732  rOStm.SetEndian( SvStreamEndian::LITTLE );
2733  rOStm.WriteBytes( "VCLMTF", 6 );
2734 
2735  pCompat = new VersionCompat( rOStm, StreamMode::WRITE, 1 );
2736 
2737  rOStm.WriteUInt32( static_cast<sal_uInt32>(nStmCompressMode) );
2738  WriteMapMode( rOStm, m_aPrefMapMode );
2739  TypeSerializer aSerializer(rOStm);
2740  aSerializer.writeSize(m_aPrefSize);
2741  rOStm.WriteUInt32( GetActionSize() );
2742 
2743  delete pCompat;
2744 
2745  ImplMetaWriteData aWriteData;
2746 
2747  aWriteData.meActualCharSet = rOStm.GetStreamCharSet();
2748 
2749  MetaAction* pAct = FirstAction();
2750  while ( pAct )
2751  {
2752  pAct->Write( rOStm, &aWriteData );
2753  pAct = NextAction();
2754  }
2755 
2756  rOStm.SetEndian( nOldFormat );
2757 
2758  return rOStm;
2759 }
2760 
2761 bool GDIMetaFile::CreateThumbnail(BitmapEx& rBitmapEx, BmpConversion eColorConversion, BmpScaleFlag nScaleFlag) const
2762 {
2763  // initialization seems to be complicated but is used to avoid rounding errors
2765  const Point aNullPt;
2766  const Point aTLPix( aVDev->LogicToPixel( aNullPt, GetPrefMapMode() ) );
2767  const Point aBRPix( aVDev->LogicToPixel( Point( GetPrefSize().Width() - 1, GetPrefSize().Height() - 1 ), GetPrefMapMode() ) );
2768  Size aDrawSize( aVDev->LogicToPixel( GetPrefSize(), GetPrefMapMode() ) );
2769  Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
2770  sal_uInt32 nMaximumExtent = 256;
2771 
2772  if (!rBitmapEx.IsEmpty())
2773  rBitmapEx.SetEmpty();
2774 
2775  // determine size that has the same aspect ratio as image size and
2776  // fits into the rectangle determined by nMaximumExtent
2777  if ( aSizePix.Width() && aSizePix.Height()
2778  && ( sal::static_int_cast< unsigned long >(aSizePix.Width()) >
2779  nMaximumExtent ||
2780  sal::static_int_cast< unsigned long >(aSizePix.Height()) >
2781  nMaximumExtent ) )
2782  {
2783  const Size aOldSizePix( aSizePix );
2784  double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height();
2785 
2786  if ( fWH <= 1.0 )
2787  {
2788  aSizePix.setWidth( FRound( nMaximumExtent * fWH ) );
2789  aSizePix.setHeight( nMaximumExtent );
2790  }
2791  else
2792  {
2793  aSizePix.setWidth( nMaximumExtent );
2794  aSizePix.setHeight( FRound( nMaximumExtent / fWH ) );
2795  }
2796 
2797  aDrawSize.setWidth( FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() ) );
2798  aDrawSize.setHeight( FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() ) );
2799  }
2800 
2801  // draw image(s) into VDev and get resulting image
2802  // do it 4x larger to be able to scale it down & get beautiful antialias
2803  Size aAntialiasSize(aSizePix.Width() * 4, aSizePix.Height() * 4);
2804  if (aVDev->SetOutputSizePixel(aAntialiasSize))
2805  {
2806  // antialias: provide 4x larger size, and then scale down the result
2807  Size aAntialias(aDrawSize.Width() * 4, aDrawSize.Height() * 4);
2808 
2809  // draw metafile into VDev
2810  const_cast<GDIMetaFile *>(this)->WindStart();
2811  const_cast<GDIMetaFile *>(this)->Play(aVDev.get(), Point(), aAntialias);
2812 
2813  // get paint bitmap
2814  BitmapEx aBitmap( aVDev->GetBitmapEx( aNullPt, aVDev->GetOutputSizePixel() ) );
2815 
2816  // scale down the image to the desired size - use the input scaler for the scaling operation
2817  aBitmap.Scale(aDrawSize, nScaleFlag);
2818 
2819  // convert to desired bitmap color format
2820  Size aSize(aBitmap.GetSizePixel());
2821  if (aSize.Width() && aSize.Height())
2822  aBitmap.Convert(eColorConversion);
2823 
2824  rBitmapEx = aBitmap;
2825  }
2826 
2827  return !rBitmapEx.IsEmpty();
2828 }
2829 
2830 void GDIMetaFile::UseCanvas( bool _bUseCanvas )
2831 {
2832  m_bUseCanvas = _bUseCanvas;
2833 }
2834 
2835 void GDIMetaFile::dumpAsXml(const char* pFileName) const
2836 {
2837  SvFileStream aStream(pFileName ? OUString::fromUtf8(pFileName) : OUString("file:///tmp/metafile.xml"),
2838  StreamMode::STD_READWRITE | StreamMode::TRUNC);
2839  assert(aStream.good());
2840  MetafileXmlDump aDumper;
2841  aDumper.dump(*this, aStream);
2842 }
2843 
2844 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 Count() const
static SAL_DLLPRIVATE BitmapEx ImplBmpAdjustFnc(const BitmapEx &rBmpEx, const void *pBmpParam)
Definition: gdimtf.cxx:1716
const Fraction & GetScaleX() const
Definition: mapmod.cxx:172
long Width() const
const Gradient & GetGradient() const
Definition: metaact.hxx:1559
void Mirror(BmpMirrorFlags nMirrorFlags)
Definition: gdimtf.cxx:576
OutDevType GetOutDevType() const
Definition: outdev.hxx:522
virtual void Execute(OutputDevice *pOut)
Definition: metaact.cxx:168
const LineInfo & GetLineInfo() const
Definition: metaact.hxx:182
void dump(const GDIMetaFile &rMetaFile, SvStream &rStream)
The actual result that will be used for testing.
Definition: mtfxmldump.cxx:516
void SetDigitLanguage(LanguageType)
void SetPixelOffset(const Size &rOffset)
Set an offset in pixel.
Definition: map.cxx:1904
GDIMetaFile * m_pPrev
Definition: gdimtf.hxx:65
Bitmap GetMask() const
Definition: bitmapex.cxx:258
long GetWidth() const
sal_uInt64 BitmapChecksum
Definition: checksum.hxx:30
const Size & GetDestSize() const
Definition: metaact.hxx:949
Definition: hatch.hxx:44
VclPtr< OutputDevice > m_pOutDev
Definition: gdimtf.hxx:67
const LineInfo & GetLineInfo() const
Definition: metaact.hxx:401
bool IsClipping() const
Definition: metaact.hxx:1102
void SetRelativeMapMode(const MapMode &rNewMapMode)
Definition: map.cxx:775
const Color & GetColor() const
Definition: metaact.hxx:1346
const Bitmap & GetBitmap() const
Definition: metaact.hxx:907
sal_Int32 GetLen() const
Definition: metaact.hxx:492
MetaAction * GetCurAction() const
Definition: gdimtf.hxx:171
long GetHeight() const
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
const Point & GetPoint() const
Definition: metaact.hxx:700
sal_uInt8 GetRed() const
rtl_TextEncoding meActualCharSet
Definition: metaact.hxx:46
static MetaAction * ReadMetaAction(SvStream &rIStm, ImplMetaReadData *pData)
Definition: metaact.cxx:195
void ReplaceColors(const Color *pSearchColors, const Color *rReplaceColors, sal_uLong nColorCount)
Definition: gdimtf.cxx:2146
const Point & GetEndPoint() const
Definition: metaact.hxx:337
sal_uInt8 SVBT16[2]
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
long FRound(double fVal)
SAL_DLLPRIVATE bool ImplPlayWithRenderer(OutputDevice *pOut, const Point &rPos, Size rLogicDestSize)
Definition: gdimtf.cxx:365
const GDIMetaFile & GetGDIMetaFile() const
Definition: metaact.hxx:1556
void Replace(const Color &rSearchColor, const Color &rReplaceColor)
Replace all pixel having the search color with the specified color.
Definition: bitmapex.cxx:596
bool Adjust(short nLuminancePercent, short nContrastPercent, short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, double fGamma=1.0, bool bInvert=false, bool msoBrightness=false)
Change various global color characteristics.
Definition: bitmapex.cxx:608
const Point & GetSrcPoint() const
Definition: metaact.hxx:738
sal_uInt32 GetVertRound() const
Definition: metaact.hxx:243
const tools::PolyPolygon & GetPolyPolygon() const
Definition: metaact.hxx:1010
SvStream & WriteMapMode(SvStream &rOStm, const MapMode &rMapMode)
Definition: mapmod.cxx:152
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1668
GDIMetaFile & operator=(const GDIMetaFile &rMtf)
Definition: gdimtf.cxx:189
long Height() const
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
This is an overloaded member function, provided for convenience. It differs from the above function o...
SvStream & WriteSvtGraphicStroke(SvStream &rOStm, const SvtGraphicStroke &rClass)
bool IsSetting() const
Definition: metaact.hxx:1293
const Point & GetPoint() const
Definition: metaact.hxx:525
SvStream & Read(SvStream &rIStm)
Definition: gdimtf.cxx:2718
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:241
const MapMode & GetPrefMapMode() const
Definition: gdimtf.hxx:176
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: bitmapex.cxx:370
sal_uInt8 GetTransparency() const
sal_uIntPtr sal_uLong
MtfConversion
Definition: gdimtf.hxx:44
void writeSize(const Size &rSize)
void dumpAsXml(const char *pFileName=nullptr) const
Dumps the meta actions as XML in metafile.xml.
Definition: gdimtf.cxx:2835
MetaAction * NextAction()
Definition: gdimtf.cxx:173
#define F_PI1800
sal_uInt8 GetLuminance() const
const Point & GetPoint() const
Definition: metaact.hxx:1593
sal_Int64 n
Encapsulates geometry and associated attributes of a graphical 'pen stroke'.
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:174
const Point & GetPoint() const
Definition: metaact.hxx:1557
void Clear()
Definition: gdimtf.cxx:248
static SAL_DLLPRIVATE Color ImplColMonoFnc(const Color &rColor, const void *pColParam)
Definition: gdimtf.cxx:1747
sal_uInt64 Seek(sal_uInt64 nPos)
const Size & GetSize() const
Definition: metaact.hxx:701
const MapMode & GetMapMode() const
Definition: outdev.hxx:1674
const tools::PolyPolygon & GetPolyPolygon() const
Definition: metaact.hxx:1523
sal_Int32 GetIndex() const
Definition: metaact.hxx:527
OUString aId
void SetLayoutMode(ComplexTextLayoutFlags nTextLayoutMode)
BitmapChecksum vcl_get_checksum(BitmapChecksum Checksum, const void *Data, sal_uInt32 DatLen)
Definition: checksum.hxx:72
const Point & GetEndPoint() const
Definition: metaact.hxx:181
GDIMetaFile * GetConnectMetaFile() const
Definition: outdev.hxx:417
const OUString & GetText() const
Definition: metaact.hxx:564
bool IsRecord() const
Definition: gdimtf.hxx:142
Size GetSizePixel() const
SvStream & ReadSvtGraphicStroke(SvStream &rIStm, SvtGraphicStroke &rClass)
static SAL_DLLPRIVATE void ImplAddGradientEx(GDIMetaFile &rMtf, const OutputDevice &rMapDev, const tools::PolyPolygon &rPolyPoly, const Gradient &rGrad)
Definition: gdimtf.cxx:778
const Size & GetSrcSize() const
Definition: metaact.hxx:739
tools::Rectangle GetBoundRect() const
Definition: region.cxx:1214
void SetOrientation(short nLineOrientation)
Definition: font/font.cxx:192
SvStreamCompressFlags GetCompressMode() const
static SAL_DLLPRIVATE BitmapEx ImplBmpReplaceFnc(const BitmapEx &rBmpEx, const void *pBmpParam)
Definition: gdimtf.cxx:1791
void Clip(const tools::Rectangle &)
Definition: gdimtf.cxx:715
void SetMapMode()
Definition: map.cxx:655
const Point & GetPoint() const
Definition: metaact.hxx:909
bool Convert(BmpConversion eConversion)
Convert bitmap format.
Definition: bitmapex.cxx:454
BitmapChecksum GetChecksum() const
Definition: bitmapex.cxx:292
SvStream & ReadSvtGraphicFill(SvStream &rIStm, SvtGraphicFill &rClass)
sal_uInt8 SVBT32[4]
void Move(long nHorzMoveDelta, long nVertMoveDelta)
const sal_uInt8 * GetData() const
Definition: metaact.hxx:1655
bool IsEmpty() const
HashMap_OWString_Interface aMap
sal_uInt16 sal_Unicode
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
void Rotate(long nAngle10)
Definition: gdimtf.cxx:800
bool IsAlpha() const
Definition: bitmapex.cxx:226
static SAL_DLLPRIVATE tools::Polygon ImplGetRotatedPolygon(const tools::Polygon &rPoly, const Point &rRotatePt, const Size &rOffset, double fSin, double fCos)
Definition: gdimtf.cxx:756
ErrCode GetError() const
const Point & GetPoint() const
Definition: metaact.hxx:801
void Record(OutputDevice *pOutDev)
Definition: gdimtf.cxx:289
const Sequence< Sequence< double > > & m_rData
void push_back(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:571
bool eof() const
const OUString & GetText() const
Definition: metaact.hxx:490
const Fraction & GetScaleY() const
Definition: mapmod.cxx:174
const Color & GetColor() const
Definition: metaact.hxx:873
SvStream & WriteGDIMetaFile(SvStream &rOStm, const GDIMetaFile &rGDIMetaFile)
Definition: gdimtf.cxx:2709
geometry::IntegerSize2D integerSize2DFromSize(const Size &rSize)
#define X
Definition: field.cxx:1075
const Bitmap & GetBitmap() const
Definition: metaact.hxx:667
void Rotate(const Point &rCenter, double fSin, double fCos)
void Adjust(short nLuminancePercent, short nContrastPercent, short nChannelRPercent=0, short nChannelGPercent=0, short nChannelBPercent=0, double fGamma=1.0, bool bInvert=false, bool msoBrightness=false)
Definition: gdimtf.cxx:2054
int nCount
long GetWidth() const
Definition: metaact.hxx:635
const vcl::Region & GetRegion() const
Definition: metaact.hxx:1101
bool CreateThumbnail(BitmapEx &rBitmapEx, BmpConversion nColorConversion=BmpConversion::N24Bit, BmpScaleFlag nScaleFlag=BmpScaleFlag::BestQuality) const
Creates an antialiased thumbnail.
Definition: gdimtf.cxx:2761
void SetStartColor(const Color &rColor)
const Gradient & GetGradient() const
Definition: metaact.hxx:981
SvStream & WriteUInt32(sal_uInt32 nUInt32)
const Point & GetStartPoint() const
Definition: metaact.hxx:303
const Color & GetColor() const
Definition: metaact.hxx:1213
MetaActionType
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:1130
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:300
const tools::PolyPolygon & GetPolyPolygon() const
Definition: metaact.hxx:457
BitmapEx(* BmpExchangeFnc)(const BitmapEx &rBmpEx, const void *pBmpParam)
Definition: gdimtf.hxx:52
const Size & GetSize() const
Definition: metaact.hxx:802
GDIMetaFile GetMonochromeMtf(const Color &rCol) const
Definition: gdimtf.cxx:2185
void readSize(Size &rSize)
sal_uInt8 GetBlue() const
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:271
FontLineStyle GetUnderline() const
Definition: metaact.hxx:637
Size m_aPrefSize
Definition: gdimtf.hxx:64
const tools::Polygon & GetPolygon() const
Definition: metaact.hxx:429
tools::PolyPolygon GetAsPolyPolygon() const
Definition: region.cxx:1261
sal_uInt32 GetHorzRound() const
Definition: metaact.hxx:242
void Move(long nHorzMove, long nVertMove)
void Rotate(const Point &rCenter, double fSin, double fCos)
void setPath(const tools::PolyPolygon &rPath)
Set path to fill.
const vcl::Region & GetRegion() const
Definition: metaact.hxx:1158
static SAL_DLLPRIVATE tools::PolyPolygon ImplGetRotatedPolyPolygon(const tools::PolyPolygon &rPoly, const Point &rRotatePt, const Size &rOffset, double fSin, double fCos)
Definition: gdimtf.cxx:767
const Size & GetSrcSize() const
Definition: metaact.hxx:951
bool m_bPause
Definition: gdimtf.hxx:68
static SAL_DLLPRIVATE Point ImplGetRotatedPoint(const Point &rPt, const Point &rRotatePt, const Size &rOffset, double fSin, double fCos)
Definition: gdimtf.cxx:746
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
void SetEmpty()
Definition: bitmapex.cxx:208
static vcl::Window * GetFirstTopLevelWindow()
Get the first top-level window of the application.
Definition: svapp.cxx:1055
bool IsEmpty() const
Definition: bitmapex.cxx:203
void Move(long nHorzMove, long nVertMove)
bool GetUseCanvas() const
Definition: gdimtf.hxx:199
bool Create(const css::uno::Reference< css::rendering::XBitmapCanvas > &xBitmapCanvas, const Size &rSize)
populate from a canvas implementation
Definition: bitmapex.cxx:774
#define BITMAP_CHECKSUM_SIZE
Definition: checksum.hxx:28
void SetConnectMetaFile(GDIMetaFile *pMtf)
Definition: outdev.cxx:208
void SetScaleX(const Fraction &rScaleX)
Definition: mapmod.cxx:108
#define TOOLS_WARN_EXCEPTION(area, stream)
friend VCL_DLLPUBLIC SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pReadData)
Definition: gdimtf.cxx:2625
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:210
static SAL_DLLPRIVATE BitmapEx ImplBmpConvertFnc(const BitmapEx &rBmpEx, const void *pBmpParam)
Definition: gdimtf.cxx:1738
const Size & GetPrefSize() const
Definition: gdimtf.hxx:173
~GDIMetaFile()
Definition: gdimtf.cxx:152
const tools::Polygon & GetPolygon() const
Definition: metaact.hxx:400
GDIMetaFile * m_pNext
Definition: gdimtf.hxx:66
::std::vector< rtl::Reference< MetaAction > > m_aList
Definition: gdimtf.hxx:60
uno_Any a
sal_uInt16 GetTransparence() const
Definition: metaact.hxx:1524
const BitmapEx & GetBitmapEx() const
Definition: metaact.hxx:836
virtual void Scale(double fScaleX, double fScaleY)
Definition: metaact.cxx:181
const Size & GetSize() const
Definition: metaact.hxx:910
const Point & GetDestPoint() const
Definition: metaact.hxx:837
const Point & GetPoint() const
Definition: metaact.hxx:489
SAL_DLLPRIVATE void ImplExchangeColors(ColorExchangeFnc pFncCol, const void *pColParam, BmpExchangeFnc pFncBmp, const void *pBmpParam)
Definition: gdimtf.cxx:1801
void Convert(MtfConversion eConversion)
Definition: gdimtf.cxx:2135
bool IsSetting() const
Definition: metaact.hxx:1214
#define LANGUAGE_SYSTEM
BitmapChecksum GetChecksum() const
Color(* ColorExchangeFnc)(const Color &rColor, const void *pColParam)
Definition: gdimtf.hxx:51
const BitmapEx & GetBitmapEx() const
Definition: metaact.hxx:768
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:980
const OUString & GetText() const
Definition: metaact.hxx:526
int i
QPRO_FUNC_TYPE const nType
const Bitmap & GetBitmap() const
Definition: metaact.hxx:735
const Color & GetColor() const
Definition: metaact.hxx:1292
Size GetOutputSize() const
Definition: outdev.hxx:450
const Size & GetSize() const
Definition: metaact.hxx:1558
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:102
sal_uInt32 GetWidth() const
Definition: metaact.hxx:565
void SetRight(long v)
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
std::size_t WriteBytes(const void *pData, std::size_t nSize)
rtl_TextEncoding meActualCharSet
Definition: metaact.hxx:57
long * GetDXArray() const
Definition: metaact.hxx:529
const Point & GetEndPoint() const
Definition: metaact.hxx:304
SvStreamCompressFlags
BmpMirrorFlags
Definition: bitmap.hxx:36
void SetScaleY(const Fraction &rScaleY)
Definition: mapmod.cxx:115
void UseCanvas(bool _bUseCanvas)
Definition: gdimtf.cxx:2830
void SetError(ErrCode nErrorCode)
BmpScaleFlag
Definition: bitmap.hxx:48
void Intersect(const tools::Rectangle &rRegion)
Definition: region.cxx:584
void getPath(tools::Polygon &) const
Query path to stroke.
const Point & GetStartPoint() const
Definition: metaact.hxx:369
const Point & GetSrcPoint() const
Definition: metaact.hxx:839
sal_Int32 GetLen() const
Definition: metaact.hxx:567
const Point & GetPoint() const
Definition: metaact.hxx:769
bool m_bRecord
Definition: gdimtf.hxx:69
const Bitmap & GetBitmap() const
Definition: metaact.hxx:872
Size GetOutputSizePixel() const
Definition: outdev.hxx:441
MapUnit GetMapUnit() const
Definition: mapmod.cxx:168
sal_uInt8 SVBT64[8]
BmpConversion
Definition: bitmap.hxx:65
void WindStart()
Definition: gdimtf.cxx:531
bool IsTransparent() const
Definition: bitmapex.cxx:221
const Bitmap & GetBitmap() const
Definition: metaact.hxx:946
const Point & GetPoint() const
Definition: metaact.hxx:874
long X() const
static vcl::Window * GetActiveTopWindow()
Get the "active" top window.
Definition: svapp.cxx:1099
static SAL_DLLPRIVATE Color ImplColAdjustFnc(const Color &rColor, const void *pColParam)
Definition: gdimtf.cxx:1707
FontStrikeout GetStrikeout() const
Definition: metaact.hxx:636
tools::Rectangle GetBoundRect(OutputDevice &i_rReference, tools::Rectangle *pHairline=nullptr) const
Definition: gdimtf.cxx:1285
#define Y
const Size & GetSize() const
Definition: metaact.hxx:1594
const Bitmap & GetBitmap() const
Definition: metaact.hxx:699
const Point & GetDestPoint() const
Definition: metaact.hxx:736
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:302
void SetColor(const Color &)
Definition: font/font.cxx:80
const Size & GetDestSize() const
Definition: metaact.hxx:737
PushFlags GetFlags() const
Definition: metaact.hxx:1451
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:368
std::size_t ReadBytes(void *pData, std::size_t nSize)
Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1179
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:934
const tools::PolyPolygon & GetPolyPolygon() const
Definition: metaact.hxx:1040
SvStream & WriteSvtGraphicFill(SvStream &rOStm, const SvtGraphicFill &rClass)
const GfxLink & GetLink() const
Definition: metaact.hxx:1591
const Point & GetPoint() const
Definition: metaact.hxx:563
bool IsSetting() const
Definition: metaact.hxx:1347
void SetAngle(sal_uInt16 nAngle10)
Definition: gdi/hatch.cxx:74
bool IsSetting() const
Definition: metaact.hxx:1241
sal_uInt8 GetGreen() const
bool IsSetting() const
Definition: metaact.hxx:1320
SvStreamEndian GetEndian() const
const Color & GetColor() const
Definition: metaact.hxx:1266
void Stop()
Definition: gdimtf.cxx:518
const Color & GetColor() const
Definition: metaact.hxx:908
MapMode m_aPrefMapMode
Definition: gdimtf.hxx:63
const Point & GetStartPoint() const
Definition: metaact.hxx:180
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:1071
sal_uInt32 GetDataSize() const
Definition: metaact.hxx:1654
bool operator==(const GDIMetaFile &rMtf) const
Definition: gdimtf.cxx:222
const BitmapEx & GetBitmapEx() const
Definition: metaact.hxx:800
void Pause(bool bPause)
Definition: gdimtf.cxx:499
bool IsSetting() const
Definition: metaact.hxx:1621
const Point & GetStartPoint() const
Definition: metaact.hxx:336
AlphaMask GetAlpha() const
Definition: bitmapex.cxx:268
BitmapChecksum GetChecksum() const
Definition: gdimtf.cxx:2200
const Point & GetPoint() const
Definition: metaact.hxx:120
const Size & GetSrcSize() const
Definition: metaact.hxx:840
const Color & GetColor() const
Definition: metaact.hxx:947
tools::Rectangle & Union(const tools::Rectangle &rRect)
unsigned char sal_uInt8
void ReplaceAction(rtl::Reference< MetaAction > pAction, size_t nAction)
Definition: gdimtf.cxx:178
void BCToBCOA(BitmapChecksum n, BitmapChecksumOctetArray p)
Definition: checksum.hxx:34
const Point & GetStartPoint() const
Definition: metaact.hxx:634
static SAL_DLLPRIVATE Color ImplColReplaceFnc(const Color &rColor, const void *pColParam)
Definition: gdimtf.cxx:1771
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:544
MetaAction * GetAction(size_t nAction) const
Definition: gdimtf.cxx:162
void Move(long nX, long nY)
Definition: gdimtf.cxx:612
SvStream & ReadGDIMetaFile(SvStream &rIStm, GDIMetaFile &rGDIMetaFile, ImplMetaReadData *pData)
Definition: gdimtf.cxx:2625
void SetEndian(SvStreamEndian SvStreamEndian)
#define SAL_INFO(area, stream)
const Gradient & GetGradient() const
Definition: metaact.hxx:1011
const Point & GetPoint() const
Definition: metaact.hxx:148
const Point & GetPoint() const
Definition: metaact.hxx:668
bool m_bUseCanvas
Definition: gdimtf.hxx:70
void Linker(OutputDevice *pOut, bool bLink)
Definition: gdimtf.cxx:256
const Point & GetDestPoint() const
Definition: metaact.hxx:948
#define SVSTREAM_FILEFORMAT_ERROR
Definition: errcode.hxx:262
rtl_TextEncoding GetStreamCharSet() const
void Scale(double fScaleX, double fScaleY)
Definition: gdimtf.cxx:689
static SAL_DLLPRIVATE BitmapEx ImplBmpMonoFnc(const BitmapEx &rBmpEx, const void *pBmpParam)
Definition: gdimtf.cxx:1752
bool HasPolyPolygonOrB2DPolyPolygon() const
Definition: region.hxx:110
sal_uInt64 Tell() const
void * p
Reference< XComponentContext > getProcessComponentContext()
size_t GetActionSize() const
Definition: gdimtf.cxx:157
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
const Wallpaper & GetWallpaper() const
Definition: metaact.hxx:1072
MetaActionType GetType() const
Definition: metaact.hxx:89
long Left() const
const Color & GetColor() const
Definition: metaact.hxx:1319
void setPath(const tools::Polygon &)
Set path to stroke.
long GetHorzMove() const
Definition: metaact.hxx:1186
const Point & GetEndPoint() const
Definition: metaact.hxx:370
const Hatch & GetHatch() const
Definition: metaact.hxx:1041
const Point & GetSrcPoint() const
Definition: metaact.hxx:950
FontLineStyle GetOverline() const
Definition: metaact.hxx:638
bool good() const
bool Erase(const Color &rFillColor)
Fill the entire bitmap with the given color.
Definition: bitmappaint.cxx:34
const Color & GetColor() const
Definition: metaact.hxx:121
basegfx::B2DPolyPolygon GetAsB2DPolyPolygon() const
Definition: region.cxx:1289
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:335
long GetVertMove() const
Definition: metaact.hxx:1187
MetaAction * FirstAction()
Definition: gdimtf.cxx:167
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
Size GetPixelOffset() const
Get the offset in pixel.
Definition: outdev.hxx:1718
tools::Rectangle GetBoundRect() const
void Move(long nHorzMove, long nVertMove)
#define SAL_WARN(area, stream)
const Point & GetRefPoint() const
Definition: metaact.hxx:1620
DepthGuard(HWPFile &rFile)
sal_uInt8 BitmapChecksumOctetArray[BITMAP_CHECKSUM_SIZE]
Definition: checksum.hxx:31
SvStreamEndian
SvStream & ReadMapMode(SvStream &rIStm, MapMode &rMapMode)
Definition: mapmod.cxx:136
const OString & GetComment() const
Definition: metaact.hxx:1652
Encapsulates geometry and associated attributes of a filled area.
tools::Rectangle GetBoundRect() const
static void ImplActionBounds(tools::Rectangle &o_rOutBounds, const tools::Rectangle &i_rInBounds, const std::vector< tools::Rectangle > &i_rClipStack, tools::Rectangle *o_pHairline)
Definition: gdimtf.cxx:1260
virtual void Move(long nHorzMove, long nVertMove)
Definition: metaact.cxx:177
size_t m_nCurrentActionElement
Definition: gdimtf.hxx:61
sal_Int32 GetLen() const
Definition: metaact.hxx:528
void getPath(tools::PolyPolygon &) const
Query path to fill.
Converts old SVGDI aka SVM1 format data to current VCLMTF aka SVM2 format metafile data...
const Size & GetDestSize() const
Definition: metaact.hxx:838
std::enable_if< std::is_signed< T >::value||std::is_floating_point< T >::value, long >::type MinMax(T nVal, long nMin, long nMax)
const Size & GetSizePixel() const
Definition: bitmapex.hxx:83
const Color & GetColor() const
Definition: metaact.hxx:1240
virtual void Write(SvStream &rOStm, ImplMetaWriteData *pData)
Definition: metaact.cxx:185
const GDIMetaFile & GetSubstitute() const
Definition: metaact.hxx:1592
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
void SetColor(const Color &rColor)
Definition: gdi/hatch.cxx:64
void setWidth(long nWidth)
bool Crop(const tools::Rectangle &rRectPixel)
Crop the bitmap.
Definition: bitmapex.cxx:434
const vcl::Font & GetFont() const
Definition: metaact.hxx:1426
const tools::Rectangle & GetRect() const
Definition: metaact.hxx:598
#define GAMMA(_def_cVal, _def_InvGamma)
Definition: gdimtf.cxx:52
aStr
sal_Int32 GetIndex() const
Definition: metaact.hxx:566
sal_Int32 GetIndex() const
Definition: metaact.hxx:491
SvStream & Write(SvStream &rOStm)
Definition: gdimtf.cxx:2726
Point Center() const
long Y() const
static SAL_DLLPRIVATE Color ImplColConvertFnc(const Color &rColor, const void *pColParam)
Definition: gdimtf.cxx:1728
void WindPrev()
Definition: gdimtf.cxx:537
const void * GetData()
void setHeight(long nHeight)
bool Rotate(long nAngle10, const Color &rFillColor)
Rotate bitmap by the specified angle.
Definition: bitmapex.cxx:390
sal_uLong GetSizeBytes() const
Definition: gdimtf.cxx:2544