LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/filter/wmf - winmtf.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 710 1166 60.9 %
Date: 2012-12-27 Functions: 64 83 77.1 %
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 "winmtf.hxx"
      21             : #include <basegfx/matrix/b2dhommatrix.hxx>
      22             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      23             : #include <vcl/metaact.hxx>
      24             : #include <vcl/graphictools.hxx>
      25             : #include <vcl/canvastools.hxx>
      26             : #include <vcl/metric.hxx>
      27             : #include <vcl/svapp.hxx>
      28             : #include <rtl/strbuf.hxx>
      29             : #include <rtl/tencinfo.h>
      30             : 
      31             : // ------------------------------------------------------------------------
      32             : 
      33             : #if OSL_DEBUG_LEVEL > 1
      34             : #define EMFP_DEBUG(x) x
      35             : #else
      36             : #define EMFP_DEBUG(x)
      37             : #endif
      38             : 
      39           3 : void WinMtfClipPath::intersectClipRect( const Rectangle& rRect )
      40             : {
      41             :     maClip.intersectRange(
      42           3 :         vcl::unotools::b2DRectangleFromRectangle(rRect));
      43           3 : }
      44             : 
      45           0 : void WinMtfClipPath::excludeClipRect( const Rectangle& rRect )
      46             : {
      47             :     maClip.subtractRange(
      48           0 :         vcl::unotools::b2DRectangleFromRectangle(rRect));
      49           0 : }
      50             : 
      51           8 : void WinMtfClipPath::setClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
      52             : {
      53           8 :     const basegfx::B2DPolyPolygon& rB2DPoly=rPolyPolygon.getB2DPolyPolygon();
      54           8 :     switch ( nClippingMode )
      55             :     {
      56             :         case RGN_OR :
      57           0 :             maClip.unionPolyPolygon(rB2DPoly);
      58           0 :             break;
      59             :         case RGN_XOR :
      60           0 :             maClip.xorPolyPolygon(rB2DPoly);
      61           0 :             break;
      62             :         case RGN_DIFF :
      63           0 :             maClip.subtractPolyPolygon(rB2DPoly);
      64           0 :             break;
      65             :         case RGN_AND :
      66           5 :             maClip.intersectPolyPolygon(rB2DPoly);
      67           5 :             break;
      68             :         case RGN_COPY :
      69           3 :             maClip = basegfx::tools::B2DClipState(rB2DPoly);
      70           3 :             break;
      71           8 :     }
      72           8 : }
      73             : 
      74           0 : void WinMtfClipPath::moveClipRegion( const Size& rSize )
      75             : {
      76             :     // what a weird concept. emulate, don't want this in B2DClipState
      77             :     // API
      78           0 :     basegfx::B2DPolyPolygon aCurrClip=maClip.getClipPoly();
      79           0 :     basegfx::B2DHomMatrix aTranslate;
      80           0 :     aTranslate.translate(rSize.Width(), rSize.Height());
      81             : 
      82           0 :     aCurrClip.transform(aTranslate);
      83           0 :     maClip = basegfx::tools::B2DClipState( aCurrClip );
      84           0 : }
      85             : 
      86           8 : basegfx::B2DPolyPolygon WinMtfClipPath::getClipPath() const
      87             : {
      88           8 :     return maClip.getClipPoly();
      89             : }
      90             : 
      91             : // ------------------------------------------------------------------------
      92             : 
      93          21 : void WinMtfPathObj::AddPoint( const Point& rPoint )
      94             : {
      95          21 :     if ( bClosed )
      96          19 :         Insert( Polygon(), POLYPOLY_APPEND );
      97          21 :     Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
      98          21 :     rPoly.Insert( rPoly.GetSize(), rPoint, POLY_NORMAL );
      99          21 :     bClosed = sal_False;
     100          21 : }
     101             : 
     102          21 : void WinMtfPathObj::AddPolyLine( const Polygon& rPolyLine )
     103             : {
     104          21 :     if ( bClosed )
     105           0 :         Insert( Polygon(), POLYPOLY_APPEND );
     106          21 :     Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
     107          21 :     rPoly.Insert( rPoly.GetSize(), rPolyLine );
     108          21 :     bClosed = sal_False;
     109          21 : }
     110             : 
     111           0 : void WinMtfPathObj::AddPolygon( const Polygon& rPoly )
     112             : {
     113           0 :     Insert( rPoly, POLYPOLY_APPEND );
     114           0 :     bClosed = sal_True;
     115           0 : }
     116             : 
     117           0 : void WinMtfPathObj::AddPolyPolygon( const PolyPolygon& rPolyPoly )
     118             : {
     119           0 :     sal_uInt16 i, nCount = rPolyPoly.Count();
     120           0 :     for ( i = 0; i < nCount; i++ )
     121           0 :         Insert( rPolyPoly[ i ], POLYPOLY_APPEND );
     122           0 :     bClosed = sal_True;
     123           0 : }
     124             : 
     125          13 : void WinMtfPathObj::ClosePath()
     126             : {
     127          13 :     if ( Count() )
     128             :     {
     129          13 :         Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
     130          13 :         if ( rPoly.GetSize() > 2 )
     131             :         {
     132          13 :             Point aFirst( rPoly[ 0 ] );
     133          13 :             if ( aFirst != rPoly[ rPoly.GetSize() - 1 ] )
     134          13 :                 rPoly.Insert( rPoly.GetSize(), aFirst, POLY_NORMAL );
     135             :         }
     136             :     }
     137          13 :     bClosed = sal_True;
     138          13 : }
     139             : 
     140             : // ------------------------------------------------------------------------
     141             : 
     142          65 : WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont )
     143             : {
     144             :     CharSet eCharSet;
     145          65 :     if ( ( rFont.lfCharSet == OEM_CHARSET ) || ( rFont.lfCharSet == DEFAULT_CHARSET ) )
     146           1 :         eCharSet = RTL_TEXTENCODING_MS_1252;
     147             :     else
     148          64 :         eCharSet = rtl_getTextEncodingFromWindowsCharset( rFont.lfCharSet );
     149          65 :     if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
     150           0 :         eCharSet = RTL_TEXTENCODING_MS_1252;
     151          65 :     aFont.SetCharSet( eCharSet );
     152          65 :     aFont.SetName( rFont.alfFaceName );
     153             :     FontFamily eFamily;
     154          65 :     switch ( rFont.lfPitchAndFamily & 0xf0 )
     155             :     {
     156             :         case FF_ROMAN:
     157           0 :             eFamily = FAMILY_ROMAN;
     158           0 :         break;
     159             : 
     160             :         case FF_SWISS:
     161          61 :             eFamily = FAMILY_SWISS;
     162          61 :         break;
     163             : 
     164             :         case FF_MODERN:
     165           0 :             eFamily = FAMILY_MODERN;
     166           0 :         break;
     167             : 
     168             :         case FF_SCRIPT:
     169           0 :             eFamily = FAMILY_SCRIPT;
     170           0 :         break;
     171             : 
     172             :         case FF_DECORATIVE:
     173           0 :              eFamily = FAMILY_DECORATIVE;
     174           0 :         break;
     175             : 
     176             :         default:
     177           4 :             eFamily = FAMILY_DONTKNOW;
     178           4 :         break;
     179             :     }
     180          65 :     aFont.SetFamily( eFamily );
     181             : 
     182             :     FontPitch ePitch;
     183          65 :     switch ( rFont.lfPitchAndFamily & 0x0f )
     184             :     {
     185             :         case FIXED_PITCH:
     186           0 :             ePitch = PITCH_FIXED;
     187           0 :         break;
     188             : 
     189             :         case DEFAULT_PITCH:
     190             :         case VARIABLE_PITCH:
     191             :         default:
     192          65 :             ePitch = PITCH_VARIABLE;
     193          65 :         break;
     194             :     }
     195          65 :     aFont.SetPitch( ePitch );
     196             : 
     197             :     FontWeight eWeight;
     198          65 :     if( rFont.lfWeight <= FW_THIN )
     199           0 :         eWeight = WEIGHT_THIN;
     200          65 :     else if( rFont.lfWeight <= FW_ULTRALIGHT )
     201           0 :         eWeight = WEIGHT_ULTRALIGHT;
     202          65 :     else if( rFont.lfWeight <= FW_LIGHT )
     203           0 :         eWeight = WEIGHT_LIGHT;
     204          65 :     else if( rFont.lfWeight <  FW_MEDIUM )
     205          64 :         eWeight = WEIGHT_NORMAL;
     206           1 :     else if( rFont.lfWeight == FW_MEDIUM )
     207           0 :         eWeight = WEIGHT_MEDIUM;
     208           1 :     else if( rFont.lfWeight <= FW_SEMIBOLD )
     209           0 :         eWeight = WEIGHT_SEMIBOLD;
     210           1 :     else if( rFont.lfWeight <= FW_BOLD )
     211           1 :         eWeight = WEIGHT_BOLD;
     212           0 :     else if( rFont.lfWeight <= FW_ULTRABOLD )
     213           0 :         eWeight = WEIGHT_ULTRABOLD;
     214             :     else
     215           0 :         eWeight = WEIGHT_BLACK;
     216          65 :     aFont.SetWeight( eWeight );
     217             : 
     218          65 :     if( rFont.lfItalic )
     219           0 :         aFont.SetItalic( ITALIC_NORMAL );
     220             : 
     221          65 :     if( rFont.lfUnderline )
     222           0 :         aFont.SetUnderline( UNDERLINE_SINGLE );
     223             : 
     224          65 :     if( rFont.lfStrikeOut )
     225           0 :         aFont.SetStrikeout( STRIKEOUT_SINGLE );
     226             : 
     227          65 :     if ( rFont.lfOrientation )
     228           0 :         aFont.SetOrientation( (short)rFont.lfOrientation );
     229             :     else
     230          65 :         aFont.SetOrientation( (short)rFont.lfEscapement );
     231             : 
     232          65 :     Size  aFontSize( Size( rFont.lfWidth, rFont.lfHeight ) );
     233          65 :     if ( rFont.lfHeight > 0 )
     234             :     {
     235             :         // converting the cell height into a font height
     236           0 :         VirtualDevice aVDev;
     237           0 :         aFont.SetSize( aFontSize );
     238           0 :         aVDev.SetFont( aFont );
     239           0 :         FontMetric aMetric( aVDev.GetFontMetric() );
     240           0 :         long nHeight = aMetric.GetAscent() + aMetric.GetDescent();
     241           0 :         if ( nHeight )
     242             :         {
     243           0 :             double fHeight = ((double)aFontSize.Height() * rFont.lfHeight ) / nHeight;
     244           0 :             aFontSize.Height() = (sal_Int32)( fHeight + 0.5 );
     245           0 :         }
     246             :     }
     247          65 :     else if ( aFontSize.Height() < 0 )
     248          65 :         aFontSize.Height() *= -1;
     249             : 
     250          65 :     if ( !rFont.lfWidth )
     251             :     {
     252          63 :         VirtualDevice aVDev;
     253          63 :         aFont.SetSize( aFontSize );
     254          63 :         aVDev.SetFont( aFont );
     255          63 :         FontMetric aMetric( aVDev.GetFontMetric() );
     256          63 :         aFontSize.Width() = aMetric.GetWidth();
     257             :     }
     258             : 
     259          65 :     aFont.SetSize( aFontSize );
     260          65 : };
     261             : 
     262             : // ------------------------------------------------------------------------
     263             : 
     264             : #ifdef WIN_MTF_ASSERT
     265             : void WinMtfAssertHandler( const sal_Char* pAction, sal_uInt32 nFlags )
     266             : {
     267             :     static sal_Bool     bOnlyOnce;
     268             :     static sal_Int32    nAssertCount;
     269             : 
     270             :     if ( nFlags & WIN_MTF_ASSERT_INIT )
     271             :         nAssertCount = 0;
     272             :     if ( nFlags & WIN_MTF_ASSERT_ONCE )
     273             :        bOnlyOnce = sal_True;
     274             :     if ( nFlags & WIN_MTF_ASSERT_MIFE )
     275             :     {
     276             :         if ( ( nAssertCount == 0 ) || ( bOnlyOnce == sal_False ) )
     277             :         {
     278             :             rtl::OStringBuffer aText(RTL_CONSTASCII_STRINGPARAM(
     279             :                 "WMF/EMF Import: "));
     280             :             if (pAction)
     281             :                 aText.append(pAction);
     282             :             aText.append(RTL_CONSTASCII_STRINGPARAM(
     283             :                 " needs to be implemented"));
     284             :             DBG_ASSERT( 0, aText.getStr() );
     285             :         }
     286             :         nAssertCount++;
     287             :     }
     288             : }
     289             : #endif
     290             : 
     291             : // ------------------------------------------------------------------------
     292             : 
     293          28 : WinMtf::WinMtf( WinMtfOutput* pWinMtfOutput, SvStream& rStreamWMF, FilterConfigItem* pConfigItem ) :
     294             :     pOut                ( pWinMtfOutput ),
     295             :     pWMF                ( &rStreamWMF ),
     296          28 :     pFilterConfigItem   ( pConfigItem )
     297             : {
     298             : #ifdef WIN_MTF_ASSERT
     299             :     // we want to assert not implemented features, but we do this
     300             :     // only once, so that nobody is handicaped by getting too much assertions
     301             :     // I hope this will bring more testdocuments, without support of these
     302             :     // testdocuments the implementation of missing features won't be possible. (SJ)
     303             :     WinMtfAssertHandler( NULL, WIN_MTF_ASSERT_INIT | WIN_MTF_ASSERT_ONCE );
     304             : #endif
     305             : 
     306          28 :     SvLockBytes *pLB = pWMF->GetLockBytes();
     307          28 :     if ( pLB )
     308           3 :         pLB->SetSynchronMode( sal_True );
     309             : 
     310          28 :     nStartPos = pWMF->Tell();
     311             : 
     312          28 :     pOut->SetDevOrg( Point() );
     313          28 :     if ( pFilterConfigItem )
     314             :     {
     315           0 :         xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
     316           0 :         if ( xStatusIndicator.is() )
     317             :         {
     318           0 :             rtl::OUString aMsg;
     319           0 :             xStatusIndicator->start( aMsg, 100 );
     320             :         }
     321             :     }
     322          28 : }
     323             : 
     324             : // ------------------------------------------------------------------------
     325             : 
     326          56 : WinMtf::~WinMtf()
     327             : {
     328          28 :     delete pOut;
     329             : 
     330          28 :     if ( xStatusIndicator.is() )
     331           0 :         xStatusIndicator->end();
     332          28 : }
     333             : 
     334             : // ------------------------------------------------------------------------
     335             : 
     336          86 : void WinMtf::Callback( sal_uInt16 nPercent )
     337             : {
     338          86 :     if ( xStatusIndicator.is() )
     339           0 :         xStatusIndicator->setValue( nPercent );
     340          86 : }
     341             : 
     342             : // ------------------------------------------------------------------------
     343             : 
     344         353 : Color WinMtf::ReadColor()
     345             : {
     346             :     sal_uInt32 nColor;
     347         353 :     *pWMF >> nColor;
     348         353 :     return Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
     349             : };
     350             : 
     351             : //-----------------------------------------------------------------------------------
     352             : //-----------------------------------------------------------------------------------
     353             : //-----------------------------------------------------------------------------------
     354             : 
     355        5572 : Point WinMtfOutput::ImplMap( const Point& rPt )
     356             : {
     357        5572 :     if ( mnWinExtX && mnWinExtY )
     358             :     {
     359        5572 :         double fX = rPt.X();
     360        5572 :         double fY = rPt.Y();
     361             : 
     362        5572 :         double fX2 = fX * maXForm.eM11 + fY * maXForm.eM21 + maXForm.eDx;
     363        5572 :         double fY2 = fX * maXForm.eM12 + fY * maXForm.eM22 + maXForm.eDy;
     364             : 
     365        5572 :         if ( mnGfxMode == GM_COMPATIBLE )
     366             :         {
     367        5572 :             switch( mnMapMode )
     368             :             {
     369             :                 case MM_TEXT:
     370         777 :                     fX2 -= mnWinOrgX;
     371         777 :                     fY2 -= mnWinOrgY;
     372         777 :                     if( mnDevWidth != 1 || mnDevHeight != 1 ) {
     373           0 :                         fX2 *= 2540.0/mnUnitsPerInch;
     374           0 :                         fY2 *= 2540.0/mnUnitsPerInch;
     375             :                     }
     376         777 :                     fX2 += mnDevOrgX;
     377         777 :                     fY2 += mnDevOrgY;
     378         777 :                     fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
     379         777 :                     fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
     380             : 
     381         777 :                     break;
     382             :                 case MM_LOENGLISH :
     383             :                 {
     384           0 :                     fX2 -= mnWinOrgX;
     385           0 :                     fY2  = mnWinOrgY-fY2;
     386           0 :                     fX2 *= 25.40;
     387           0 :                     fY2 *= 25.40;
     388           0 :                     fX2 += mnDevOrgX;
     389           0 :                     fY2 += mnDevOrgY;
     390             :                 }
     391           0 :                 break;
     392             :                 case MM_HIENGLISH :
     393             :                 {
     394           0 :                     fX2 -= mnWinOrgX;
     395           0 :                     fY2  = mnWinOrgY-fY2;
     396           0 :                     fX2 *= 2.540;
     397           0 :                     fY2 *= 2.540;
     398           0 :                     fX2 += mnDevOrgX;
     399           0 :                     fY2 += mnDevOrgY;
     400             :                 }
     401           0 :                 break;
     402             :                 case MM_LOMETRIC :
     403             :                 {
     404           0 :                     fX2 -= mnWinOrgX;
     405           0 :                     fY2  = mnWinOrgY-fY2;
     406           0 :                     fX2 *= 10;
     407           0 :                     fY2 *= 10;
     408           0 :                     fX2 += mnDevOrgX;
     409           0 :                     fY2 += mnDevOrgY;
     410             :                 }
     411           0 :                 break;
     412             :                 case MM_HIMETRIC :
     413             :                 {
     414           0 :                     fX2 -= mnWinOrgX;
     415           0 :                     fY2  = mnWinOrgY-fY2;
     416           0 :                     fX2 += mnDevOrgX;
     417           0 :                     fY2 += mnDevOrgY;
     418             :                 }
     419           0 :                 break;
     420             :                 default :
     421             :                 {
     422        4795 :                     fX2 -= mnWinOrgX;
     423        4795 :                     fY2 -= mnWinOrgY;
     424        4795 :                     fX2 /= mnWinExtX;
     425        4795 :                     fY2 /= mnWinExtY;
     426        4795 :                     fX2 *= mnDevWidth;
     427        4795 :                     fY2 *= mnDevHeight;
     428        4795 :                     fX2 += mnDevOrgX;
     429        4795 :                     fY2 += mnDevOrgY;   // fX2, fY2 now in device units
     430        4795 :                     fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
     431        4795 :                     fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
     432             :                 }
     433        4795 :                 break;
     434             :             }
     435        5572 :             fX2 -= mrclFrame.Left();
     436        5572 :             fY2 -= mrclFrame.Top();
     437             :         }
     438        5572 :         return Point( FRound( fX2 ), FRound( fY2 ) );
     439             :     }
     440             :     else
     441           0 :         return Point();
     442             : };
     443             : 
     444             : // ------------------------------------------------------------------------
     445             : 
     446         543 : Size WinMtfOutput::ImplMap( const Size& rSz )
     447             : {
     448         543 :     if ( mnWinExtX && mnWinExtY )
     449             :     {
     450         543 :         double fWidth = rSz.Width() * maXForm.eM11;
     451         543 :         double fHeight = rSz.Height() * maXForm.eM22;
     452             : 
     453         543 :         if ( mnGfxMode == GM_COMPATIBLE )
     454             :         {
     455         543 :             switch( mnMapMode )
     456             :             {
     457             :                 case MM_TEXT:
     458         414 :                 if( mnDevWidth != 1 && mnDevHeight != 1 ) {
     459           0 :                     fWidth *= 2540.0/mnUnitsPerInch;
     460           0 :                     fHeight*= 2540.0/mnUnitsPerInch;
     461             :                 } else {
     462         414 :                     fWidth *= (double)mnMillX * 100 / (double)mnPixX;
     463         414 :                     fHeight *= (double)mnMillY * 100 / (double)mnPixY;
     464             :                 }
     465         414 :                 break;
     466             :                 case MM_LOENGLISH :
     467             :                 {
     468           0 :                     fWidth *= 25.40;
     469           0 :                     fHeight*=-25.40;
     470             :                 }
     471           0 :                 break;
     472             :                 case MM_HIENGLISH :
     473             :                 {
     474           0 :                     fWidth *= 2.540;
     475           0 :                     fHeight*=-2.540;
     476             :                 }
     477           0 :                 break;
     478             :                 case MM_LOMETRIC :
     479             :                 {
     480           0 :                     fWidth *= 10;
     481           0 :                     fHeight*=-10;
     482             :                 }
     483           0 :                 break;
     484             :                 case MM_HIMETRIC :
     485             :                 {
     486           0 :                     fHeight *= -1;
     487             :                 }
     488           0 :                 break;
     489             :                 default :
     490             :                 {
     491         129 :                     fWidth /= mnWinExtX;
     492         129 :                     fHeight /= mnWinExtY;
     493         129 :                     fWidth *= mnDevWidth;
     494         129 :                     fHeight *= mnDevHeight;
     495         129 :                     fWidth *= (double)mnMillX * 100 / (double)mnPixX;
     496         129 :                     fHeight *= (double)mnMillY * 100 / (double)mnPixY;
     497             :                 }
     498         129 :                 break;
     499             :             }
     500             :         }
     501         543 :         return Size( FRound( fWidth ), FRound( fHeight ) );
     502             :     }
     503             :     else
     504           0 :         return Size();
     505             : }
     506             : 
     507             : //-----------------------------------------------------------------------------------
     508             : 
     509          42 : Rectangle WinMtfOutput::ImplMap( const Rectangle& rRect )
     510             : {
     511          42 :     return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) );
     512             : }
     513             : 
     514             : //-----------------------------------------------------------------------------------
     515             : 
     516          65 : void WinMtfOutput::ImplMap( Font& rFont )
     517             : {
     518             :     // !!! HACK: Wir setzen die Breite jetzt immer auf Null,
     519             :     // da OS die Breite unterschiedlich interpretieren;
     520             :     // muss spaeter in SV portabel gemacht werden ( KA 08.02.96 )
     521          65 :     Size  aFontSize = ImplMap ( rFont.GetSize() );
     522             : 
     523          65 :     if( aFontSize.Height() < 0 )
     524           1 :         aFontSize.Height() *= -1;
     525             : 
     526          65 :     rFont.SetSize( aFontSize );
     527             : 
     528          65 :     if( ( mnWinExtX * mnWinExtY ) < 0 )
     529           0 :         rFont.SetOrientation( 3600 - rFont.GetOrientation() );
     530          65 : }
     531             : 
     532             : //-----------------------------------------------------------------------------------
     533             : 
     534         222 : Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
     535             : {
     536         222 :     sal_uInt16 nPoints = rPolygon.GetSize();
     537        5635 :     for ( sal_uInt16 i = 0; i < nPoints; i++ )
     538             :     {
     539        5413 :         rPolygon[ i ] = ImplMap( rPolygon[ i ] );
     540             :     }
     541         222 :     return rPolygon;
     542             : }
     543             : 
     544             : //-----------------------------------------------------------------------------------
     545             : 
     546           9 : PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
     547             : {
     548           9 :     sal_uInt16 nPolys = rPolyPolygon.Count();
     549           9 :     for ( sal_uInt16 i = 0; i < nPolys; ImplMap( rPolyPolygon[ i++ ] ) ) ;
     550           9 :     return rPolyPolygon;
     551             : }
     552             : 
     553             : //-----------------------------------------------------------------------------------
     554             : 
     555         684 : void WinMtfOutput::SelectObject( sal_Int32 nIndex )
     556             : {
     557         684 :     GDIObj* pGDIObj = NULL;
     558             : 
     559         684 :     if ( nIndex & ENHMETA_STOCK_OBJECT )
     560         319 :         pGDIObj = new GDIObj();
     561             :     else
     562             :     {
     563         365 :         nIndex &= 0xffff;       // zur Sicherheit: mehr als 65535 nicht zulassen
     564             : 
     565         365 :         if ( (sal_uInt32)nIndex < vGDIObj.size() )
     566         365 :             pGDIObj = vGDIObj[ nIndex ];
     567             :     }
     568             : 
     569         684 :     if( pGDIObj == NULL )
     570         689 :         return;
     571             : 
     572         679 :     if ( nIndex & ENHMETA_STOCK_OBJECT )
     573             :     {
     574         319 :         sal_uInt16 nStockId = (sal_uInt8)nIndex;
     575         319 :         switch( nStockId )
     576             :         {
     577             :             case WHITE_BRUSH :
     578             :             {
     579           3 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ) ) );
     580             :             }
     581           3 :             break;
     582             :             case LTGRAY_BRUSH :
     583             :             {
     584          63 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_LIGHTGRAY ) ) );
     585             :             }
     586          63 :             break;
     587             :             case GRAY_BRUSH :
     588             :             case DKGRAY_BRUSH :
     589             :             {
     590           3 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_GRAY ) ) );
     591             :             }
     592           3 :             break;
     593             :             case BLACK_BRUSH :
     594             :             {
     595           3 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_BLACK ) ) );
     596             :             }
     597           3 :             break;
     598             :             case NULL_BRUSH :
     599             :             {
     600           0 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True ) );
     601             :             }
     602           0 :             break;
     603             :             case WHITE_PEN :
     604             :             {
     605           0 :                 pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_WHITE ) ) );
     606             :             }
     607           0 :             break;
     608             :             case BLACK_PEN :
     609             :             {
     610         192 :                 pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_BLACK ) ) );
     611             :             }
     612         192 :             break;
     613             :             case NULL_PEN :
     614             :             {
     615           0 :                 pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True ) );
     616             :             }
     617           0 :             break;
     618             :             default:
     619          55 :             break;
     620             :         }
     621             :     }
     622         679 :     if ( pGDIObj->pStyle )
     623             :     {
     624         624 :         switch( pGDIObj->eType )
     625             :         {
     626             :             case GDI_PEN :
     627         406 :                 maLineStyle = (WinMtfLineStyle*)pGDIObj->pStyle;
     628         406 :             break;
     629             :             case GDI_BRUSH :
     630             :             {
     631         153 :                 maFillStyle = (WinMtfFillStyle*)pGDIObj->pStyle;
     632         153 :                 mbFillStyleSelected = sal_True;
     633             :             }
     634         153 :             break;
     635             :             case GDI_FONT :
     636          65 :                 maFont = ((WinMtfFontStyle*)pGDIObj->pStyle)->aFont;
     637          65 :             break;
     638             :             default:
     639           0 :             break;  //  -Wall many options not handled.
     640             :         }
     641             :     }
     642         679 :     if ( nIndex & ENHMETA_STOCK_OBJECT )
     643         319 :         delete pGDIObj;
     644             : }
     645             : 
     646             : //-----------------------------------------------------------------------------------
     647             : 
     648           0 : const Font& WinMtfOutput::GetFont() const
     649             : {
     650           0 :     return maFont;
     651             : }
     652             : 
     653             : //-----------------------------------------------------------------------------------
     654             : 
     655          65 : void WinMtfOutput::SetTextLayoutMode( const sal_uInt32 nTextLayoutMode )
     656             : {
     657          65 :     mnTextLayoutMode = nTextLayoutMode;
     658          65 : }
     659             : 
     660             : //-----------------------------------------------------------------------------------
     661             : 
     662          11 : void WinMtfOutput::SetBkMode( sal_uInt32 nMode )
     663             : {
     664          11 :     mnBkMode = nMode;
     665          11 : }
     666             : 
     667             : //-----------------------------------------------------------------------------------
     668             : 
     669           6 : void WinMtfOutput::SetBkColor( const Color& rColor )
     670             : {
     671           6 :     maBkColor = rColor;
     672           6 : }
     673             : 
     674             : //-----------------------------------------------------------------------------------
     675             : 
     676          62 : void WinMtfOutput::SetTextColor( const Color& rColor )
     677             : {
     678          62 :     maTextColor = rColor;
     679          62 : }
     680             : 
     681             : //-----------------------------------------------------------------------------------
     682             : 
     683          59 : void WinMtfOutput::SetTextAlign( sal_uInt32 nAlign )
     684             : {
     685          59 :     mnTextAlign = nAlign;
     686          59 : }
     687             : 
     688             : //-----------------------------------------------------------------------------------
     689             : 
     690          17 : void WinMtfOutput::ImplResizeObjectArry( sal_uInt32 nNewEntrys )
     691             : {
     692          17 :     sal_uInt32 i = vGDIObj.size();
     693          17 :     vGDIObj.resize( nNewEntrys );
     694         299 :     for ( ; i < nNewEntrys ; i++ )
     695         282 :         vGDIObj[ i ] = NULL;
     696          17 : }
     697             : 
     698             : //-----------------------------------------------------------------------------------
     699             : 
     700           0 : void WinMtfOutput::ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly )
     701             : {
     702           0 :     if ( rPolyPoly.Count() )
     703             :     {
     704           0 :         ImplSetNonPersistentLineColorTransparenz();
     705           0 :         if ( rPolyPoly.Count() == 1 )
     706             :         {
     707           0 :             if ( rPolyPoly.IsRect() )
     708           0 :                 mpGDIMetaFile->AddAction( new MetaRectAction( rPolyPoly.GetBoundRect() ) );
     709             :             else
     710             :             {
     711           0 :                 Polygon aPoly( rPolyPoly[ 0 ] );
     712           0 :                 sal_uInt16 nCount = aPoly.GetSize();
     713           0 :                 if ( nCount )
     714             :                 {
     715           0 :                     if ( aPoly[ nCount - 1 ] != aPoly[ 0 ] )
     716             :                     {
     717           0 :                         Point aPoint( aPoly[ 0 ] );
     718           0 :                         aPoly.Insert( nCount, aPoint );
     719             :                     }
     720           0 :                     mpGDIMetaFile->AddAction( new MetaPolygonAction( aPoly ) );
     721           0 :                 }
     722             :             }
     723             :         }
     724             :         else
     725           0 :             mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
     726             :     }
     727           0 : }
     728             : 
     729             : 
     730             : //-----------------------------------------------------------------------------------
     731             : 
     732          25 : void WinMtfOutput::CreateObject( GDIObjectType eType, void* pStyle )
     733             : {
     734          25 :     if ( pStyle )
     735             :     {
     736          25 :         if ( eType == GDI_FONT )
     737             :         {
     738           2 :             ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
     739           2 :             if (!((WinMtfFontStyle*)pStyle)->aFont.GetHeight() )
     740           0 :                 ((WinMtfFontStyle*)pStyle)->aFont.SetHeight( 423 );     // defaulting to 12pt
     741             :         }
     742          23 :         else if ( eType == GDI_PEN )
     743             :         {
     744           8 :             Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
     745           8 :             ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
     746           8 :             if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
     747             :             {
     748           0 :                 aSize.Width() += 1;
     749           0 :                 long nDotLen = ImplMap( aSize ).Width();
     750           0 :                 ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
     751           0 :                 ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
     752           0 :                 ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
     753             :             }
     754             :         }
     755             :     }
     756             :     sal_uInt32 nIndex;
     757          47 :     for ( nIndex = 0; nIndex < vGDIObj.size(); nIndex++ )
     758             :     {
     759          40 :         if ( vGDIObj[ nIndex ] == NULL )
     760          18 :             break;
     761             :     }
     762          25 :     if ( nIndex == vGDIObj.size() )
     763           7 :         ImplResizeObjectArry( vGDIObj.size() + 16 );
     764             : 
     765          25 :     vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
     766          25 : }
     767             : 
     768             : //-----------------------------------------------------------------------------------
     769             : 
     770         326 : void WinMtfOutput::CreateObject( sal_Int32 nIndex, GDIObjectType eType, void* pStyle )
     771             : {
     772         326 :     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     773             :     {
     774         326 :         nIndex &= 0xffff;       // zur Sicherheit: mehr als 65535 nicht zulassen
     775         326 :         if ( pStyle )
     776             :         {
     777         326 :             if ( eType == GDI_FONT )
     778          63 :                 ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
     779         263 :             else if ( eType == GDI_PEN )
     780             :             {
     781         198 :                 Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
     782         198 :                 ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
     783         198 :                 if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
     784             :                 {
     785           0 :                     aSize.Width() += 1;
     786           0 :                     long nDotLen = ImplMap( aSize ).Width();
     787           0 :                     ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
     788           0 :                     ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
     789           0 :                     ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
     790             :                 }
     791             :             }
     792             :         }
     793         326 :         if ( (sal_uInt32)nIndex >= vGDIObj.size() )
     794          10 :             ImplResizeObjectArry( nIndex + 16 );
     795             : 
     796         326 :         if ( vGDIObj[ nIndex ] != NULL )
     797           0 :             delete vGDIObj[ nIndex ];
     798             : 
     799         326 :         vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
     800             :     }
     801             :     else
     802             :     {
     803           0 :         switch ( eType )
     804             :         {
     805             :             case GDI_PEN :
     806           0 :                 delete (WinMtfLineStyle*)pStyle;
     807           0 :             break;
     808             :             case GDI_BRUSH :
     809           0 :                 delete (WinMtfFillStyle*)pStyle;
     810           0 :             break;
     811             :             case GDI_FONT :
     812           0 :                 delete (WinMtfFontStyle*)pStyle;
     813           0 :             break;
     814             : 
     815             :             default:
     816             :                 OSL_FAIL( "unsupported style not deleted" );
     817           0 :                 break;
     818             :         }
     819             :     }
     820         326 : }
     821             : 
     822             : //-----------------------------------------------------------------------------------
     823             : 
     824         323 : void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
     825             : {
     826         323 :     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     827             :     {
     828         323 :         if ( (sal_uInt32)nIndex < vGDIObj.size() )
     829             :         {
     830         323 :             delete vGDIObj[ nIndex ];
     831         323 :             vGDIObj[ nIndex ] = NULL;
     832             :         }
     833             :     }
     834         323 : }
     835             : 
     836             : //-----------------------------------------------------------------------------------
     837             : 
     838           3 : void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
     839             : {
     840           3 :     mbClipNeedsUpdate=true;
     841           3 :     aClipPath.intersectClipRect( ImplMap( rRect ) );
     842           3 : }
     843             : 
     844             : //-----------------------------------------------------------------------------------
     845             : 
     846           0 : void WinMtfOutput::ExcludeClipRect( const Rectangle& rRect )
     847             : {
     848           0 :     mbClipNeedsUpdate=true;
     849           0 :     aClipPath.excludeClipRect( ImplMap( rRect ) );
     850           0 : }
     851             : 
     852             : //-----------------------------------------------------------------------------------
     853             : 
     854           0 : void WinMtfOutput::MoveClipRegion( const Size& rSize )
     855             : {
     856           0 :     mbClipNeedsUpdate=true;
     857           0 :     aClipPath.moveClipRegion( ImplMap( rSize ) );
     858           0 : }
     859             : 
     860           8 : void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, sal_Bool bIsMapped )
     861             : {
     862           8 :     mbClipNeedsUpdate=true;
     863           8 :     if ( bIsMapped )
     864           5 :         aClipPath.setClipPath( rPolyPolygon, nClippingMode );
     865             :     else
     866             :     {
     867           3 :         PolyPolygon aPP( rPolyPolygon );
     868           3 :         aClipPath.setClipPath( ImplMap( aPP ), nClippingMode );
     869             :     }
     870           8 : }
     871             : 
     872             : //-----------------------------------------------------------------------------------
     873             : //-----------------------------------------------------------------------------------
     874             : //-----------------------------------------------------------------------------------
     875             : 
     876          28 : WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
     877             :     mnLatestTextAlign   ( 0 ),
     878             :     mnTextAlign         ( TA_LEFT | TA_TOP | TA_NOUPDATECP ),
     879             :     maLatestBkColor     ( 0x12345678 ),
     880             :     maBkColor           ( COL_WHITE ),
     881             :     mnLatestTextLayoutMode( TEXT_LAYOUT_DEFAULT ),
     882             :     mnTextLayoutMode    ( TEXT_LAYOUT_DEFAULT ),
     883             :     mnLatestBkMode      ( 0 ),
     884             :     mnBkMode            ( OPAQUE ),
     885             :     meLatestRasterOp    ( ROP_INVERT ),
     886             :     meRasterOp          ( ROP_OVERPAINT ),
     887             :     maActPos            ( Point() ),
     888             :     mbNopMode           ( sal_False ),
     889             :     mbFillStyleSelected ( sal_False ),
     890             :     mbClipNeedsUpdate   ( true ),
     891             :     mbComplexClip       ( false ),
     892             :     mnGfxMode           ( GM_COMPATIBLE ),
     893             :     mnMapMode           ( MM_TEXT ),
     894             :     mnUnitsPerInch ( 96 ),
     895             :     mnDevOrgX           ( 0 ),
     896             :     mnDevOrgY           ( 0 ),
     897             :     mnDevWidth          ( 1 ),
     898             :     mnDevHeight         ( 1 ),
     899             :     mnWinOrgX           ( 0 ),
     900             :     mnWinOrgY           ( 0 ),
     901             :     mnWinExtX           ( 1 ),
     902             :     mnWinExtY           ( 1 ),
     903             :     mnPixX              ( 100 ),
     904             :     mnPixY              ( 100 ),
     905             :     mnMillX             ( 1 ),
     906             :     mnMillY             ( 1 ),
     907          28 :     mpGDIMetaFile       ( &rGDIMetaFile )
     908             : {
     909          28 :     mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) );      // The original clipregion has to be on top
     910             :                                                                             // of the stack so it can always be restored
     911             :                                                                             // this is necessary to be able to support
     912             :                                                                             // SetClipRgn( NULL ) and similar ClipRgn actions (SJ)
     913             : 
     914          28 :     maFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Arial" )) );  // sj: #i57205#, we do have some scaling problems if using
     915          28 :     maFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );                      // the default font then most times a x11 font is used, we
     916          28 :     maFont.SetHeight( 423 );                                                // will prevent this defining a font
     917             : 
     918          28 :     maLatestLineStyle.aLineColor = Color( 0x12, 0x34, 0x56 );
     919          28 :     maLatestFillStyle.aFillColor = Color( 0x12, 0x34, 0x56 );
     920             : 
     921          28 :     mnRop = R2_BLACK + 1;
     922          28 :     SetRasterOp( R2_BLACK );
     923          28 : };
     924             : 
     925             : //-----------------------------------------------------------------------------------
     926             : 
     927          84 : WinMtfOutput::~WinMtfOutput()
     928             : {
     929          28 :     mpGDIMetaFile->AddAction( new MetaPopAction() );
     930          28 :     mpGDIMetaFile->SetPrefMapMode( MAP_100TH_MM );
     931          28 :     if ( mrclFrame.IsEmpty() )
     932          13 :         mpGDIMetaFile->SetPrefSize( Size( mnDevWidth, mnDevHeight ) );
     933             :     else
     934          15 :         mpGDIMetaFile->SetPrefSize( mrclFrame.GetSize() );
     935             : 
     936         310 :     for ( sal_uInt32 i = 0; i < vGDIObj.size(); i++ )
     937         282 :         delete vGDIObj[ i ];
     938          56 : };
     939             : 
     940             : //-----------------------------------------------------------------------------------
     941             : 
     942         448 : void WinMtfOutput::UpdateClipRegion()
     943             : {
     944         448 :     if ( mbClipNeedsUpdate )
     945             :     {
     946          24 :         mbClipNeedsUpdate = false;
     947          24 :         mbComplexClip = false;
     948             : 
     949          24 :         mpGDIMetaFile->AddAction( new MetaPopAction() );                    // taking the orignal clipregion
     950          24 :         mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) );  //
     951             : 
     952             :         // skip for 'no clipping at all' case
     953          24 :         if( !aClipPath.isEmpty() )
     954             :         {
     955           8 :             const basegfx::B2DPolyPolygon& rClipPoly( aClipPath.getClipPath() );
     956             :             mpGDIMetaFile->AddAction(
     957             :                 new MetaISectRectClipRegionAction(
     958             :                     vcl::unotools::rectangleFromB2DRectangle(
     959           8 :                         rClipPoly.getB2DRange())));
     960             : 
     961           8 :             mbComplexClip = rClipPoly.count() > 1
     962           8 :                 || !basegfx::tools::isRectangle(rClipPoly);
     963             :         }
     964             :     }
     965         448 : }
     966             : 
     967             : //-----------------------------------------------------------------------------------
     968             : 
     969          31 : void WinMtfOutput::ImplSetNonPersistentLineColorTransparenz()
     970             : {
     971          31 :     Color aColor(  COL_TRANSPARENT);
     972          31 :     WinMtfLineStyle aTransparentLine( aColor, sal_True );
     973          31 :     if ( ! ( maLatestLineStyle == aTransparentLine ) )
     974             :     {
     975           4 :         maLatestLineStyle = aTransparentLine;
     976           4 :         mpGDIMetaFile->AddAction( new MetaLineColorAction( aTransparentLine.aLineColor, !aTransparentLine.bTransparent ) );
     977          31 :     }
     978          31 : }
     979             : 
     980             : //-----------------------------------------------------------------------------------
     981             : 
     982         221 : void WinMtfOutput::UpdateLineStyle()
     983             : {
     984         221 :     if (!( maLatestLineStyle == maLineStyle ) )
     985             :     {
     986         113 :         maLatestLineStyle = maLineStyle;
     987         113 :         mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
     988             :     }
     989         221 : }
     990             : 
     991             : //-----------------------------------------------------------------------------------
     992             : 
     993         143 : void WinMtfOutput::UpdateFillStyle()
     994             : {
     995         143 :     if ( !mbFillStyleSelected )     // SJ: #i57205# taking care of bkcolor if no brush is selected
     996           1 :         maFillStyle = WinMtfFillStyle( maBkColor, mnBkMode == TRANSPARENT );
     997         143 :     if (!( maLatestFillStyle == maFillStyle ) )
     998             :     {
     999          57 :         maLatestFillStyle = maFillStyle;
    1000          57 :         if (maFillStyle.aType == FillStyleSolid)
    1001          57 :             mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
    1002             :     }
    1003         143 : }
    1004             : 
    1005             : //-----------------------------------------------------------------------------------
    1006             : 
    1007         165 : sal_uInt32 WinMtfOutput::SetRasterOp( sal_uInt32 nRasterOp )
    1008             : {
    1009         165 :     sal_uInt32 nRetROP = mnRop;
    1010         165 :     if ( nRasterOp != mnRop )
    1011             :     {
    1012          94 :         mnRop = nRasterOp;
    1013          94 :         static WinMtfFillStyle aNopFillStyle;
    1014          94 :         static WinMtfLineStyle aNopLineStyle;
    1015             : 
    1016          94 :         if ( mbNopMode && ( nRasterOp != R2_NOP ) )
    1017             :         {   // beim uebergang von R2_NOP auf anderen Modus
    1018             :             // gesetzten Pen und Brush aktivieren
    1019           0 :             maFillStyle = aNopFillStyle;
    1020           0 :             maLineStyle = aNopLineStyle;
    1021           0 :             mbNopMode = sal_False;
    1022             :         }
    1023          94 :         switch( nRasterOp )
    1024             :         {
    1025             :             case R2_NOT:
    1026           0 :                 meRasterOp = ROP_INVERT;
    1027           0 :             break;
    1028             : 
    1029             :             case R2_XORPEN:
    1030           0 :                 meRasterOp = ROP_XOR;
    1031           0 :             break;
    1032             : 
    1033             :             case R2_NOP:
    1034             :             {
    1035           0 :                 meRasterOp = ROP_OVERPAINT;
    1036           0 :                 if( mbNopMode == sal_False )
    1037             :                 {
    1038           0 :                     aNopFillStyle = maFillStyle;
    1039           0 :                     aNopLineStyle = maLineStyle;
    1040           0 :                     maFillStyle = WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True );
    1041           0 :                     maLineStyle = WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True );
    1042           0 :                     mbNopMode = sal_True;
    1043             :                 }
    1044             :             }
    1045           0 :             break;
    1046             : 
    1047             :             default:
    1048          94 :                 meRasterOp = ROP_OVERPAINT;
    1049          94 :             break;
    1050             :         }
    1051             :     }
    1052         165 :     if ( nRetROP != nRasterOp )
    1053          94 :         mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
    1054         165 :     return nRetROP;
    1055             : };
    1056             : 
    1057             : //-----------------------------------------------------------------------------------
    1058             : 
    1059          11 : void WinMtfOutput::StrokeAndFillPath( sal_Bool bStroke, sal_Bool bFill )
    1060             : {
    1061          11 :     if ( aPathObj.Count() )
    1062             :     {
    1063          11 :         UpdateClipRegion();
    1064          11 :         UpdateLineStyle();
    1065          11 :         UpdateFillStyle();
    1066          11 :         if ( bFill )
    1067             :         {
    1068          11 :             if ( !bStroke )
    1069             :             {
    1070          11 :                 mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
    1071          11 :                 mpGDIMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
    1072             :             }
    1073          11 :             if ( aPathObj.Count() == 1 )
    1074           6 :                 mpGDIMetaFile->AddAction( new MetaPolygonAction( aPathObj.GetObject( 0 ) ) );
    1075             :             else
    1076           5 :                 mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( aPathObj ) );
    1077             : 
    1078          11 :             if ( !bStroke )
    1079          11 :                 mpGDIMetaFile->AddAction( new MetaPopAction() );
    1080             :         }
    1081             :         else
    1082             :         {
    1083           0 :             sal_uInt16 i, nCount = aPathObj.Count();
    1084           0 :             for ( i = 0; i < nCount; i++ )
    1085           0 :                 mpGDIMetaFile->AddAction( new MetaPolyLineAction( aPathObj[ i ], maLineStyle.aLineInfo ) );
    1086             :         }
    1087          11 :         ClearPath();
    1088             :     }
    1089          11 : }
    1090             : 
    1091             : //-----------------------------------------------------------------------------------
    1092             : 
    1093           0 : void WinMtfOutput::DrawPixel( const Point& rSource, const Color& rColor )
    1094             : {
    1095           0 :     mpGDIMetaFile->AddAction( new MetaPixelAction( ImplMap( rSource), rColor ) );
    1096           0 : }
    1097             : 
    1098             : //-----------------------------------------------------------------------------------
    1099             : 
    1100          21 : void WinMtfOutput::MoveTo( const Point& rPoint, sal_Bool bRecordPath )
    1101             : {
    1102          21 :     Point aDest( ImplMap( rPoint ) );
    1103          21 :     if ( bRecordPath )
    1104             :     {
    1105             :         // fdo#57353 create new subpath for subsequent moves
    1106          21 :         if ( aPathObj.Count() )
    1107           5 :             if ( aPathObj[ aPathObj.Count() - 1 ].GetSize() )
    1108           5 :                 aPathObj.Insert( Polygon(), POLYPOLY_APPEND );
    1109          21 :         aPathObj.AddPoint( aDest );
    1110             :     }
    1111          21 :     maActPos = aDest;
    1112          21 : }
    1113             : 
    1114             : //-----------------------------------------------------------------------------------
    1115             : 
    1116           0 : void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
    1117             : {
    1118           0 :     UpdateClipRegion();
    1119             : 
    1120           0 :     Point aDest( ImplMap( rPoint ) );
    1121           0 :     if ( bRecordPath )
    1122           0 :         aPathObj.AddPoint( aDest );
    1123             :     else
    1124             :     {
    1125           0 :         UpdateLineStyle();
    1126           0 :         mpGDIMetaFile->AddAction( new MetaLineAction( maActPos, aDest, maLineStyle.aLineInfo ) );
    1127             :     }
    1128           0 :     maActPos = aDest;
    1129           0 : }
    1130             : 
    1131             : //-----------------------------------------------------------------------------------
    1132             : 
    1133          39 : void WinMtfOutput::DrawRect( const Rectangle& rRect, sal_Bool bEdge )
    1134             : {
    1135          39 :     UpdateClipRegion();
    1136          39 :     UpdateFillStyle();
    1137             : 
    1138          39 :     if ( mbComplexClip )
    1139             :     {
    1140           0 :         Polygon aPoly( ImplMap( rRect ) );
    1141           0 :         PolyPolygon aPolyPolyRect( aPoly );
    1142           0 :         PolyPolygon aDest;
    1143           0 :         PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPolyRect, aDest );
    1144           0 :         ImplDrawClippedPolyPolygon( aDest );
    1145             :     }
    1146             :     else
    1147             :     {
    1148          39 :         if ( bEdge )
    1149             :         {
    1150           9 :             if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1151             :             {
    1152           0 :                 ImplSetNonPersistentLineColorTransparenz();
    1153           0 :                 mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
    1154           0 :                 UpdateLineStyle();
    1155           0 :                 mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect ) ),maLineStyle.aLineInfo ) );
    1156             :             }
    1157             :             else
    1158             :             {
    1159           9 :                 UpdateLineStyle();
    1160           9 :                 mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
    1161             :             }
    1162             :         }
    1163             :         else
    1164             :         {
    1165          30 :             ImplSetNonPersistentLineColorTransparenz();
    1166          30 :             mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
    1167             :         }
    1168             :     }
    1169          39 : }
    1170             : 
    1171             : //-----------------------------------------------------------------------------------
    1172             : 
    1173           0 : void WinMtfOutput::DrawRoundRect( const Rectangle& rRect, const Size& rSize )
    1174             : {
    1175           0 :     UpdateClipRegion();
    1176           0 :     UpdateLineStyle();
    1177           0 :     UpdateFillStyle();
    1178           0 :     mpGDIMetaFile->AddAction( new MetaRoundRectAction( ImplMap( rRect ), labs( ImplMap( rSize ).Width() ), labs( ImplMap( rSize ).Height() ) ) );
    1179           0 : }
    1180             : 
    1181             : //-----------------------------------------------------------------------------------
    1182             : 
    1183           0 : void WinMtfOutput::DrawEllipse( const Rectangle& rRect )
    1184             : {
    1185           0 :     UpdateClipRegion();
    1186           0 :     UpdateFillStyle();
    1187             : 
    1188           0 :     if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1189             :     {
    1190           0 :         Point aCenter( ImplMap( rRect.Center() ) );
    1191           0 :         Size  aRad( ImplMap( Size( rRect.GetWidth() / 2, rRect.GetHeight() / 2 ) ) );
    1192             : 
    1193           0 :         ImplSetNonPersistentLineColorTransparenz();
    1194           0 :         mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
    1195           0 :         UpdateLineStyle();
    1196           0 :         mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
    1197             :     }
    1198             :     else
    1199             :     {
    1200           0 :         UpdateLineStyle();
    1201           0 :         mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
    1202             :     }
    1203           0 : }
    1204             : 
    1205             : //-----------------------------------------------------------------------------------
    1206             : 
    1207           0 : void WinMtfOutput::DrawArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, sal_Bool bTo )
    1208             : {
    1209           0 :     UpdateClipRegion();
    1210           0 :     UpdateLineStyle();
    1211           0 :     UpdateFillStyle();
    1212             : 
    1213           0 :     Rectangle   aRect( ImplMap( rRect ) );
    1214           0 :     Point       aStart( ImplMap( rStart ) );
    1215           0 :     Point       aEnd( ImplMap( rEnd ) );
    1216             : 
    1217           0 :     if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1218             :     {
    1219           0 :         if ( aStart == aEnd )
    1220             :         {   // SJ: #i53768# if start & end is identical, then we have to draw a full ellipse
    1221           0 :             Point aCenter( aRect.Center() );
    1222           0 :             Size  aRad( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
    1223             : 
    1224           0 :             mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
    1225             :         }
    1226             :         else
    1227           0 :             mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_ARC ), maLineStyle.aLineInfo ) );
    1228             :     }
    1229             :     else
    1230           0 :         mpGDIMetaFile->AddAction( new MetaArcAction( aRect, aStart, aEnd ) );
    1231             : 
    1232           0 :     if ( bTo )
    1233           0 :         maActPos = aEnd;
    1234           0 : }
    1235             : 
    1236             : //-----------------------------------------------------------------------------------
    1237             : 
    1238           0 : void WinMtfOutput::DrawPie( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
    1239             : {
    1240           0 :     UpdateClipRegion();
    1241           0 :     UpdateFillStyle();
    1242             : 
    1243           0 :     Rectangle   aRect( ImplMap( rRect ) );
    1244           0 :     Point       aStart( ImplMap( rStart ) );
    1245           0 :     Point       aEnd( ImplMap( rEnd ) );
    1246             : 
    1247           0 :     if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1248             :     {
    1249           0 :         ImplSetNonPersistentLineColorTransparenz();
    1250           0 :         mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
    1251           0 :         UpdateLineStyle();
    1252           0 :         mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_PIE ), maLineStyle.aLineInfo ) );
    1253             :     }
    1254             :     else
    1255             :     {
    1256           0 :         UpdateLineStyle();
    1257           0 :         mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
    1258             :     }
    1259           0 : }
    1260             : 
    1261             : //-----------------------------------------------------------------------------------
    1262             : 
    1263           0 : void WinMtfOutput::DrawChord( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
    1264             : {
    1265           0 :     UpdateClipRegion();
    1266           0 :     UpdateFillStyle();
    1267             : 
    1268           0 :     Rectangle   aRect( ImplMap( rRect ) );
    1269           0 :     Point       aStart( ImplMap( rStart ) );
    1270           0 :     Point       aEnd( ImplMap( rEnd ) );
    1271             : 
    1272           0 :     if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1273             :     {
    1274           0 :         ImplSetNonPersistentLineColorTransparenz();
    1275           0 :         mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
    1276           0 :         UpdateLineStyle();
    1277           0 :         mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_CHORD ), maLineStyle.aLineInfo ) );
    1278             :     }
    1279             :     else
    1280             :     {
    1281           0 :         UpdateLineStyle();
    1282           0 :         mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
    1283             :     }
    1284           0 : }
    1285             : 
    1286             : //-----------------------------------------------------------------------------------
    1287             : 
    1288          57 : void WinMtfOutput::DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath )
    1289             : {
    1290          57 :     UpdateClipRegion();
    1291          57 :     ImplMap( rPolygon );
    1292          57 :     if ( bRecordPath )
    1293           0 :         aPathObj.AddPolygon( rPolygon );
    1294             :     else
    1295             :     {
    1296          57 :         UpdateFillStyle();
    1297             : 
    1298          57 :         if ( mbComplexClip )
    1299             :         {
    1300           0 :             PolyPolygon aPolyPoly( rPolygon );
    1301           0 :             PolyPolygon aDest;
    1302           0 :             PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPoly, aDest );
    1303           0 :             ImplDrawClippedPolyPolygon( aDest );
    1304             :         }
    1305             :         else
    1306             :         {
    1307          57 :             if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1308             :             {
    1309           1 :                 sal_uInt16 nCount = rPolygon.GetSize();
    1310           1 :                 if ( nCount )
    1311             :                 {
    1312           1 :                     if ( rPolygon[ nCount - 1 ] != rPolygon[ 0 ] )
    1313             :                     {
    1314           0 :                         Point aPoint( rPolygon[ 0 ] );
    1315           0 :                         rPolygon.Insert( nCount, aPoint );
    1316             :                     }
    1317             :                 }
    1318           1 :                 ImplSetNonPersistentLineColorTransparenz();
    1319           1 :                 mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
    1320           1 :                 UpdateLineStyle();
    1321           1 :                 mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
    1322             :             }
    1323             :             else
    1324             :             {
    1325          56 :                 UpdateLineStyle();
    1326             : 
    1327          56 :                 if (maLatestFillStyle.aType != FillStylePattern)
    1328          56 :                     mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
    1329             :                 else {
    1330             :                     SvtGraphicFill aFill = SvtGraphicFill( PolyPolygon( rPolygon ),
    1331             :                                                            Color(),
    1332             :                                                            0.0,
    1333             :                                                            SvtGraphicFill::fillNonZero,
    1334             :                                                            SvtGraphicFill::fillTexture,
    1335             :                                                            SvtGraphicFill::Transform(),
    1336             :                                                            true,
    1337             :                                                            SvtGraphicFill::hatchSingle,
    1338             :                                                            Color(),
    1339             :                                                            SvtGraphicFill::gradientLinear,
    1340             :                                                            Color(),
    1341             :                                                            Color(),
    1342             :                                                            0,
    1343           0 :                                                            Graphic (maLatestFillStyle.aBmp) );
    1344             : 
    1345           0 :                     SvMemoryStream  aMemStm;
    1346             : 
    1347           0 :                     aMemStm << aFill;
    1348             : 
    1349             :                     mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
    1350             :                                                             static_cast<const sal_uInt8*>(aMemStm.GetData()),
    1351           0 :                                                             aMemStm.Seek( STREAM_SEEK_TO_END ) ) );
    1352           0 :                     mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_END" ) );
    1353             :                 }
    1354             : 
    1355             :             }
    1356             :         }
    1357             :     }
    1358          57 : }
    1359             : 
    1360             : //-----------------------------------------------------------------------------------
    1361             : 
    1362           6 : void WinMtfOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool bRecordPath )
    1363             : {
    1364           6 :     UpdateClipRegion();
    1365             : 
    1366           6 :     ImplMap( rPolyPolygon );
    1367             : 
    1368           6 :     if ( bRecordPath )
    1369           0 :         aPathObj.AddPolyPolygon( rPolyPolygon );
    1370             :     else
    1371             :     {
    1372           6 :         UpdateFillStyle();
    1373             : 
    1374           6 :         if ( mbComplexClip )
    1375             :         {
    1376           0 :             PolyPolygon aDest;
    1377           0 :             PolyPolygon(aClipPath.getClipPath()).GetIntersection( rPolyPolygon, aDest );
    1378           0 :             ImplDrawClippedPolyPolygon( aDest );
    1379             :         }
    1380             :         else
    1381             :         {
    1382           6 :             UpdateLineStyle();
    1383           6 :             mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPolygon ) );
    1384             :         }
    1385             :     }
    1386           6 : }
    1387             : 
    1388             : //-----------------------------------------------------------------------------------
    1389             : 
    1390         143 : void WinMtfOutput::DrawPolyLine( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
    1391             : {
    1392         143 :     UpdateClipRegion();
    1393             : 
    1394         143 :     ImplMap( rPolygon );
    1395         143 :     if ( bTo )
    1396             :     {
    1397           5 :         rPolygon[ 0 ] = maActPos;
    1398           5 :         maActPos = rPolygon[ rPolygon.GetSize() - 1 ];
    1399             :     }
    1400         143 :     if ( bRecordPath )
    1401           5 :         aPathObj.AddPolyLine( rPolygon );
    1402             :     else
    1403             :     {
    1404         138 :         UpdateLineStyle();
    1405         138 :         mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
    1406             :     }
    1407         143 : }
    1408             : 
    1409             : //-----------------------------------------------------------------------------------
    1410             : 
    1411          16 : void WinMtfOutput::DrawPolyBezier( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
    1412             : {
    1413          16 :     UpdateClipRegion();
    1414             : 
    1415          16 :     sal_uInt16 nPoints = rPolygon.GetSize();
    1416          16 :     if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) )
    1417             :     {
    1418          16 :         ImplMap( rPolygon );
    1419          16 :         if ( bTo )
    1420             :         {
    1421          16 :             rPolygon[ 0 ] = maActPos;
    1422          16 :             maActPos = rPolygon[ nPoints - 1 ];
    1423             :         }
    1424             :         sal_uInt16 i;
    1425         188 :         for ( i = 0; ( i + 2 ) < nPoints; )
    1426             :         {
    1427         156 :             rPolygon.SetFlags( i++, POLY_NORMAL );
    1428         156 :             rPolygon.SetFlags( i++, POLY_CONTROL );
    1429         156 :             rPolygon.SetFlags( i++, POLY_CONTROL );
    1430             :         }
    1431          16 :         if ( bRecordPath )
    1432          16 :             aPathObj.AddPolyLine( rPolygon );
    1433             :         else
    1434             :         {
    1435           0 :             UpdateLineStyle();
    1436           0 :             mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
    1437             :         }
    1438             :     }
    1439          16 : }
    1440             : 
    1441             : //-----------------------------------------------------------------------------------
    1442             : 
    1443          65 : void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry, sal_Bool bRecordPath, sal_Int32 nGfxMode )
    1444             : {
    1445          65 :     UpdateClipRegion();
    1446             : 
    1447          65 :     VirtualDevice* pVDev = NULL;
    1448             : 
    1449          65 :     rPosition = ImplMap( rPosition );
    1450             : 
    1451          65 :     sal_Int32 nOldGfxMode = GetGfxMode();
    1452          65 :     SetGfxMode( GM_COMPATIBLE );
    1453          65 :     if ( pDXArry )
    1454             :     {
    1455          65 :         sal_Int32 i, nSum, nLen = rText.Len();
    1456             : 
    1457         329 :         for( i = 0, nSum = 0; i < nLen; i++ )
    1458             :         {
    1459         264 :             if ( i ) {
    1460         199 :                 pDXArry[ i - 1 ] = ImplMap( Size( nSum, 0 ) ).Width();
    1461             :             }
    1462         264 :             nSum += pDXArry[ i ];
    1463             :         }
    1464             :     }
    1465          65 :     if ( mnLatestTextLayoutMode != mnTextLayoutMode )
    1466             :     {
    1467           0 :         mnLatestTextLayoutMode = mnTextLayoutMode;
    1468           0 :         mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
    1469             :     }
    1470          65 :     SetGfxMode( nGfxMode );
    1471          65 :     sal_Bool bChangeFont = sal_False;
    1472          65 :     if ( mnLatestTextAlign != mnTextAlign )
    1473             :     {
    1474           4 :         bChangeFont = sal_True;
    1475           4 :         mnLatestTextAlign = mnTextAlign;
    1476             :         TextAlign eTextAlign;
    1477           4 :         if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
    1478           4 :             eTextAlign = ALIGN_BASELINE;
    1479           0 :         else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
    1480           0 :             eTextAlign = ALIGN_BOTTOM;
    1481             :         else
    1482           0 :             eTextAlign = ALIGN_TOP;
    1483           4 :         mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
    1484             :     }
    1485          65 :     if ( maLatestTextColor != maTextColor )
    1486             :     {
    1487           0 :         bChangeFont = sal_True;
    1488           0 :         maLatestTextColor = maTextColor;
    1489           0 :         mpGDIMetaFile->AddAction( new MetaTextColorAction( maTextColor ) );
    1490             :     }
    1491          65 :     sal_Bool bChangeFillColor = sal_False;
    1492          65 :     if ( maLatestBkColor != maBkColor )
    1493             :     {
    1494           8 :         bChangeFillColor = sal_True;
    1495           8 :         maLatestBkColor = maBkColor;
    1496             :     }
    1497          65 :     if ( mnLatestBkMode != mnBkMode )
    1498             :     {
    1499           8 :         bChangeFillColor = sal_True;
    1500           8 :         mnLatestBkMode = mnBkMode;
    1501             :     }
    1502          65 :     if ( bChangeFillColor )
    1503             :     {
    1504           8 :         bChangeFont = sal_True;
    1505           8 :         mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
    1506             :     }
    1507          65 :     Font aTmp( maFont );
    1508          65 :     aTmp.SetColor( maTextColor );
    1509          65 :     aTmp.SetFillColor( maBkColor );
    1510             : 
    1511          65 :     if( mnBkMode == TRANSPARENT )
    1512          65 :         aTmp.SetTransparent( sal_True );
    1513             :     else
    1514           0 :         aTmp.SetTransparent( sal_False );
    1515             : 
    1516          65 :     if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
    1517          59 :         aTmp.SetAlign( ALIGN_BASELINE );
    1518           6 :     else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
    1519           0 :         aTmp.SetAlign( ALIGN_BOTTOM );
    1520             :     else
    1521           6 :         aTmp.SetAlign( ALIGN_TOP );
    1522             : 
    1523          65 :     if ( nGfxMode == GM_ADVANCED )
    1524             :     {
    1525             :         // check whether there is a font rotation applied via transformation
    1526           0 :         Point aP1( ImplMap( Point() ) );
    1527           0 :         Point aP2( ImplMap( Point( 0, 100 ) ) );
    1528           0 :         aP2.X() -= aP1.X();
    1529           0 :         aP2.Y() -= aP1.Y();
    1530           0 :         double fX = aP2.X();
    1531           0 :         double fY = aP2.Y();
    1532           0 :         if ( fX )
    1533             :         {
    1534           0 :             double fOrientation = acos( fX / sqrt( fX * fX + fY * fY ) ) * 57.29577951308;
    1535           0 :             if ( fY > 0 )
    1536           0 :                 fOrientation = 360 - fOrientation;
    1537           0 :             fOrientation += 90;
    1538           0 :             fOrientation *= 10;
    1539           0 :             fOrientation += aTmp.GetOrientation();
    1540           0 :             aTmp.SetOrientation( sal_Int16( fOrientation ) );
    1541             :         }
    1542             :     }
    1543             : 
    1544          65 :     if( mnTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) )
    1545             :     {
    1546           0 :         if ( !pVDev )
    1547           0 :             pVDev = new VirtualDevice;
    1548             :         sal_Int32 nTextWidth;
    1549           0 :         pVDev->SetMapMode( MapMode( MAP_100TH_MM ) );
    1550           0 :         pVDev->SetFont( maFont );
    1551           0 :         if( pDXArry )
    1552             :         {
    1553           0 :             sal_uInt32 nLen = rText.Len();
    1554           0 :             nTextWidth = pVDev->GetTextWidth( rtl::OUString(rText.GetChar( (sal_uInt16)( nLen - 1 ) )) );
    1555           0 :             if( nLen > 1 )
    1556           0 :                 nTextWidth += pDXArry[ nLen - 2 ];
    1557             :         }
    1558             :         else
    1559           0 :             nTextWidth = pVDev->GetTextWidth( rText );
    1560             : 
    1561           0 :         if( mnTextAlign & TA_UPDATECP )
    1562           0 :             rPosition = maActPos;
    1563             : 
    1564           0 :         if ( mnTextAlign & TA_RIGHT_CENTER )
    1565             :         {
    1566           0 :             double fLenght = ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1;
    1567           0 :             rPosition.X() -= (sal_Int32)( fLenght * cos( maFont.GetOrientation() * F_PI1800 ) );
    1568           0 :             rPosition.Y() -= (sal_Int32)(-( fLenght * sin( maFont.GetOrientation() * F_PI1800 ) ) );
    1569             :         }
    1570             : 
    1571           0 :         if( mnTextAlign & TA_UPDATECP )
    1572           0 :             maActPos.X() = rPosition.X() + nTextWidth;
    1573             :     }
    1574          65 :     if ( bChangeFont || ( maLatestFont != aTmp ) )
    1575             :     {
    1576          14 :         maLatestFont = aTmp;
    1577          14 :         mpGDIMetaFile->AddAction( new MetaFontAction( aTmp ) );
    1578          14 :         mpGDIMetaFile->AddAction( new MetaTextAlignAction( aTmp.GetAlign() ) );
    1579          14 :         mpGDIMetaFile->AddAction( new MetaTextColorAction( aTmp.GetColor() ) );
    1580          14 :         mpGDIMetaFile->AddAction( new MetaTextFillColorAction( aTmp.GetFillColor(), !aTmp.IsTransparent() ) );
    1581             :     }
    1582          65 :     if ( bRecordPath )
    1583             :     {
    1584             :         // ToDo
    1585             :     }
    1586             :     else
    1587             :     {
    1588             :         /* because text without dx array is badly scaled, we
    1589             :            will create such an array if necessary */
    1590          65 :         sal_Int32* pDX = pDXArry;
    1591          65 :         if ( !pDXArry )
    1592             :         {
    1593           0 :             SolarMutexGuard aGuard;
    1594             : 
    1595           0 :             pDX = new sal_Int32[ rText.Len() ];
    1596           0 :             if ( !pVDev )
    1597           0 :                 pVDev = new VirtualDevice;
    1598           0 :             pVDev->SetMapMode( MAP_100TH_MM );
    1599           0 :             pVDev->SetFont( maLatestFont );
    1600           0 :             pVDev->GetTextArray( rText, pDX, 0, STRING_LEN );
    1601             :         }
    1602          65 :         mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDX, 0, STRING_LEN ) );
    1603          65 :         if ( !pDXArry )     // this means we have created our own array
    1604           0 :             delete[] pDX;   // which must be deleted
    1605             :     }
    1606          65 :     SetGfxMode( nOldGfxMode );
    1607          65 :     delete pVDev;
    1608          65 : }
    1609             : 
    1610             : //-----------------------------------------------------------------------------------
    1611             : 
    1612           1 : void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap )
    1613             : {
    1614           1 :     BitmapEx aBmpEx( rBitmap );
    1615           1 :     if ( mbComplexClip )
    1616             :     {
    1617           0 :         VirtualDevice aVDev;
    1618           0 :         MapMode aMapMode( MAP_100TH_MM );
    1619           0 :         aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) );
    1620           0 :         const Size aOutputSizePixel( aVDev.LogicToPixel( rSize, aMapMode ) );
    1621           0 :         const Size aSizePixel( rBitmap.GetSizePixel() );
    1622           0 :         if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() )
    1623             :         {
    1624           0 :             aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) );
    1625           0 :             aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) );
    1626             :         }
    1627           0 :         aVDev.SetMapMode( aMapMode );
    1628           0 :         aVDev.SetOutputSizePixel( aSizePixel );
    1629           0 :         aVDev.SetFillColor( Color( COL_BLACK ) );
    1630           0 :         const PolyPolygon aClip( aClipPath.getClipPath() );
    1631           0 :         aVDev.DrawPolyPolygon( aClip );
    1632           0 :         const Point aEmptyPoint;
    1633             : 
    1634             :         // #i50672# Extract whole VDev content (to match size of rBitmap)
    1635           0 :         aVDev.EnableMapMode( sal_False );
    1636           0 :         Bitmap aMask( aVDev.GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) );
    1637             : 
    1638           0 :         if ( aBmpEx.IsTransparent() )
    1639             :         {
    1640           0 :             if ( rBitmap.GetTransparentColor() == Color( COL_WHITE ) )
    1641           0 :                 aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_OR );
    1642             :             else
    1643           0 :                 aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_AND );
    1644           0 :             aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
    1645             :         }
    1646             :         else
    1647           0 :             aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
    1648             :     }
    1649           1 :     if ( aBmpEx.IsTransparent() )
    1650           0 :         mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( rPos, rSize, aBmpEx ) );
    1651             :     else
    1652           1 :         mpGDIMetaFile->AddAction( new MetaBmpScaleAction( rPos, rSize, aBmpEx.GetBitmap() ) );
    1653           1 : }
    1654             : 
    1655             : //-----------------------------------------------------------------------------------
    1656             : 
    1657          19 : void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
    1658             : {
    1659          19 :     UpdateClipRegion();
    1660             : 
    1661          19 :     size_t nObjects     = rSaveList.size();
    1662          19 :     size_t nObjectsLeft = nObjects;
    1663             : 
    1664          69 :     while ( nObjectsLeft )
    1665             :     {
    1666             :         size_t          i;
    1667          31 :         size_t          nObjectsOfSameSize = 0;
    1668          31 :         size_t          nObjectStartIndex = nObjects - nObjectsLeft;
    1669             : 
    1670          31 :         BSaveStruct*    pSave = rSaveList[ nObjectStartIndex ];
    1671          31 :         Rectangle       aRect( pSave->aOutRect );
    1672             : 
    1673          81 :         for ( i = nObjectStartIndex; i < nObjects; )
    1674             :         {
    1675          31 :             nObjectsOfSameSize++;
    1676          31 :             if ( ++i < nObjects )
    1677             :             {
    1678          12 :                 pSave = rSaveList[ i ];
    1679          12 :                 if ( pSave->aOutRect != aRect )
    1680          12 :                     break;
    1681             :             }
    1682             :         }
    1683          31 :         Point   aPos( ImplMap( aRect.TopLeft() ) );
    1684          31 :         Size    aSize( ImplMap( aRect.GetSize() ) );
    1685             : 
    1686          62 :         for ( i = nObjectStartIndex; i < ( nObjectStartIndex + nObjectsOfSameSize ); i++ )
    1687             :         {
    1688          31 :             pSave = rSaveList[ i ];
    1689             : 
    1690          31 :             sal_uInt32  nWinRop = pSave->nWinRop;
    1691          31 :             sal_uInt8   nRasterOperation = (sal_uInt8)( nWinRop >> 16 );
    1692             : 
    1693          31 :             sal_uInt32  nUsed =  0;
    1694          31 :             if ( ( nRasterOperation & 0xf )  != ( nRasterOperation >> 4 ) )
    1695          30 :                 nUsed |= 1;     // pattern is used
    1696          31 :             if ( ( nRasterOperation & 0x33 ) != ( ( nRasterOperation & 0xcc ) >> 2 ) )
    1697           1 :                 nUsed |= 2;     // source is used
    1698          31 :             if ( ( nRasterOperation & 0xaa ) != ( ( nRasterOperation & 0x55 ) << 1 ) )
    1699           0 :                 nUsed |= 4;     // destination is used
    1700             : 
    1701          31 :             if ( (nUsed & 1) && (( nUsed & 2 ) == 0) && nWinRop != PATINVERT )
    1702             :             {   // patterns aren't well supported yet
    1703          30 :                 sal_uInt32 nOldRop = SetRasterOp( ROP_OVERPAINT );  // in this case nRasterOperation is either 0 or 0xff
    1704          30 :                 UpdateFillStyle();
    1705          30 :                 DrawRect( aRect, sal_False );
    1706          30 :                 SetRasterOp( nOldRop );
    1707             :             }
    1708             :             else
    1709             :             {
    1710           1 :                 sal_Bool bDrawn = sal_False;
    1711             : 
    1712           1 :                 if ( i == nObjectStartIndex )   // optimizing, sometimes it is possible to create just one transparent bitmap
    1713             :                 {
    1714           1 :                     if ( nObjectsOfSameSize == 2 )
    1715             :                     {
    1716           0 :                         BSaveStruct* pSave2 = rSaveList[ i + 1 ];
    1717           0 :                         if ( ( pSave->aBmp.GetPrefSize() == pSave2->aBmp.GetPrefSize() ) &&
    1718           0 :                              ( pSave->aBmp.GetPrefMapMode() == pSave2->aBmp.GetPrefMapMode() ) )
    1719             :                         {
    1720             :                             // TODO: Strictly speaking, we should
    1721             :                             // check whether mask is monochrome, and
    1722             :                             // whether image is black (upper branch)
    1723             :                             // or white (lower branch). Otherwise, the
    1724             :                             // effect is not the same as a masked
    1725             :                             // bitmap.
    1726           0 :                             if ( ( nWinRop == SRCPAINT ) && ( pSave2->nWinRop == SRCAND ) )
    1727             :                             {
    1728           0 :                                 Bitmap aMask( pSave->aBmp ); aMask.Invert();
    1729           0 :                                 BitmapEx aBmpEx( pSave2->aBmp, aMask );
    1730           0 :                                 ImplDrawBitmap( aPos, aSize, aBmpEx );
    1731           0 :                                 bDrawn = sal_True;
    1732           0 :                                 i++;
    1733             :                             }
    1734             :                             // #i20085# This is just the other way
    1735             :                             // around as above. Only difference: mask
    1736             :                             // is inverted
    1737           0 :                             else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCPAINT ) )
    1738             :                             {
    1739           0 :                                 Bitmap aMask( pSave->aBmp );
    1740           0 :                                 BitmapEx aBmpEx( pSave2->aBmp, aMask );
    1741           0 :                                 ImplDrawBitmap( aPos, aSize, aBmpEx );
    1742           0 :                                 bDrawn = sal_True;
    1743           0 :                                 i++;
    1744             :                             }
    1745             :                         }
    1746             :                     }
    1747             :                 }
    1748             : 
    1749           1 :                 if ( !bDrawn )
    1750             :                 {
    1751           1 :                     Push();
    1752           1 :                     sal_uInt32  nOldRop = SetRasterOp( R2_COPYPEN );
    1753           1 :                     Bitmap      aBitmap( pSave->aBmp );
    1754           1 :                     sal_uInt32  nOperation = ( nRasterOperation & 0xf );
    1755           1 :                     switch( nOperation )
    1756             :                     {
    1757             :                         case 0x1 :
    1758             :                         case 0xe :
    1759             :                         {
    1760           0 :                             SetRasterOp( R2_XORPEN );
    1761           0 :                             ImplDrawBitmap( aPos, aSize, aBitmap );
    1762           0 :                             SetRasterOp( R2_COPYPEN );
    1763           0 :                             Bitmap  aMask( aBitmap );
    1764           0 :                             aMask.Invert();
    1765           0 :                             BitmapEx aBmpEx( aBitmap, aMask );
    1766           0 :                             ImplDrawBitmap( aPos, aSize, aBmpEx );
    1767           0 :                             if ( nOperation == 0x1 )
    1768             :                             {
    1769           0 :                                 SetRasterOp( R2_NOT );
    1770           0 :                                 DrawRect( aRect, sal_False );
    1771           0 :                             }
    1772             :                         }
    1773           0 :                         break;
    1774             :                         case 0x7 :
    1775             :                         case 0x8 :
    1776             :                         {
    1777           0 :                             Bitmap  aMask( aBitmap );
    1778           0 :                             if ( ( nUsed & 1 ) && ( nRasterOperation & 0xb0 ) == 0xb0 )     // pattern used
    1779             :                             {
    1780           0 :                                 aBitmap.Convert( BMP_CONVERSION_24BIT );
    1781           0 :                                 aBitmap.Erase( maFillStyle.aFillColor );
    1782             :                             }
    1783           0 :                             BitmapEx aBmpEx( aBitmap, aMask );
    1784           0 :                             ImplDrawBitmap( aPos, aSize, aBmpEx );
    1785           0 :                             if ( nOperation == 0x7 )
    1786             :                             {
    1787           0 :                                 SetRasterOp( R2_NOT );
    1788           0 :                                 DrawRect( aRect, sal_False );
    1789           0 :                             }
    1790             :                         }
    1791           0 :                         break;
    1792             : 
    1793             :                         case 0x4 :
    1794             :                         case 0xb :
    1795             :                         {
    1796           0 :                             SetRasterOp( R2_NOT );
    1797           0 :                             DrawRect( aRect, sal_False );
    1798           0 :                             SetRasterOp( R2_COPYPEN );
    1799           0 :                             Bitmap  aMask( aBitmap );
    1800           0 :                             aBitmap.Invert();
    1801           0 :                             BitmapEx aBmpEx( aBitmap, aMask );
    1802           0 :                             ImplDrawBitmap( aPos, aSize, aBmpEx );
    1803           0 :                             SetRasterOp( R2_XORPEN );
    1804           0 :                             ImplDrawBitmap( aPos, aSize, aBitmap );
    1805           0 :                             if ( nOperation == 0xb )
    1806             :                             {
    1807           0 :                                 SetRasterOp( R2_NOT );
    1808           0 :                                 DrawRect( aRect, sal_False );
    1809           0 :                             }
    1810             :                         }
    1811           0 :                         break;
    1812             : 
    1813             :                         case 0x2 :
    1814             :                         case 0xd :
    1815             :                         {
    1816           0 :                             Bitmap  aMask( aBitmap );
    1817           0 :                             aMask.Invert();
    1818           0 :                             BitmapEx aBmpEx( aBitmap, aMask );
    1819           0 :                             ImplDrawBitmap( aPos, aSize, aBmpEx );
    1820           0 :                             SetRasterOp( R2_XORPEN );
    1821           0 :                             ImplDrawBitmap( aPos, aSize, aBitmap );
    1822           0 :                             if ( nOperation == 0xd )
    1823             :                             {
    1824           0 :                                 SetRasterOp( R2_NOT );
    1825           0 :                                 DrawRect( aRect, sal_False );
    1826           0 :                             }
    1827             :                         }
    1828           0 :                         break;
    1829             :                         case 0x6 :
    1830             :                         case 0x9 :
    1831             :                         {
    1832           0 :                             SetRasterOp( R2_XORPEN );
    1833           0 :                             ImplDrawBitmap( aPos, aSize, aBitmap );
    1834           0 :                             if ( nOperation == 0x9 )
    1835             :                             {
    1836           0 :                                 SetRasterOp( R2_NOT );
    1837           0 :                                 DrawRect( aRect, sal_False );
    1838             :                             }
    1839             :                         }
    1840           0 :                         break;
    1841             : 
    1842             :                         case 0x0 :  // WHITENESS
    1843             :                         case 0xf :  // BLACKNESS
    1844             :                         {                                                   // in this case nRasterOperation is either 0 or 0xff
    1845           0 :                             maFillStyle = WinMtfFillStyle( Color( nRasterOperation, nRasterOperation, nRasterOperation ) );
    1846           0 :                             UpdateFillStyle();
    1847           0 :                             DrawRect( aRect, sal_False );
    1848             :                         }
    1849           0 :                         break;
    1850             : 
    1851             :                         case 0x3 :  // only source is used
    1852             :                         case 0xc :
    1853             :                         {
    1854           1 :                             if ( nRasterOperation == 0x33 )
    1855           0 :                                 aBitmap.Invert();
    1856           1 :                             ImplDrawBitmap( aPos, aSize, aBitmap );
    1857             :                         }
    1858           1 :                         break;
    1859             : 
    1860             :                         case 0x5 :  // only destination is used
    1861             :                         {
    1862           0 :                             SetRasterOp( R2_NOT );
    1863           0 :                             DrawRect( aRect, sal_False );
    1864             :                         }
    1865             :                         case 0xa :  // no operation
    1866           0 :                         break;
    1867             :                     }
    1868           1 :                     SetRasterOp( nOldRop );
    1869           1 :                     Pop();
    1870             :                 }
    1871             :             }
    1872             :         }
    1873          31 :         nObjectsLeft -= nObjectsOfSameSize;
    1874             :     }
    1875             : 
    1876          50 :     for( size_t i = 0, n = rSaveList.size(); i < n; ++i )
    1877          31 :         delete rSaveList[ i ];
    1878          19 :     rSaveList.clear();
    1879          19 : }
    1880             : 
    1881             : //-----------------------------------------------------------------------------------
    1882             : 
    1883          39 : void WinMtfOutput::SetDevOrg( const Point& rPoint )
    1884             : {
    1885          39 :     mnDevOrgX = rPoint.X();
    1886          39 :     mnDevOrgY = rPoint.Y();
    1887          39 : }
    1888             : 
    1889             : //-----------------------------------------------------------------------------------
    1890             : 
    1891           0 : void WinMtfOutput::SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
    1892             : {
    1893           0 :     mnDevOrgX += nXAdd;
    1894           0 :     mnDevOrgY += nYAdd;
    1895           0 : }
    1896             : 
    1897             : //-----------------------------------------------------------------------------------
    1898             : 
    1899          34 : void WinMtfOutput::SetDevExt( const Size& rSize )
    1900             : {
    1901          34 :     if ( rSize.Width() && rSize.Height() )
    1902             :     {
    1903          34 :         switch( mnMapMode )
    1904             :         {
    1905             :             case MM_ISOTROPIC :
    1906             :             case MM_ANISOTROPIC :
    1907             :             {
    1908          34 :                 mnDevWidth = rSize.Width();
    1909          34 :                 mnDevHeight = rSize.Height();
    1910             :             }
    1911             :         }
    1912             :     }
    1913          34 : }
    1914             : 
    1915             : //-----------------------------------------------------------------------------------
    1916             : 
    1917           3 : void WinMtfOutput::ScaleDevExt( double fX, double fY )
    1918             : {
    1919           3 :     mnDevWidth = FRound( mnDevWidth * fX );
    1920           3 :     mnDevHeight = FRound( mnDevHeight * fY );
    1921           3 : }
    1922             : 
    1923             : //-----------------------------------------------------------------------------------
    1924             : 
    1925          55 : void WinMtfOutput::SetWinOrg( const Point& rPoint )
    1926             : {
    1927          55 :     mnWinOrgX = rPoint.X();
    1928          55 :     mnWinOrgY = rPoint.Y();
    1929          55 : }
    1930             : 
    1931             : //-----------------------------------------------------------------------------------
    1932             : 
    1933           0 : void WinMtfOutput::SetWinOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
    1934             : {
    1935           0 :     mnWinOrgX += nXAdd;
    1936           0 :     mnWinOrgY += nYAdd;
    1937           0 : }
    1938             : 
    1939             : //-----------------------------------------------------------------------------------
    1940             : 
    1941          57 : void WinMtfOutput::SetWinExt( const Size& rSize )
    1942             : {
    1943             : 
    1944          57 :     if( rSize.Width() && rSize.Height() )
    1945             :     {
    1946          57 :         switch( mnMapMode )
    1947             :         {
    1948             :             case MM_ISOTROPIC :
    1949             :             case MM_ANISOTROPIC :
    1950             :             {
    1951          54 :                 mnWinExtX = rSize.Width();
    1952          54 :                 mnWinExtY = rSize.Height();
    1953             :             }
    1954             :         }
    1955             :     }
    1956          57 : }
    1957             : 
    1958             : //-----------------------------------------------------------------------------------
    1959             : 
    1960           0 : void WinMtfOutput::ScaleWinExt( double fX, double fY )
    1961             : {
    1962           0 :     mnWinExtX = FRound( mnWinExtX * fX );
    1963           0 :     mnWinExtY = FRound( mnWinExtY * fY );
    1964           0 : }
    1965             : 
    1966             : //-----------------------------------------------------------------------------------
    1967             : 
    1968          15 : void WinMtfOutput::SetrclBounds( const Rectangle& rRect )
    1969             : {
    1970          15 :     mrclBounds = rRect;
    1971          15 : }
    1972             : 
    1973             : //-----------------------------------------------------------------------------------
    1974             : 
    1975          15 : void WinMtfOutput::SetrclFrame( const Rectangle& rRect )
    1976             : {
    1977          15 :     mrclFrame = rRect;
    1978          15 : }
    1979             : 
    1980             : //-----------------------------------------------------------------------------------
    1981             : 
    1982          15 : void WinMtfOutput::SetRefPix( const Size& rSize )
    1983             : {
    1984          15 :     mnPixX = rSize.Width();
    1985          15 :     mnPixY = rSize.Height();
    1986          15 : }
    1987             : 
    1988             : //-----------------------------------------------------------------------------------
    1989             : 
    1990          15 : void WinMtfOutput::SetRefMill( const Size& rSize )
    1991             : {
    1992          15 :     mnMillX = rSize.Width();
    1993          15 :     mnMillY = rSize.Height();
    1994          15 : }
    1995             : 
    1996             : //-----------------------------------------------------------------------------------
    1997             : 
    1998          32 : void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
    1999             : {
    2000          32 :     mnMapMode = nMapMode;
    2001          32 :     if ( nMapMode == MM_TEXT )
    2002             :     {
    2003           2 :         mnWinExtX = mnDevWidth;
    2004           2 :         mnWinExtY = mnDevHeight;
    2005             :     }
    2006          30 :     else if ( mnMapMode == MM_HIMETRIC )
    2007             :     {
    2008           0 :         mnWinExtX = mnMillX * 100;
    2009           0 :         mnWinExtY = mnMillY * 100;
    2010             :     }
    2011          32 : }
    2012             : 
    2013             : //-----------------------------------------------------------------------------------
    2014             : 
    2015          13 : void WinMtfOutput::SetUnitsPerInch( sal_uInt16 nUnitsPerInch )
    2016             : {
    2017          13 :     if( nUnitsPerInch != 0 )
    2018          13 :     mnUnitsPerInch = nUnitsPerInch;
    2019          13 : }
    2020             : 
    2021             : //-----------------------------------------------------------------------------------
    2022             : 
    2023           1 : void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
    2024             : {
    2025           1 :     maXForm.eM11 = rXForm.eM11;
    2026           1 :     maXForm.eM12 = rXForm.eM12;
    2027           1 :     maXForm.eM21 = rXForm.eM21;
    2028           1 :     maXForm.eM22 = rXForm.eM22;
    2029           1 :     maXForm.eDx = rXForm.eDx;
    2030           1 :     maXForm.eDy = rXForm.eDy;
    2031           1 : }
    2032             : 
    2033             : //-----------------------------------------------------------------------------------
    2034             : 
    2035           1 : void WinMtfOutput::ModifyWorldTransform( const XForm& rXForm, sal_uInt32 nMode )
    2036             : {
    2037           1 :     switch( nMode )
    2038             :     {
    2039             :         case MWT_IDENTITY :
    2040             :         {
    2041           0 :             maXForm.eM11 = maXForm.eM12 = maXForm.eM21 = maXForm.eM22 = 1.0f;
    2042           0 :             maXForm.eDx = maXForm.eDy = 0.0f;
    2043             :         }
    2044           0 :         break;
    2045             : 
    2046             :         case MWT_RIGHTMULTIPLY :
    2047             :         case MWT_LEFTMULTIPLY :
    2048             :         {
    2049             :             const XForm* pLeft;
    2050             :             const XForm* pRight;
    2051             : 
    2052           1 :             if ( nMode == MWT_LEFTMULTIPLY )
    2053             :             {
    2054           1 :                 pLeft = &rXForm;
    2055           1 :                 pRight = &maXForm;
    2056             :             }
    2057             :             else
    2058             :             {
    2059           0 :                 pLeft = &maXForm;
    2060           0 :                 pRight = &rXForm;
    2061             :             }
    2062             : 
    2063             :             float aF[3][3];
    2064             :             float bF[3][3];
    2065             :             float cF[3][3];
    2066             : 
    2067           1 :             aF[0][0] = pLeft->eM11;
    2068           1 :             aF[0][1] = pLeft->eM12;
    2069           1 :             aF[0][2] = 0;
    2070           1 :             aF[1][0] = pLeft->eM21;
    2071           1 :             aF[1][1] = pLeft->eM22;
    2072           1 :             aF[1][2] = 0;
    2073           1 :             aF[2][0] = pLeft->eDx;
    2074           1 :             aF[2][1] = pLeft->eDy;
    2075           1 :             aF[2][2] = 1;
    2076             : 
    2077           1 :             bF[0][0] = pRight->eM11;
    2078           1 :             bF[0][1] = pRight->eM12;
    2079           1 :             bF[0][2] = 0;
    2080           1 :             bF[1][0] = pRight->eM21;
    2081           1 :             bF[1][1] = pRight->eM22;
    2082           1 :             bF[1][2] = 0;
    2083           1 :             bF[2][0] = pRight->eDx;
    2084           1 :             bF[2][1] = pRight->eDy;
    2085           1 :             bF[2][2] = 1;
    2086             : 
    2087             :             int i, j, k;
    2088           4 :             for ( i = 0; i < 3; i++ )
    2089             :             {
    2090          12 :               for ( j = 0; j < 3; j++ )
    2091             :               {
    2092           9 :                  cF[i][j] = 0;
    2093          36 :                  for ( k = 0; k < 3; k++ )
    2094          27 :                     cF[i][j] += aF[i][k] * bF[k][j];
    2095             :               }
    2096             :             }
    2097           1 :             maXForm.eM11 = cF[0][0];
    2098           1 :             maXForm.eM12 = cF[0][1];
    2099           1 :             maXForm.eM21 = cF[1][0];
    2100           1 :             maXForm.eM22 = cF[1][1];
    2101           1 :             maXForm.eDx = cF[2][0];
    2102           1 :             maXForm.eDy = cF[2][1];
    2103             :         }
    2104           1 :         break;
    2105             :     }
    2106           1 :  }
    2107             : 
    2108             : //-----------------------------------------------------------------------------------
    2109             : 
    2110          92 : void WinMtfOutput::Push()                       // !! to be able to access the original ClipRegion it
    2111             : {                                               // is not allowed to use the MetaPushAction()
    2112          92 :     UpdateClipRegion();                         // (the original clip region is on top of the stack) (SJ)
    2113          92 :     SaveStructPtr pSave( new SaveStruct );
    2114             : 
    2115          92 :     pSave->aLineStyle = maLineStyle;
    2116          92 :     pSave->aFillStyle = maFillStyle;
    2117             : 
    2118          92 :     pSave->aFont = maFont;
    2119          92 :     pSave->aTextColor = maTextColor;
    2120          92 :     pSave->nTextAlign = mnTextAlign;
    2121          92 :     pSave->nTextLayoutMode = mnTextLayoutMode;
    2122          92 :     pSave->nMapMode = mnMapMode;
    2123          92 :     pSave->nGfxMode = mnGfxMode;
    2124          92 :     pSave->nBkMode = mnBkMode;
    2125          92 :     pSave->aBkColor = maBkColor;
    2126          92 :     pSave->bFillStyleSelected = mbFillStyleSelected;
    2127             : 
    2128          92 :     pSave->aActPos = maActPos;
    2129          92 :     pSave->aXForm = maXForm;
    2130          92 :     pSave->eRasterOp = meRasterOp;
    2131             : 
    2132          92 :     pSave->nWinOrgX = mnWinOrgX;
    2133          92 :     pSave->nWinOrgY = mnWinOrgY;
    2134          92 :     pSave->nWinExtX = mnWinExtX;
    2135          92 :     pSave->nWinExtY = mnWinExtY;
    2136          92 :     pSave->nDevOrgX = mnDevOrgX;
    2137          92 :     pSave->nDevOrgY = mnDevOrgY;
    2138          92 :     pSave->nDevWidth = mnDevWidth;
    2139          92 :     pSave->nDevHeight = mnDevHeight;
    2140             : 
    2141          92 :     pSave->aPathObj = aPathObj;
    2142          92 :     pSave->aClipPath = aClipPath;
    2143             : 
    2144          92 :     vSaveStack.push_back( pSave );
    2145          92 : }
    2146             : 
    2147             : //-----------------------------------------------------------------------------------
    2148             : 
    2149          80 : void WinMtfOutput::Pop()
    2150             : {
    2151             :     // Die aktuellen Daten vom Stack holen
    2152          80 :     if( !vSaveStack.empty() )
    2153             :     {
    2154             :         // Die aktuelle Daten auf dem Stack sichern
    2155          80 :         SaveStructPtr pSave( vSaveStack.back() );
    2156             : 
    2157          80 :         maLineStyle = pSave->aLineStyle;
    2158          80 :         maFillStyle = pSave->aFillStyle;
    2159             : 
    2160          80 :         maFont = pSave->aFont;
    2161          80 :         maTextColor = pSave->aTextColor;
    2162          80 :         mnTextAlign = pSave->nTextAlign;
    2163          80 :         mnTextLayoutMode = pSave->nTextLayoutMode;
    2164          80 :         mnBkMode = pSave->nBkMode;
    2165          80 :         mnGfxMode = pSave->nGfxMode;
    2166          80 :         mnMapMode = pSave->nMapMode;
    2167          80 :         maBkColor = pSave->aBkColor;
    2168          80 :         mbFillStyleSelected = pSave->bFillStyleSelected;
    2169             : 
    2170          80 :         maActPos = pSave->aActPos;
    2171          80 :         maXForm = pSave->aXForm;
    2172          80 :         meRasterOp = pSave->eRasterOp;
    2173             : 
    2174          80 :         mnWinOrgX = pSave->nWinOrgX;
    2175          80 :         mnWinOrgY = pSave->nWinOrgY;
    2176          80 :         mnWinExtX = pSave->nWinExtX;
    2177          80 :         mnWinExtY = pSave->nWinExtY;
    2178          80 :         mnDevOrgX = pSave->nDevOrgX;
    2179          80 :         mnDevOrgY = pSave->nDevOrgY;
    2180          80 :         mnDevWidth = pSave->nDevWidth;
    2181          80 :         mnDevHeight = pSave->nDevHeight;
    2182             : 
    2183          80 :         aPathObj = pSave->aPathObj;
    2184          80 :         if ( ! ( aClipPath == pSave->aClipPath ) )
    2185             :         {
    2186           5 :             aClipPath = pSave->aClipPath;
    2187           5 :             mbClipNeedsUpdate = true;
    2188             :         }
    2189          80 :         if ( meLatestRasterOp != meRasterOp )
    2190          80 :             mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
    2191          80 :         vSaveStack.pop_back();
    2192             :     }
    2193          80 : }
    2194             : 
    2195           0 : void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
    2196             : {
    2197           0 :    rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
    2198           0 : }
    2199             : 
    2200           4 : void WinMtfOutput::PassEMFPlusHeaderInfo()
    2201             : {
    2202             :     EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS header info\n"));
    2203             : 
    2204           4 :     SvMemoryStream mem;
    2205             :     sal_Int32 nLeft, nRight, nTop, nBottom;
    2206             : 
    2207           4 :     nLeft = mrclFrame.Left();
    2208           4 :     nTop = mrclFrame.Top();
    2209           4 :     nRight = mrclFrame.Right();
    2210           4 :     nBottom = mrclFrame.Bottom();
    2211             : 
    2212             :     // emf header info
    2213           4 :     mem << nLeft << nTop << nRight << nBottom;
    2214           4 :     mem << mnPixX << mnPixY << mnMillX << mnMillY;
    2215             : 
    2216             :     float one, zero;
    2217             : 
    2218           4 :     one = 1;
    2219           4 :     zero = 0;
    2220             : 
    2221             :     // add transformation matrix to be used in vcl's metaact.cxx for
    2222             :     // rotate and scale operations
    2223           4 :     mem << one << zero << zero << one << zero << zero;
    2224             : 
    2225             :     // need to flush the stream, otherwise GetEndOfData will return 0
    2226             :     // on windows where the function parameters are probably resolved in reverse order
    2227           4 :     mem.Flush();
    2228             : 
    2229           4 :     mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const sal_uInt8*) mem.GetData(), mem.GetEndOfData() ) );
    2230           4 :     mpGDIMetaFile->UseCanvas( sal_True );
    2231           4 : }
    2232             : 
    2233          70 : void WinMtfOutput::PassEMFPlus( void* pBuffer, sal_uInt32 nLength )
    2234             : {
    2235             :     EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS comment length %04x\n",(unsigned int) nLength));
    2236          70 :     mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS", 0, static_cast<const sal_uInt8*>(pBuffer), nLength ) );
    2237          70 : }
    2238             : 
    2239             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10