LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/gdi - gdimtf.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 319 1496 21.3 %
Date: 2012-12-27 Functions: 29 65 44.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10