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

Generated by: LCOV version 1.10