LCOV - code coverage report
Current view: top level - vcl/source/filter/wmf - winmtf.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 824 1178 69.9 %
Date: 2014-04-11 Functions: 69 86 80.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10