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