LCOV - code coverage report
Current view: top level - vcl/source/filter/wmf - winmtf.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1178 0.0 %
Date: 2014-04-14 Functions: 0 86 0.0 %
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           0 : void WinMtfClipPath::intersectClipRect( const Rectangle& rRect )
      39             : {
      40             :     maClip.intersectRange(
      41           0 :         vcl::unotools::b2DRectangleFromRectangle(rRect));
      42           0 : }
      43             : 
      44           0 : void WinMtfClipPath::excludeClipRect( const Rectangle& rRect )
      45             : {
      46             :     maClip.subtractRange(
      47           0 :         vcl::unotools::b2DRectangleFromRectangle(rRect));
      48           0 : }
      49             : 
      50           0 : void WinMtfClipPath::setClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
      51             : {
      52           0 :     const basegfx::B2DPolyPolygon& rB2DPoly=rPolyPolygon.getB2DPolyPolygon();
      53           0 :     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           0 :             maClip.intersectPolyPolygon(rB2DPoly);
      66           0 :             break;
      67             :         case RGN_COPY :
      68           0 :             maClip = basegfx::tools::B2DClipState(rB2DPoly);
      69           0 :             break;
      70           0 :     }
      71           0 : }
      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           0 : basegfx::B2DPolyPolygon WinMtfClipPath::getClipPath() const
      86             : {
      87           0 :     return maClip.getClipPoly();
      88             : }
      89             : 
      90           0 : void WinMtfPathObj::AddPoint( const Point& rPoint )
      91             : {
      92           0 :     if ( bClosed )
      93           0 :         Insert( Polygon(), POLYPOLY_APPEND );
      94           0 :     Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
      95           0 :     rPoly.Insert( rPoly.GetSize(), rPoint, POLY_NORMAL );
      96           0 :     bClosed = false;
      97           0 : }
      98             : 
      99           0 : void WinMtfPathObj::AddPolyLine( const Polygon& rPolyLine )
     100             : {
     101           0 :     if ( bClosed )
     102           0 :         Insert( Polygon(), POLYPOLY_APPEND );
     103           0 :     Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
     104           0 :     rPoly.Insert( rPoly.GetSize(), rPolyLine );
     105           0 :     bClosed = false;
     106           0 : }
     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           0 : void WinMtfPathObj::ClosePath()
     123             : {
     124           0 :     if ( Count() )
     125             :     {
     126           0 :         Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
     127           0 :         if ( rPoly.GetSize() > 2 )
     128             :         {
     129           0 :             Point aFirst( rPoly[ 0 ] );
     130           0 :             if ( aFirst != rPoly[ rPoly.GetSize() - 1 ] )
     131           0 :                 rPoly.Insert( rPoly.GetSize(), aFirst, POLY_NORMAL );
     132             :         }
     133             :     }
     134           0 :     bClosed = true;
     135           0 : }
     136             : 
     137           0 : WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont )
     138             : {
     139             :     rtl_TextEncoding eCharSet;
     140           0 :     if ( ( rFont.lfCharSet == OEM_CHARSET ) || ( rFont.lfCharSet == DEFAULT_CHARSET ) )
     141           0 :         eCharSet = RTL_TEXTENCODING_MS_1252;
     142             :     else
     143           0 :         eCharSet = rtl_getTextEncodingFromWindowsCharset( rFont.lfCharSet );
     144           0 :     if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
     145           0 :         eCharSet = RTL_TEXTENCODING_MS_1252;
     146           0 :     aFont.SetCharSet( eCharSet );
     147           0 :     aFont.SetName( rFont.alfFaceName );
     148             :     FontFamily eFamily;
     149           0 :     switch ( rFont.lfPitchAndFamily & 0xf0 )
     150             :     {
     151             :         case FF_ROMAN:
     152           0 :             eFamily = FAMILY_ROMAN;
     153           0 :         break;
     154             : 
     155             :         case FF_SWISS:
     156           0 :             eFamily = FAMILY_SWISS;
     157           0 :         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           0 :             eFamily = FAMILY_DONTKNOW;
     173           0 :         break;
     174             :     }
     175           0 :     aFont.SetFamily( eFamily );
     176             : 
     177             :     FontPitch ePitch;
     178           0 :     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           0 :             ePitch = PITCH_VARIABLE;
     188           0 :         break;
     189             :     }
     190           0 :     aFont.SetPitch( ePitch );
     191             : 
     192             :     FontWeight eWeight;
     193           0 :     if( rFont.lfWeight <= FW_THIN )
     194           0 :         eWeight = WEIGHT_THIN;
     195           0 :     else if( rFont.lfWeight <= FW_ULTRALIGHT )
     196           0 :         eWeight = WEIGHT_ULTRALIGHT;
     197           0 :     else if( rFont.lfWeight <= FW_LIGHT )
     198           0 :         eWeight = WEIGHT_LIGHT;
     199           0 :     else if( rFont.lfWeight <  FW_MEDIUM )
     200           0 :         eWeight = WEIGHT_NORMAL;
     201           0 :     else if( rFont.lfWeight == FW_MEDIUM )
     202           0 :         eWeight = WEIGHT_MEDIUM;
     203           0 :     else if( rFont.lfWeight <= FW_SEMIBOLD )
     204           0 :         eWeight = WEIGHT_SEMIBOLD;
     205           0 :     else if( rFont.lfWeight <= FW_BOLD )
     206           0 :         eWeight = WEIGHT_BOLD;
     207           0 :     else if( rFont.lfWeight <= FW_ULTRABOLD )
     208           0 :         eWeight = WEIGHT_ULTRABOLD;
     209             :     else
     210           0 :         eWeight = WEIGHT_BLACK;
     211           0 :     aFont.SetWeight( eWeight );
     212             : 
     213           0 :     if( rFont.lfItalic )
     214           0 :         aFont.SetItalic( ITALIC_NORMAL );
     215             : 
     216           0 :     if( rFont.lfUnderline )
     217           0 :         aFont.SetUnderline( UNDERLINE_SINGLE );
     218             : 
     219           0 :     if( rFont.lfStrikeOut )
     220           0 :         aFont.SetStrikeout( STRIKEOUT_SINGLE );
     221             : 
     222           0 :     if ( rFont.lfOrientation )
     223           0 :         aFont.SetOrientation( (short)rFont.lfOrientation );
     224             :     else
     225           0 :         aFont.SetOrientation( (short)rFont.lfEscapement );
     226             : 
     227           0 :     Size  aFontSize( Size( rFont.lfWidth, rFont.lfHeight ) );
     228           0 :     if ( rFont.lfHeight > 0 )
     229             :     {
     230             :         // #i117968# VirtualDevice is not thread safe, but filter is used in multithreading
     231           0 :         SolarMutexGuard aGuard;
     232           0 :         VirtualDevice aVDev;
     233             : 
     234             :         // converting the cell height into a font height
     235           0 :         aFont.SetSize( aFontSize );
     236           0 :         aVDev.SetFont( aFont );
     237           0 :         FontMetric aMetric( aVDev.GetFontMetric() );
     238           0 :         long nHeight = aMetric.GetAscent() + aMetric.GetDescent();
     239           0 :         if ( nHeight )
     240             :         {
     241           0 :             double fHeight = ((double)aFontSize.Height() * rFont.lfHeight ) / nHeight;
     242           0 :             aFontSize.Height() = (sal_Int32)( fHeight + 0.5 );
     243           0 :         }
     244             :     }
     245           0 :     else if ( aFontSize.Height() < 0 )
     246           0 :         aFontSize.Height() *= -1;
     247             : 
     248           0 :     if ( !rFont.lfWidth )
     249             :     {
     250             :         // #i117968# VirtualDevice is not thread safe, but filter is used in multithreading
     251           0 :         SolarMutexGuard aGuard;
     252           0 :         VirtualDevice aVDev;
     253             : 
     254           0 :         aFont.SetSize( aFontSize );
     255           0 :         aVDev.SetFont( aFont );
     256           0 :         FontMetric aMetric( aVDev.GetFontMetric() );
     257           0 :         aFontSize.Width() = aMetric.GetWidth();
     258             :     }
     259             : 
     260           0 :     aFont.SetSize( aFontSize );
     261           0 : };
     262             : 
     263           0 : WinMtf::WinMtf( WinMtfOutput* pWinMtfOutput, SvStream& rStreamWMF, FilterConfigItem* pConfigItem )
     264             :     : pOut( pWinMtfOutput )
     265             :     , pWMF( &rStreamWMF )
     266             :     , nEndPos( 0 )
     267           0 :     , pFilterConfigItem( pConfigItem )
     268             : {
     269           0 :     SvLockBytes *pLB = pWMF->GetLockBytes();
     270           0 :     if ( pLB )
     271           0 :         pLB->SetSynchronMode( true );
     272             : 
     273           0 :     nStartPos = pWMF->Tell();
     274             : 
     275           0 :     pOut->SetDevOrg( Point() );
     276           0 :     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           0 : }
     286             : 
     287           0 : WinMtf::~WinMtf()
     288             : {
     289           0 :     delete pOut;
     290             : 
     291           0 :     if ( xStatusIndicator.is() )
     292           0 :         xStatusIndicator->end();
     293           0 : }
     294             : 
     295           0 : void WinMtf::Callback( sal_uInt16 nPercent )
     296             : {
     297           0 :     if ( xStatusIndicator.is() )
     298           0 :         xStatusIndicator->setValue( nPercent );
     299           0 : }
     300             : 
     301           0 : Color WinMtf::ReadColor()
     302             : {
     303             :     sal_uInt32 nColor;
     304           0 :     pWMF->ReadUInt32( nColor );
     305           0 :     return Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
     306             : };
     307             : 
     308           0 : Point WinMtfOutput::ImplScale( const Point& rPt) // Hack to set varying defaults for incompletely defined files.
     309             : {
     310           0 :         if (mbIsMapDevSet && mbIsMapWinSet)
     311             :         {
     312           0 :             return rPt; //fdo#73764
     313             :         }
     314             :         else
     315             :         {
     316           0 :             return Point((rPt.X())*UNDOCUMENTED_WIN_RCL_RELATION-mrclFrame.Left(),(rPt.Y())*UNDOCUMENTED_WIN_RCL_RELATION-mrclFrame.Top());
     317             :         }
     318             : }
     319             : 
     320           0 : Point WinMtfOutput::ImplMap( const Point& rPt )
     321             : {
     322           0 :     if ( mnWinExtX && mnWinExtY )
     323             :     {
     324           0 :         double fX = rPt.X();
     325           0 :         double fY = rPt.Y();
     326             : 
     327           0 :         double fX2 = fX * maXForm.eM11 + fY * maXForm.eM21 + maXForm.eDx;
     328           0 :         double fY2 = fX * maXForm.eM12 + fY * maXForm.eM22 + maXForm.eDy;
     329             : 
     330           0 :         if ( mnGfxMode == GM_COMPATIBLE )
     331             :         {
     332           0 :             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           0 :                     fX2 -= mnWinOrgX;
     385           0 :                     fY2 -= mnWinOrgY;
     386           0 :                     fX2 /= mnWinExtX;
     387           0 :                     fY2 /= mnWinExtY;
     388           0 :                     fX2 *= mnDevWidth;
     389           0 :                     fY2 *= mnDevHeight;
     390           0 :                     fX2 += mnDevOrgX;
     391           0 :                     fY2 += mnDevOrgY;   // fX2, fY2 now in device units
     392           0 :                     fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
     393           0 :                     fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
     394             :                 }
     395           0 :                 break;
     396             :             }
     397           0 :             fX2 -= mrclFrame.Left();
     398           0 :             fY2 -= mrclFrame.Top();
     399             :         }
     400           0 :         return Point( FRound( fX2 ), FRound( fY2 ) );
     401             :     }
     402             :     else
     403           0 :         return Point();
     404             : };
     405             : 
     406           0 : Size WinMtfOutput::ImplMap( const Size& rSz )
     407             : {
     408           0 :     if ( mnWinExtX && mnWinExtY )
     409             :     {
     410             :         // #i121382# apply the whole WorldTransform, else a rotation will be misinterpreted
     411           0 :         double fWidth = rSz.Width() * maXForm.eM11 + rSz.Height() * maXForm.eM21;
     412           0 :         double fHeight = rSz.Width() * maXForm.eM12 + rSz.Height() * maXForm.eM22;
     413             : 
     414           0 :         if ( mnGfxMode == GM_COMPATIBLE )
     415             :         {
     416           0 :             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           0 :                     fWidth /= mnWinExtX;
     450           0 :                     fHeight /= mnWinExtY;
     451           0 :                     fWidth *= mnDevWidth;
     452           0 :                     fHeight *= mnDevHeight;
     453           0 :                     fWidth *= (double)mnMillX * 100 / (double)mnPixX;
     454           0 :                     fHeight *= (double)mnMillY * 100 / (double)mnPixY;
     455             :                 }
     456           0 :                 break;
     457             :             }
     458             :         }
     459           0 :         return Size( FRound( fWidth ), FRound( fHeight ) );
     460             :     }
     461             :     else
     462           0 :         return Size();
     463             : }
     464             : 
     465           0 : Rectangle WinMtfOutput::ImplMap( const Rectangle& rRect )
     466             : {
     467           0 :     return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) );
     468             : }
     469             : 
     470           0 : 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           0 :     Size  aFontSize = ImplMap ( rFont.GetSize() );
     475             : 
     476           0 :     if( aFontSize.Height() < 0 )
     477           0 :         aFontSize.Height() *= -1;
     478             : 
     479           0 :     rFont.SetSize( aFontSize );
     480             : 
     481           0 :     if( ( mnWinExtX * mnWinExtY ) < 0 )
     482           0 :         rFont.SetOrientation( 3600 - rFont.GetOrientation() );
     483           0 : }
     484             : 
     485           0 : Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
     486             : {
     487           0 :     sal_uInt16 nPoints = rPolygon.GetSize();
     488           0 :     for ( sal_uInt16 i = 0; i < nPoints; i++ )
     489             :     {
     490           0 :         rPolygon[ i ] = ImplMap( rPolygon[ i ] );
     491             :     }
     492           0 :     return rPolygon;
     493             : }
     494             : 
     495           0 : Polygon& WinMtfOutput::ImplScale( Polygon& rPolygon )
     496             : {
     497           0 :     sal_uInt16 nPoints = rPolygon.GetSize();
     498           0 :     for ( sal_uInt16 i = 0; i < nPoints; i++ )
     499             :     {
     500           0 :         rPolygon[ i ] = ImplScale( rPolygon[ i ] );
     501             :     }
     502           0 :     return rPolygon;
     503             : }
     504             : 
     505           0 : PolyPolygon& WinMtfOutput::ImplScale( PolyPolygon& rPolyPolygon )
     506             : {
     507           0 :     sal_uInt16 nPolys = rPolyPolygon.Count();
     508           0 :     for (sal_uInt16 i = 0; i < nPolys; ++i)
     509             :     {
     510           0 :         ImplScale(rPolyPolygon[i]);
     511             :     }
     512           0 :     return rPolyPolygon;
     513             : }
     514             : 
     515           0 : PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
     516             : {
     517           0 :     sal_uInt16 nPolys = rPolyPolygon.Count();
     518           0 :     for ( sal_uInt16 i = 0; i < nPolys; ImplMap( rPolyPolygon[ i++ ] ) ) ;
     519           0 :     return rPolyPolygon;
     520             : }
     521             : 
     522           0 : void WinMtfOutput::SelectObject( sal_Int32 nIndex )
     523             : {
     524           0 :     GDIObj* pGDIObj = NULL;
     525             : 
     526           0 :     if ( nIndex & ENHMETA_STOCK_OBJECT )
     527           0 :         pGDIObj = new GDIObj();
     528             :     else
     529             :     {
     530           0 :         nIndex &= 0xffff;       // safety check: don't allow index to be > 65535
     531             : 
     532           0 :         if ( (sal_uInt32)nIndex < vGDIObj.size() )
     533           0 :             pGDIObj = vGDIObj[ nIndex ];
     534             :     }
     535             : 
     536           0 :     if( pGDIObj == NULL )
     537           0 :         return;
     538             : 
     539           0 :     if ( nIndex & ENHMETA_STOCK_OBJECT )
     540             :     {
     541           0 :         sal_uInt16 nStockId = (sal_uInt8)nIndex;
     542           0 :         switch( nStockId )
     543             :         {
     544             :             case WHITE_BRUSH :
     545             :             {
     546           0 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ) ) );
     547             :             }
     548           0 :             break;
     549             :             case LTGRAY_BRUSH :
     550             :             {
     551           0 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_LIGHTGRAY ) ) );
     552             :             }
     553           0 :             break;
     554             :             case GRAY_BRUSH :
     555             :             case DKGRAY_BRUSH :
     556             :             {
     557           0 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_GRAY ) ) );
     558             :             }
     559           0 :             break;
     560             :             case BLACK_BRUSH :
     561             :             {
     562           0 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_BLACK ) ) );
     563             :             }
     564           0 :             break;
     565             :             case NULL_BRUSH :
     566             :             {
     567           0 :                 pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_TRANSPARENT ), true ) );
     568             :             }
     569           0 :             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           0 :                 pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_BLACK ) ) );
     578             :             }
     579           0 :             break;
     580             :             case NULL_PEN :
     581             :             {
     582           0 :                 pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_TRANSPARENT ), true ) );
     583             :             }
     584           0 :             break;
     585             :             default:
     586           0 :             break;
     587             :         }
     588             :     }
     589           0 :     if ( pGDIObj->pStyle )
     590             :     {
     591           0 :         switch( pGDIObj->eType )
     592             :         {
     593             :             case GDI_PEN :
     594           0 :                 maLineStyle = (WinMtfLineStyle*)pGDIObj->pStyle;
     595           0 :             break;
     596             :             case GDI_BRUSH :
     597             :             {
     598           0 :                 maFillStyle = (WinMtfFillStyle*)pGDIObj->pStyle;
     599           0 :                 mbFillStyleSelected = true;
     600             :             }
     601           0 :             break;
     602             :             case GDI_FONT :
     603           0 :                 maFont = ((WinMtfFontStyle*)pGDIObj->pStyle)->aFont;
     604           0 :             break;
     605             :             default:
     606           0 :             break;  //  -Wall many options not handled.
     607             :         }
     608             :     }
     609           0 :     if ( nIndex & ENHMETA_STOCK_OBJECT )
     610           0 :         delete pGDIObj;
     611             : }
     612             : 
     613           0 : const Font& WinMtfOutput::GetFont() const
     614             : {
     615           0 :     return maFont;
     616             : }
     617             : 
     618           0 : void WinMtfOutput::SetTextLayoutMode( const sal_uInt32 nTextLayoutMode )
     619             : {
     620           0 :     mnTextLayoutMode = nTextLayoutMode;
     621           0 : }
     622             : 
     623           0 : void WinMtfOutput::SetBkMode( sal_uInt32 nMode )
     624             : {
     625           0 :     mnBkMode = nMode;
     626           0 : }
     627             : 
     628           0 : void WinMtfOutput::SetBkColor( const Color& rColor )
     629             : {
     630           0 :     maBkColor = rColor;
     631           0 : }
     632             : 
     633           0 : void WinMtfOutput::SetTextColor( const Color& rColor )
     634             : {
     635           0 :     maTextColor = rColor;
     636           0 : }
     637             : 
     638           0 : void WinMtfOutput::SetTextAlign( sal_uInt32 nAlign )
     639             : {
     640           0 :     mnTextAlign = nAlign;
     641           0 : }
     642             : 
     643           0 : void WinMtfOutput::ImplResizeObjectArry( sal_uInt32 nNewEntrys )
     644             : {
     645           0 :     sal_uInt32 i = vGDIObj.size();
     646           0 :     vGDIObj.resize( nNewEntrys );
     647           0 :     for ( ; i < nNewEntrys ; i++ )
     648           0 :         vGDIObj[ i ] = NULL;
     649           0 : }
     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           0 : void WinMtfOutput::CreateObject( GDIObjectType eType, void* pStyle )
     681             : {
     682           0 :     if ( pStyle )
     683             :     {
     684           0 :         if ( eType == GDI_FONT )
     685             :         {
     686           0 :             ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
     687           0 :             if (!((WinMtfFontStyle*)pStyle)->aFont.GetHeight() )
     688           0 :                 ((WinMtfFontStyle*)pStyle)->aFont.SetHeight( 423 );     // defaulting to 12pt
     689             :         }
     690           0 :         else if ( eType == GDI_PEN )
     691             :         {
     692           0 :             Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
     693           0 :             ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
     694             :         }
     695             :     }
     696             :     sal_uInt32 nIndex;
     697           0 :     for ( nIndex = 0; nIndex < vGDIObj.size(); nIndex++ )
     698             :     {
     699           0 :         if ( vGDIObj[ nIndex ] == NULL )
     700           0 :             break;
     701             :     }
     702           0 :     if ( nIndex == vGDIObj.size() )
     703           0 :         ImplResizeObjectArry( vGDIObj.size() + 16 );
     704             : 
     705           0 :     vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
     706           0 : }
     707             : 
     708           0 : void WinMtfOutput::CreateObject( sal_Int32 nIndex, GDIObjectType eType, void* pStyle )
     709             : {
     710           0 :     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     711             :     {
     712           0 :         nIndex &= 0xffff;       // safety check: do not allow index to be > 65535
     713           0 :         if ( pStyle )
     714             :         {
     715           0 :             if ( eType == GDI_FONT )
     716           0 :                 ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
     717           0 :             else if ( eType == GDI_PEN )
     718             :             {
     719           0 :                 Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
     720           0 :                 ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
     721             :             }
     722             :         }
     723           0 :         if ( (sal_uInt32)nIndex >= vGDIObj.size() )
     724           0 :             ImplResizeObjectArry( nIndex + 16 );
     725             : 
     726           0 :         if ( vGDIObj[ nIndex ] != NULL )
     727           0 :             delete vGDIObj[ nIndex ];
     728             : 
     729           0 :         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           0 : }
     751             : 
     752           0 : void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
     753             : {
     754           0 :     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     755             :     {
     756           0 :         if ( (sal_uInt32)nIndex < vGDIObj.size() )
     757             :         {
     758           0 :             delete vGDIObj[ nIndex ];
     759           0 :             vGDIObj[ nIndex ] = NULL;
     760             :         }
     761             :     }
     762           0 : }
     763             : 
     764           0 : void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
     765             : {
     766           0 :     mbClipNeedsUpdate=true;
     767           0 :     if ((rRect.Left()-rRect.Right()==0) && (rRect.Top()-rRect.Bottom()==0))
     768             :     {
     769           0 :         return; // empty rectangles cause trouble
     770             :     }
     771           0 :     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           0 : void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, bool bIsMapped )
     787             : {
     788           0 :     mbClipNeedsUpdate=true;
     789           0 :     if ( bIsMapped )
     790             :     {
     791           0 :         PolyPolygon aPP( rPolyPolygon );
     792           0 :         aClipPath.setClipPath( ImplScale( aPP ), nClippingMode );
     793             :     }
     794             :     else
     795             :     {
     796           0 :         PolyPolygon aPP( rPolyPolygon );
     797           0 :         aClipPath.setClipPath( ImplMap( aPP ), nClippingMode );
     798             :     }
     799           0 : }
     800             : 
     801           0 : 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           0 :     mpGDIMetaFile       ( &rGDIMetaFile )
     832             : {
     833           0 :     mbIsMapWinSet = false;
     834           0 :     mbIsMapDevSet = false;
     835           0 :     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           0 :     maFont.SetName( "Arial" );                                              // sj: #i57205#, we do have some scaling problems if using
     841           0 :     maFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );                          // the default font then most times a x11 font is used, we
     842           0 :     maFont.SetHeight( 423 );                                                // will prevent this defining a font
     843             : 
     844           0 :     maLatestLineStyle.aLineColor = Color( 0x12, 0x34, 0x56 );
     845           0 :     maLatestFillStyle.aFillColor = Color( 0x12, 0x34, 0x56 );
     846             : 
     847           0 :     mnRop = R2_BLACK + 1;
     848           0 :     SetRasterOp( R2_BLACK );
     849           0 : };
     850             : 
     851           0 : WinMtfOutput::~WinMtfOutput()
     852             : {
     853           0 :     mpGDIMetaFile->AddAction( new MetaPopAction() );
     854           0 :     mpGDIMetaFile->SetPrefMapMode( MAP_100TH_MM );
     855           0 :     if ( mrclFrame.IsEmpty() )
     856           0 :         mpGDIMetaFile->SetPrefSize( Size( mnDevWidth, mnDevHeight ) );
     857             :     else
     858           0 :         mpGDIMetaFile->SetPrefSize( mrclFrame.GetSize() );
     859             : 
     860           0 :     for ( sal_uInt32 i = 0; i < vGDIObj.size(); i++ )
     861           0 :         delete vGDIObj[ i ];
     862           0 : };
     863             : 
     864           0 : void WinMtfOutput::UpdateClipRegion()
     865             : {
     866           0 :     if ( mbClipNeedsUpdate )
     867             :     {
     868           0 :         mbClipNeedsUpdate = false;
     869           0 :         mbComplexClip = false;
     870             : 
     871           0 :         mpGDIMetaFile->AddAction( new MetaPopAction() );                    // taking the original clipregion
     872           0 :         mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) );
     873             : 
     874             :         // skip for 'no clipping at all' case
     875           0 :         if( !aClipPath.isEmpty() )
     876             :         {
     877           0 :             const basegfx::B2DPolyPolygon& rClipPoly( aClipPath.getClipPath() );
     878             :             mpGDIMetaFile->AddAction(
     879             :                 new MetaISectRectClipRegionAction(
     880             :                     vcl::unotools::rectangleFromB2DRectangle(
     881           0 :                         rClipPoly.getB2DRange())));
     882             : 
     883           0 :             mbComplexClip = rClipPoly.count() > 1
     884           0 :                 || !basegfx::tools::isRectangle(rClipPoly);
     885             :         }
     886             :     }
     887           0 : }
     888             : 
     889           0 : void WinMtfOutput::ImplSetNonPersistentLineColorTransparenz()
     890             : {
     891           0 :     Color aColor(  COL_TRANSPARENT);
     892           0 :     WinMtfLineStyle aTransparentLine( aColor, true );
     893           0 :     if ( ! ( maLatestLineStyle == aTransparentLine ) )
     894             :     {
     895           0 :         maLatestLineStyle = aTransparentLine;
     896           0 :         mpGDIMetaFile->AddAction( new MetaLineColorAction( aTransparentLine.aLineColor, !aTransparentLine.bTransparent ) );
     897           0 :     }
     898           0 : }
     899             : 
     900           0 : void WinMtfOutput::UpdateLineStyle()
     901             : {
     902           0 :     if (!( maLatestLineStyle == maLineStyle ) )
     903             :     {
     904           0 :         maLatestLineStyle = maLineStyle;
     905           0 :         mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
     906             :     }
     907           0 : }
     908             : 
     909           0 : void WinMtfOutput::UpdateFillStyle()
     910             : {
     911           0 :     if ( !mbFillStyleSelected )     // SJ: #i57205# taking care of bkcolor if no brush is selected
     912           0 :         maFillStyle = WinMtfFillStyle( maBkColor, mnBkMode == TRANSPARENT );
     913           0 :     if (!( maLatestFillStyle == maFillStyle ) )
     914             :     {
     915           0 :         maLatestFillStyle = maFillStyle;
     916           0 :         if (maFillStyle.aType == FillStyleSolid)
     917           0 :             mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
     918             :     }
     919           0 : }
     920             : 
     921           0 : sal_uInt32 WinMtfOutput::SetRasterOp( sal_uInt32 nRasterOp )
     922             : {
     923           0 :     sal_uInt32 nRetROP = mnRop;
     924           0 :     if ( nRasterOp != mnRop )
     925             :     {
     926           0 :         mnRop = nRasterOp;
     927           0 :         static WinMtfFillStyle aNopFillStyle;
     928           0 :         static WinMtfLineStyle aNopLineStyle;
     929             : 
     930           0 :         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           0 :         switch( nRasterOp )
     937             :         {
     938             :             case R2_NOT:
     939           0 :                 meRasterOp = ROP_INVERT;
     940           0 :             break;
     941             : 
     942             :             case R2_XORPEN:
     943           0 :                 meRasterOp = ROP_XOR;
     944           0 :             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           0 :                 meRasterOp = ROP_OVERPAINT;
     962           0 :             break;
     963             :         }
     964             :     }
     965           0 :     if ( nRetROP != nRasterOp )
     966           0 :         mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
     967           0 :     return nRetROP;
     968             : };
     969             : 
     970           0 : void WinMtfOutput::StrokeAndFillPath( bool bStroke, bool bFill )
     971             : {
     972           0 :     if ( aPathObj.Count() )
     973             :     {
     974           0 :         UpdateClipRegion();
     975           0 :         UpdateLineStyle();
     976           0 :         UpdateFillStyle();
     977           0 :         if ( bFill )
     978             :         {
     979           0 :             if ( !bStroke )
     980             :             {
     981           0 :                 mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
     982           0 :                 mpGDIMetaFile->AddAction( new MetaLineColorAction( Color(), false ) );
     983             :             }
     984           0 :             if ( aPathObj.Count() == 1 )
     985           0 :                 mpGDIMetaFile->AddAction( new MetaPolygonAction( aPathObj.GetObject( 0 ) ) );
     986             :             else
     987           0 :                 mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( aPathObj ) );
     988             : 
     989           0 :             if ( !bStroke )
     990           0 :                 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           0 :         ClearPath();
     999             :     }
    1000           0 : }
    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           0 : void WinMtfOutput::MoveTo( const Point& rPoint, bool bRecordPath )
    1008             : {
    1009           0 :     Point aDest( ImplMap( rPoint ) );
    1010           0 :     if ( bRecordPath )
    1011             :     {
    1012             :         // fdo#57353 create new subpath for subsequent moves
    1013           0 :         if ( aPathObj.Count() )
    1014           0 :             if ( aPathObj[ aPathObj.Count() - 1 ].GetSize() )
    1015           0 :                 aPathObj.Insert( Polygon(), POLYPOLY_APPEND );
    1016           0 :         aPathObj.AddPoint( aDest );
    1017             :     }
    1018           0 :     maActPos = aDest;
    1019           0 : }
    1020             : 
    1021           0 : void WinMtfOutput::LineTo( const Point& rPoint, bool bRecordPath )
    1022             : {
    1023           0 :     UpdateClipRegion();
    1024           0 :     Point aDest( ImplMap( rPoint ) );
    1025           0 :     if ( bRecordPath )
    1026           0 :         aPathObj.AddPoint( aDest );
    1027             :     else
    1028             :     {
    1029           0 :         UpdateLineStyle();
    1030           0 :         mpGDIMetaFile->AddAction( new MetaLineAction( maActPos, aDest, maLineStyle.aLineInfo ) );
    1031             :     }
    1032           0 :     maActPos = aDest;
    1033           0 : }
    1034             : 
    1035           0 : void WinMtfOutput::DrawRect( const Rectangle& rRect, bool bEdge )
    1036             : {
    1037           0 :     UpdateClipRegion();
    1038           0 :     UpdateFillStyle();
    1039             : 
    1040           0 :     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           0 :         if ( bEdge )
    1051             :         {
    1052           0 :             if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1053             :             {
    1054           0 :                 ImplSetNonPersistentLineColorTransparenz();
    1055           0 :                 mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
    1056           0 :                 UpdateLineStyle();
    1057           0 :                 mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect ) ),maLineStyle.aLineInfo ) );
    1058             :             }
    1059             :             else
    1060             :             {
    1061           0 :                 UpdateLineStyle();
    1062           0 :                 mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
    1063             :             }
    1064             :         }
    1065             :         else
    1066             :         {
    1067           0 :             ImplSetNonPersistentLineColorTransparenz();
    1068           0 :             mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
    1069             :         }
    1070             :     }
    1071           0 : }
    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           0 : void WinMtfOutput::DrawPolygon( Polygon& rPolygon, bool bRecordPath )
    1179             : {
    1180           0 :     UpdateClipRegion();
    1181           0 :     ImplMap( rPolygon );
    1182           0 :     if ( bRecordPath )
    1183           0 :         aPathObj.AddPolygon( rPolygon );
    1184             :     else
    1185             :     {
    1186           0 :         UpdateFillStyle();
    1187             : 
    1188           0 :         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           0 :             if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
    1198             :             {
    1199           0 :                 sal_uInt16 nCount = rPolygon.GetSize();
    1200           0 :                 if ( nCount )
    1201             :                 {
    1202           0 :                     if ( rPolygon[ nCount - 1 ] != rPolygon[ 0 ] )
    1203             :                     {
    1204           0 :                         Point aPoint( rPolygon[ 0 ] );
    1205           0 :                         rPolygon.Insert( nCount, aPoint );
    1206             :                     }
    1207             :                 }
    1208           0 :                 ImplSetNonPersistentLineColorTransparenz();
    1209           0 :                 mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
    1210           0 :                 UpdateLineStyle();
    1211           0 :                 mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
    1212             :             }
    1213             :             else
    1214             :             {
    1215           0 :                 UpdateLineStyle();
    1216             : 
    1217           0 :                 if (maLatestFillStyle.aType != FillStylePattern)
    1218           0 :                     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           0 : }
    1249             : 
    1250           0 : void WinMtfOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon, bool bRecordPath )
    1251             : {
    1252           0 :     UpdateClipRegion();
    1253             : 
    1254           0 :     ImplMap( rPolyPolygon );
    1255             : 
    1256           0 :     if ( bRecordPath )
    1257           0 :         aPathObj.AddPolyPolygon( rPolyPolygon );
    1258             :     else
    1259             :     {
    1260           0 :         UpdateFillStyle();
    1261             : 
    1262           0 :         if ( mbComplexClip )
    1263             :         {
    1264           0 :             PolyPolygon aDest;
    1265           0 :             PolyPolygon(aClipPath.getClipPath()).GetIntersection( rPolyPolygon, aDest );
    1266           0 :             ImplDrawClippedPolyPolygon( aDest );
    1267             :         }
    1268             :         else
    1269             :         {
    1270           0 :             UpdateLineStyle();
    1271           0 :             mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPolygon ) );
    1272             :         }
    1273             :     }
    1274           0 : }
    1275             : 
    1276           0 : void WinMtfOutput::DrawPolyLine( Polygon& rPolygon, bool bTo, bool bRecordPath )
    1277             : {
    1278           0 :     UpdateClipRegion();
    1279             : 
    1280           0 :     ImplMap( rPolygon );
    1281           0 :     if ( bTo )
    1282             :     {
    1283           0 :         rPolygon[ 0 ] = maActPos;
    1284           0 :         maActPos = rPolygon[ rPolygon.GetSize() - 1 ];
    1285             :     }
    1286           0 :     if ( bRecordPath )
    1287           0 :         aPathObj.AddPolyLine( rPolygon );
    1288             :     else
    1289             :     {
    1290           0 :         UpdateLineStyle();
    1291           0 :         mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
    1292             :     }
    1293           0 : }
    1294             : 
    1295           0 : void WinMtfOutput::DrawPolyBezier( Polygon& rPolygon, bool bTo, bool bRecordPath )
    1296             : {
    1297           0 :     UpdateClipRegion();
    1298             : 
    1299           0 :     sal_uInt16 nPoints = rPolygon.GetSize();
    1300           0 :     if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) )
    1301             :     {
    1302           0 :         ImplMap( rPolygon );
    1303           0 :         if ( bTo )
    1304             :         {
    1305           0 :             rPolygon[ 0 ] = maActPos;
    1306           0 :             maActPos = rPolygon[ nPoints - 1 ];
    1307             :         }
    1308             :         sal_uInt16 i;
    1309           0 :         for ( i = 0; ( i + 2 ) < nPoints; )
    1310             :         {
    1311           0 :             rPolygon.SetFlags( i++, POLY_NORMAL );
    1312           0 :             rPolygon.SetFlags( i++, POLY_CONTROL );
    1313           0 :             rPolygon.SetFlags( i++, POLY_CONTROL );
    1314             :         }
    1315           0 :         if ( bRecordPath )
    1316           0 :             aPathObj.AddPolyLine( rPolygon );
    1317             :         else
    1318             :         {
    1319           0 :             UpdateLineStyle();
    1320           0 :             mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
    1321             :         }
    1322             :     }
    1323           0 : }
    1324             : 
    1325           0 : void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, sal_Int32* pDXArry, bool bRecordPath, sal_Int32 nGfxMode )
    1326             : {
    1327           0 :     UpdateClipRegion();
    1328           0 :     rPosition = ImplMap( rPosition );
    1329           0 :     sal_Int32 nOldGfxMode = GetGfxMode();
    1330           0 :     SetGfxMode( GM_COMPATIBLE );
    1331             : 
    1332           0 :     if ( pDXArry )
    1333             :     {
    1334           0 :         sal_Int32 i, nSum, nLen = rText.getLength();
    1335             : 
    1336           0 :         for( i = 0, nSum = 0; i < nLen; i++ )
    1337             :         {
    1338           0 :             if ( i ) {
    1339             :                 // #i121382# Map DXArray using WorldTransform
    1340           0 :                 const Size aSize(ImplMap(Size( nSum, 0)));
    1341           0 :                 const basegfx::B2DVector aVector(aSize.Width(), aSize.Height());
    1342           0 :                 pDXArry[ i - 1 ] = basegfx::fround(aVector.getLength());
    1343             :             }
    1344           0 :             nSum += pDXArry[ i ];
    1345             :         }
    1346             :     }
    1347           0 :     if ( mnLatestTextLayoutMode != mnTextLayoutMode )
    1348             :     {
    1349           0 :         mnLatestTextLayoutMode = mnTextLayoutMode;
    1350           0 :         mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
    1351             :     }
    1352           0 :     SetGfxMode( nGfxMode );
    1353           0 :     bool bChangeFont = false;
    1354           0 :     if ( mnLatestTextAlign != mnTextAlign )
    1355             :     {
    1356           0 :         bChangeFont = true;
    1357           0 :         mnLatestTextAlign = mnTextAlign;
    1358             :         TextAlign eTextAlign;
    1359           0 :         if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
    1360           0 :             eTextAlign = ALIGN_BASELINE;
    1361           0 :         else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
    1362           0 :             eTextAlign = ALIGN_BOTTOM;
    1363             :         else
    1364           0 :             eTextAlign = ALIGN_TOP;
    1365           0 :         mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
    1366             :     }
    1367           0 :     if ( maLatestTextColor != maTextColor )
    1368             :     {
    1369           0 :         bChangeFont = true;
    1370           0 :         maLatestTextColor = maTextColor;
    1371           0 :         mpGDIMetaFile->AddAction( new MetaTextColorAction( maTextColor ) );
    1372             :     }
    1373           0 :     bool bChangeFillColor = false;
    1374           0 :     if ( maLatestBkColor != maBkColor )
    1375             :     {
    1376           0 :         bChangeFillColor = true;
    1377           0 :         maLatestBkColor = maBkColor;
    1378             :     }
    1379           0 :     if ( mnLatestBkMode != mnBkMode )
    1380             :     {
    1381           0 :         bChangeFillColor = true;
    1382           0 :         mnLatestBkMode = mnBkMode;
    1383             :     }
    1384           0 :     if ( bChangeFillColor )
    1385             :     {
    1386           0 :         bChangeFont = true;
    1387           0 :         mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
    1388             :     }
    1389           0 :     Font aTmp( maFont );
    1390           0 :     aTmp.SetColor( maTextColor );
    1391           0 :     aTmp.SetFillColor( maBkColor );
    1392             : 
    1393           0 :     if( mnBkMode == TRANSPARENT )
    1394           0 :         aTmp.SetTransparent( true );
    1395             :     else
    1396           0 :         aTmp.SetTransparent( false );
    1397             : 
    1398           0 :     if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
    1399           0 :         aTmp.SetAlign( ALIGN_BASELINE );
    1400           0 :     else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
    1401           0 :         aTmp.SetAlign( ALIGN_BOTTOM );
    1402             :     else
    1403           0 :         aTmp.SetAlign( ALIGN_TOP );
    1404             : 
    1405           0 :     if ( nGfxMode == GM_ADVANCED )
    1406             :     {
    1407             :         // check whether there is a font rotation applied via transformation
    1408           0 :         Point aP1( ImplMap( Point() ) );
    1409           0 :         Point aP2( ImplMap( Point( 0, 100 ) ) );
    1410           0 :         aP2.X() -= aP1.X();
    1411           0 :         aP2.Y() -= aP1.Y();
    1412           0 :         double fX = aP2.X();
    1413           0 :         double fY = aP2.Y();
    1414           0 :         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           0 :     if( mnTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) )
    1427             :     {
    1428             :         // #i117968# VirtualDevice is not thread safe, but filter is used in multithreading
    1429           0 :         SolarMutexGuard aGuard;
    1430           0 :         VirtualDevice aVDev;
    1431             : 
    1432             :         sal_Int32 nTextWidth;
    1433           0 :         aVDev.SetMapMode( MapMode( MAP_100TH_MM ) );
    1434           0 :         aVDev.SetFont( maFont );
    1435           0 :         if( pDXArry )
    1436             :         {
    1437           0 :             sal_uInt32 nLen = rText.getLength();
    1438           0 :             nTextWidth = aVDev.GetTextWidth( OUString(rText[ nLen - 1 ]) );
    1439           0 :             if( nLen > 1 )
    1440           0 :                 nTextWidth += pDXArry[ nLen - 2 ];
    1441             :         }
    1442             :         else
    1443           0 :             nTextWidth = aVDev.GetTextWidth( rText );
    1444             : 
    1445           0 :         if( mnTextAlign & TA_UPDATECP )
    1446           0 :             rPosition = maActPos;
    1447             : 
    1448           0 :         if ( mnTextAlign & TA_RIGHT_CENTER )
    1449             :         {
    1450           0 :             double fLength = ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1;
    1451           0 :             rPosition.X() -= (sal_Int32)( fLength * cos( maFont.GetOrientation() * F_PI1800 ) );
    1452           0 :             rPosition.Y() -= (sal_Int32)(-( fLength * sin( maFont.GetOrientation() * F_PI1800 ) ) );
    1453             :         }
    1454             : 
    1455           0 :         if( mnTextAlign & TA_UPDATECP )
    1456           0 :             maActPos.X() = rPosition.X() + nTextWidth;
    1457             :     }
    1458           0 :     if ( bChangeFont || ( maLatestFont != aTmp ) )
    1459             :     {
    1460           0 :         maLatestFont = aTmp;
    1461           0 :         mpGDIMetaFile->AddAction( new MetaFontAction( aTmp ) );
    1462           0 :         mpGDIMetaFile->AddAction( new MetaTextAlignAction( aTmp.GetAlign() ) );
    1463           0 :         mpGDIMetaFile->AddAction( new MetaTextColorAction( aTmp.GetColor() ) );
    1464           0 :         mpGDIMetaFile->AddAction( new MetaTextFillColorAction( aTmp.GetFillColor(), !aTmp.IsTransparent() ) );
    1465             :     }
    1466           0 :     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           0 :         sal_Int32* pDX = pDXArry;
    1475           0 :         if ( !pDXArry )
    1476             :         {
    1477             :             // #i117968# VirtualDevice is not thread safe, but filter is used in multithreading
    1478           0 :             SolarMutexGuard aGuard;
    1479           0 :             VirtualDevice aVDev;
    1480             : 
    1481           0 :             pDX = new sal_Int32[ rText.getLength() ];
    1482           0 :             aVDev.SetMapMode( MAP_100TH_MM );
    1483           0 :             aVDev.SetFont( maLatestFont );
    1484           0 :             aVDev.GetTextArray( rText, pDX, 0, rText.getLength());
    1485             :         }
    1486           0 :         mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDX, 0, rText.getLength() ) );
    1487           0 :         if ( !pDXArry )     // this means we have created our own array
    1488           0 :             delete[] pDX;   // which must be deleted
    1489             :     }
    1490           0 :     SetGfxMode( nOldGfxMode );
    1491           0 : }
    1492             : 
    1493           0 : void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap )
    1494             : {
    1495           0 :     BitmapEx aBmpEx( rBitmap );
    1496           0 :     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           0 :     if ( aBmpEx.IsTransparent() )
    1531           0 :         mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( rPos, rSize, aBmpEx ) );
    1532             :     else
    1533           0 :         mpGDIMetaFile->AddAction( new MetaBmpScaleAction( rPos, rSize, aBmpEx.GetBitmap() ) );
    1534           0 : }
    1535             : 
    1536           0 : void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
    1537             : {
    1538           0 :     UpdateClipRegion();
    1539             : 
    1540           0 :     size_t nObjects     = rSaveList.size();
    1541           0 :     size_t nObjectsLeft = nObjects;
    1542             : 
    1543           0 :     while ( nObjectsLeft )
    1544             :     {
    1545             :         size_t          i;
    1546           0 :         size_t          nObjectsOfSameSize = 0;
    1547           0 :         size_t          nObjectStartIndex = nObjects - nObjectsLeft;
    1548             : 
    1549           0 :         BSaveStruct*    pSave = rSaveList[ nObjectStartIndex ];
    1550           0 :         Rectangle       aRect( pSave->aOutRect );
    1551             : 
    1552           0 :         for ( i = nObjectStartIndex; i < nObjects; )
    1553             :         {
    1554           0 :             nObjectsOfSameSize++;
    1555           0 :             if ( ++i < nObjects )
    1556             :             {
    1557           0 :                 pSave = rSaveList[ i ];
    1558           0 :                 if ( pSave->aOutRect != aRect )
    1559           0 :                     break;
    1560             :             }
    1561             :         }
    1562           0 :         Point   aPos( ImplMap( aRect.TopLeft() ) );
    1563           0 :         Size    aSize( ImplMap( aRect.GetSize() ) );
    1564             : 
    1565           0 :         for ( i = nObjectStartIndex; i < ( nObjectStartIndex + nObjectsOfSameSize ); i++ )
    1566             :         {
    1567           0 :             pSave = rSaveList[ i ];
    1568             : 
    1569           0 :             sal_uInt32  nWinRop = pSave->nWinRop;
    1570           0 :             sal_uInt8   nRasterOperation = (sal_uInt8)( nWinRop >> 16 );
    1571             : 
    1572           0 :             sal_uInt32  nUsed =  0;
    1573           0 :             if ( ( nRasterOperation & 0xf )  != ( nRasterOperation >> 4 ) )
    1574           0 :                 nUsed |= 1;     // pattern is used
    1575           0 :             if ( ( nRasterOperation & 0x33 ) != ( ( nRasterOperation & 0xcc ) >> 2 ) )
    1576           0 :                 nUsed |= 2;     // source is used
    1577           0 :             if ( ( nRasterOperation & 0xaa ) != ( ( nRasterOperation & 0x55 ) << 1 ) )
    1578           0 :                 nUsed |= 4;     // destination is used
    1579             : 
    1580           0 :             if ( (nUsed & 1) && (( nUsed & 2 ) == 0) && nWinRop != PATINVERT )
    1581             :             {   // patterns aren't well supported yet
    1582           0 :                 sal_uInt32 nOldRop = SetRasterOp( ROP_OVERPAINT );  // in this case nRasterOperation is either 0 or 0xff
    1583           0 :                 UpdateFillStyle();
    1584           0 :                 DrawRect( aRect, false );
    1585           0 :                 SetRasterOp( nOldRop );
    1586             :             }
    1587             :             else
    1588             :             {
    1589           0 :                 bool bDrawn = false;
    1590             : 
    1591           0 :                 if ( i == nObjectStartIndex )   // optimizing, sometimes it is possible to create just one transparent bitmap
    1592             :                 {
    1593           0 :                     if ( nObjectsOfSameSize == 2 )
    1594             :                     {
    1595           0 :                         BSaveStruct* pSave2 = rSaveList[ i + 1 ];
    1596           0 :                         if ( ( pSave->aBmp.GetPrefSize() == pSave2->aBmp.GetPrefSize() ) &&
    1597           0 :                              ( 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           0 :                             if ( ( nWinRop == SRCPAINT ) && ( pSave2->nWinRop == SRCAND ) )
    1606             :                             {
    1607           0 :                                 Bitmap aMask( pSave->aBmp ); aMask.Invert();
    1608           0 :                                 BitmapEx aBmpEx( pSave2->aBmp, aMask );
    1609           0 :                                 ImplDrawBitmap( aPos, aSize, aBmpEx );
    1610           0 :                                 bDrawn = true;
    1611           0 :                                 i++;
    1612             :                             }
    1613             :                             // #i20085# This is just the other way
    1614             :                             // around as above. Only difference: mask
    1615             :                             // is inverted
    1616           0 :                             else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCPAINT ) )
    1617             :                             {
    1618           0 :                                 Bitmap aMask( pSave->aBmp );
    1619           0 :                                 BitmapEx aBmpEx( pSave2->aBmp, aMask );
    1620           0 :                                 ImplDrawBitmap( aPos, aSize, aBmpEx );
    1621           0 :                                 bDrawn = true;
    1622           0 :                                 i++;
    1623             :                             }
    1624             :                         }
    1625             :                     }
    1626             :                 }
    1627             : 
    1628           0 :                 if ( !bDrawn )
    1629             :                 {
    1630           0 :                     Push();
    1631           0 :                     sal_uInt32  nOldRop = SetRasterOp( R2_COPYPEN );
    1632           0 :                     Bitmap      aBitmap( pSave->aBmp );
    1633           0 :                     sal_uInt32  nOperation = ( nRasterOperation & 0xf );
    1634           0 :                     switch( nOperation )
    1635             :                     {
    1636             :                         case 0x1 :
    1637             :                         case 0xe :
    1638             :                         {
    1639           0 :                             SetRasterOp( R2_XORPEN );
    1640           0 :                             ImplDrawBitmap( aPos, aSize, aBitmap );
    1641           0 :                             SetRasterOp( R2_COPYPEN );
    1642           0 :                             Bitmap  aMask( aBitmap );
    1643           0 :                             aMask.Invert();
    1644           0 :                             BitmapEx aBmpEx( aBitmap, aMask );
    1645           0 :                             ImplDrawBitmap( aPos, aSize, aBmpEx );
    1646           0 :                             if ( nOperation == 0x1 )
    1647             :                             {
    1648           0 :                                 SetRasterOp( R2_NOT );
    1649           0 :                                 DrawRect( aRect, false );
    1650           0 :                             }
    1651             :                         }
    1652           0 :                         break;
    1653             :                         case 0x7 :
    1654             :                         case 0x8 :
    1655             :                         {
    1656           0 :                             Bitmap  aMask( aBitmap );
    1657           0 :                             if ( ( nUsed & 1 ) && ( nRasterOperation & 0xb0 ) == 0xb0 )     // pattern used
    1658             :                             {
    1659           0 :                                 aBitmap.Convert( BMP_CONVERSION_24BIT );
    1660           0 :                                 aBitmap.Erase( maFillStyle.aFillColor );
    1661             :                             }
    1662           0 :                             BitmapEx aBmpEx( aBitmap, aMask );
    1663           0 :                             ImplDrawBitmap( aPos, aSize, aBmpEx );
    1664           0 :                             if ( nOperation == 0x7 )
    1665             :                             {
    1666           0 :                                 SetRasterOp( R2_NOT );
    1667           0 :                                 DrawRect( aRect, false );
    1668           0 :                             }
    1669             :                         }
    1670           0 :                         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           0 :                             if ( nRasterOperation == 0x33 )
    1734           0 :                                 aBitmap.Invert();
    1735           0 :                             ImplDrawBitmap( aPos, aSize, aBitmap );
    1736             :                         }
    1737           0 :                         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           0 :                     SetRasterOp( nOldRop );
    1748           0 :                     Pop();
    1749             :                 }
    1750             :             }
    1751             :         }
    1752           0 :         nObjectsLeft -= nObjectsOfSameSize;
    1753             :     }
    1754             : 
    1755           0 :     for( size_t i = 0, n = rSaveList.size(); i < n; ++i )
    1756           0 :         delete rSaveList[ i ];
    1757           0 :     rSaveList.clear();
    1758           0 : }
    1759             : 
    1760           0 : void WinMtfOutput::SetDevOrg( const Point& rPoint )
    1761             : {
    1762           0 :     mnDevOrgX = rPoint.X();
    1763           0 :     mnDevOrgY = rPoint.Y();
    1764           0 : }
    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           0 : void WinMtfOutput::SetDevExt( const Size& rSize ,bool regular)
    1773             : {
    1774           0 :     if ( rSize.Width() && rSize.Height() )
    1775             :     {
    1776           0 :         switch( mnMapMode )
    1777             :         {
    1778             :             case MM_ISOTROPIC :
    1779             :             case MM_ANISOTROPIC :
    1780             :             {
    1781           0 :                 mnDevWidth = rSize.Width();
    1782           0 :                 mnDevHeight = rSize.Height();
    1783             :             }
    1784             :         }
    1785           0 :         if (regular)
    1786             :         {
    1787           0 :             mbIsMapDevSet=true;
    1788             :         }
    1789             :     }
    1790           0 : }
    1791             : 
    1792           0 : void WinMtfOutput::ScaleDevExt( double fX, double fY )
    1793             : {
    1794           0 :     mnDevWidth = FRound( mnDevWidth * fX );
    1795           0 :     mnDevHeight = FRound( mnDevHeight * fY );
    1796           0 : }
    1797             : 
    1798           0 : void WinMtfOutput::SetWinOrg( const Point& rPoint , bool bIsEMF)
    1799             : {
    1800           0 :     mnWinOrgX = rPoint.X();
    1801           0 :     mnWinOrgY = rPoint.Y();
    1802           0 :     if (bIsEMF)
    1803             :     {
    1804           0 :         SetDevByWin();
    1805             :     }
    1806           0 :     mbIsMapWinSet=true;
    1807           0 : }
    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           0 : void WinMtfOutput::SetDevByWin() //mnWinExt...-stuff has to be assigned before.
    1816             : {
    1817           0 :     if (!mbIsMapDevSet)
    1818             :     {
    1819           0 :         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           0 : }
    1825             : 
    1826           0 : void WinMtfOutput::SetWinExt( const Size& rSize, bool bIsEMF )
    1827             : {
    1828           0 :     if( rSize.Width() && rSize.Height() )
    1829             :     {
    1830           0 :         switch( mnMapMode )
    1831             :         {
    1832             :             case MM_ISOTROPIC :
    1833             :             case MM_ANISOTROPIC :
    1834             :             {
    1835           0 :                 mnWinExtX = rSize.Width();
    1836           0 :                 mnWinExtY = rSize.Height();
    1837           0 :                 if (bIsEMF)
    1838             :                 {
    1839           0 :                     SetDevByWin();
    1840             :                 }
    1841           0 :                 mbIsMapWinSet=true;
    1842             :             }
    1843             :         }
    1844             :     }
    1845           0 : }
    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           0 : void WinMtfOutput::SetrclBounds( const Rectangle& rRect )
    1854             : {
    1855           0 :     mrclBounds = rRect;
    1856           0 : }
    1857             : 
    1858           0 : void WinMtfOutput::SetrclFrame( const Rectangle& rRect )
    1859             : {
    1860           0 :     mrclFrame = rRect;
    1861           0 : }
    1862             : 
    1863           0 : void WinMtfOutput::SetRefPix( const Size& rSize )
    1864             : {
    1865           0 :     mnPixX = rSize.Width();
    1866           0 :     mnPixY = rSize.Height();
    1867           0 : }
    1868             : 
    1869           0 : void WinMtfOutput::SetRefMill( const Size& rSize )
    1870             : {
    1871           0 :     mnMillX = rSize.Width();
    1872           0 :     mnMillY = rSize.Height();
    1873           0 : }
    1874             : 
    1875           0 : void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
    1876             : {
    1877           0 :     mnMapMode = nMapMode;
    1878           0 :     if ( nMapMode == MM_TEXT && !mbIsMapWinSet )
    1879             :     {
    1880           0 :         mnWinExtX = mnDevWidth;
    1881           0 :         mnWinExtY = mnDevHeight;
    1882             :     }
    1883           0 :     else if ( mnMapMode == MM_HIMETRIC )
    1884             :     {
    1885           0 :         mnWinExtX = mnMillX * 100;
    1886           0 :         mnWinExtY = mnMillY * 100;
    1887             :     }
    1888           0 : }
    1889             : 
    1890           0 : void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
    1891             : {
    1892           0 :     maXForm.eM11 = rXForm.eM11;
    1893           0 :     maXForm.eM12 = rXForm.eM12;
    1894           0 :     maXForm.eM21 = rXForm.eM21;
    1895           0 :     maXForm.eM22 = rXForm.eM22;
    1896           0 :     maXForm.eDx = rXForm.eDx;
    1897           0 :     maXForm.eDy = rXForm.eDy;
    1898           0 : }
    1899             : 
    1900           0 : void WinMtfOutput::ModifyWorldTransform( const XForm& rXForm, sal_uInt32 nMode )
    1901             : {
    1902           0 :     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           0 :             if ( nMode == MWT_LEFTMULTIPLY )
    1918             :             {
    1919           0 :                 pLeft = &rXForm;
    1920           0 :                 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           0 :             aF[0][0] = pLeft->eM11;
    1933           0 :             aF[0][1] = pLeft->eM12;
    1934           0 :             aF[0][2] = 0;
    1935           0 :             aF[1][0] = pLeft->eM21;
    1936           0 :             aF[1][1] = pLeft->eM22;
    1937           0 :             aF[1][2] = 0;
    1938           0 :             aF[2][0] = pLeft->eDx;
    1939           0 :             aF[2][1] = pLeft->eDy;
    1940           0 :             aF[2][2] = 1;
    1941             : 
    1942           0 :             bF[0][0] = pRight->eM11;
    1943           0 :             bF[0][1] = pRight->eM12;
    1944           0 :             bF[0][2] = 0;
    1945           0 :             bF[1][0] = pRight->eM21;
    1946           0 :             bF[1][1] = pRight->eM22;
    1947           0 :             bF[1][2] = 0;
    1948           0 :             bF[2][0] = pRight->eDx;
    1949           0 :             bF[2][1] = pRight->eDy;
    1950           0 :             bF[2][2] = 1;
    1951             : 
    1952             :             int i, j, k;
    1953           0 :             for ( i = 0; i < 3; i++ )
    1954             :             {
    1955           0 :               for ( j = 0; j < 3; j++ )
    1956             :               {
    1957           0 :                  cF[i][j] = 0;
    1958           0 :                  for ( k = 0; k < 3; k++ )
    1959           0 :                     cF[i][j] += aF[i][k] * bF[k][j];
    1960             :               }
    1961             :             }
    1962           0 :             maXForm.eM11 = cF[0][0];
    1963           0 :             maXForm.eM12 = cF[0][1];
    1964           0 :             maXForm.eM21 = cF[1][0];
    1965           0 :             maXForm.eM22 = cF[1][1];
    1966           0 :             maXForm.eDx = cF[2][0];
    1967           0 :             maXForm.eDy = cF[2][1];
    1968           0 :             break;
    1969             :         }
    1970             :         case MWT_SET:
    1971             :         {
    1972           0 :             SetWorldTransform(rXForm);
    1973           0 :             break;
    1974             :         }
    1975             :     }
    1976           0 : }
    1977             : 
    1978           0 : void WinMtfOutput::Push()                       // !! to be able to access the original ClipRegion it
    1979             : {                                               // is not allowed to use the MetaPushAction()
    1980           0 :     UpdateClipRegion();                         // (the original clip region is on top of the stack) (SJ)
    1981           0 :     SaveStructPtr pSave( new SaveStruct );
    1982             : 
    1983           0 :     pSave->aLineStyle = maLineStyle;
    1984           0 :     pSave->aFillStyle = maFillStyle;
    1985             : 
    1986           0 :     pSave->aFont = maFont;
    1987           0 :     pSave->aTextColor = maTextColor;
    1988           0 :     pSave->nTextAlign = mnTextAlign;
    1989           0 :     pSave->nTextLayoutMode = mnTextLayoutMode;
    1990           0 :     pSave->nMapMode = mnMapMode;
    1991           0 :     pSave->nGfxMode = mnGfxMode;
    1992           0 :     pSave->nBkMode = mnBkMode;
    1993           0 :     pSave->aBkColor = maBkColor;
    1994           0 :     pSave->bFillStyleSelected = mbFillStyleSelected;
    1995             : 
    1996           0 :     pSave->aActPos = maActPos;
    1997           0 :     pSave->aXForm = maXForm;
    1998           0 :     pSave->eRasterOp = meRasterOp;
    1999             : 
    2000           0 :     pSave->nWinOrgX = mnWinOrgX;
    2001           0 :     pSave->nWinOrgY = mnWinOrgY;
    2002           0 :     pSave->nWinExtX = mnWinExtX;
    2003           0 :     pSave->nWinExtY = mnWinExtY;
    2004           0 :     pSave->nDevOrgX = mnDevOrgX;
    2005           0 :     pSave->nDevOrgY = mnDevOrgY;
    2006           0 :     pSave->nDevWidth = mnDevWidth;
    2007           0 :     pSave->nDevHeight = mnDevHeight;
    2008             : 
    2009           0 :     pSave->aPathObj = aPathObj;
    2010           0 :     pSave->aClipPath = aClipPath;
    2011             : 
    2012           0 :     vSaveStack.push_back( pSave );
    2013           0 : }
    2014             : 
    2015           0 : void WinMtfOutput::Pop()
    2016             : {
    2017             :     // Get the latest data from the stack
    2018           0 :     if( !vSaveStack.empty() )
    2019             :     {
    2020             :         // Backup the current data on the stack
    2021           0 :         SaveStructPtr pSave( vSaveStack.back() );
    2022             : 
    2023           0 :         maLineStyle = pSave->aLineStyle;
    2024           0 :         maFillStyle = pSave->aFillStyle;
    2025             : 
    2026           0 :         maFont = pSave->aFont;
    2027           0 :         maTextColor = pSave->aTextColor;
    2028           0 :         mnTextAlign = pSave->nTextAlign;
    2029           0 :         mnTextLayoutMode = pSave->nTextLayoutMode;
    2030           0 :         mnBkMode = pSave->nBkMode;
    2031           0 :         mnGfxMode = pSave->nGfxMode;
    2032           0 :         mnMapMode = pSave->nMapMode;
    2033           0 :         maBkColor = pSave->aBkColor;
    2034           0 :         mbFillStyleSelected = pSave->bFillStyleSelected;
    2035             : 
    2036           0 :         maActPos = pSave->aActPos;
    2037           0 :         maXForm = pSave->aXForm;
    2038           0 :         meRasterOp = pSave->eRasterOp;
    2039             : 
    2040           0 :         mnWinOrgX = pSave->nWinOrgX;
    2041           0 :         mnWinOrgY = pSave->nWinOrgY;
    2042           0 :         mnWinExtX = pSave->nWinExtX;
    2043           0 :         mnWinExtY = pSave->nWinExtY;
    2044           0 :         mnDevOrgX = pSave->nDevOrgX;
    2045           0 :         mnDevOrgY = pSave->nDevOrgY;
    2046           0 :         mnDevWidth = pSave->nDevWidth;
    2047           0 :         mnDevHeight = pSave->nDevHeight;
    2048             : 
    2049           0 :         aPathObj = pSave->aPathObj;
    2050           0 :         if ( ! ( aClipPath == pSave->aClipPath ) )
    2051             :         {
    2052           0 :             aClipPath = pSave->aClipPath;
    2053           0 :             mbClipNeedsUpdate = true;
    2054             :         }
    2055           0 :         if ( meLatestRasterOp != meRasterOp )
    2056           0 :             mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
    2057           0 :         vSaveStack.pop_back();
    2058             :     }
    2059           0 : }
    2060             : 
    2061           0 : void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
    2062             : {
    2063           0 :    rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
    2064           0 : }
    2065             : 
    2066           0 : void WinMtfOutput::PassEMFPlusHeaderInfo()
    2067             : {
    2068             :     EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS header info\n"));
    2069             : 
    2070           0 :     SvMemoryStream mem;
    2071             :     sal_Int32 nLeft, nRight, nTop, nBottom;
    2072             : 
    2073           0 :     nLeft = mrclFrame.Left();
    2074           0 :     nTop = mrclFrame.Top();
    2075           0 :     nRight = mrclFrame.Right();
    2076           0 :     nBottom = mrclFrame.Bottom();
    2077             : 
    2078             :     // emf header info
    2079           0 :     mem.WriteInt32( nLeft ).WriteInt32( nTop ).WriteInt32( nRight ).WriteInt32( nBottom );
    2080           0 :     mem.WriteInt32( mnPixX ).WriteInt32( mnPixY ).WriteInt32( mnMillX ).WriteInt32( mnMillY );
    2081             : 
    2082             :     float one, zero;
    2083             : 
    2084           0 :     one = 1;
    2085           0 :     zero = 0;
    2086             : 
    2087             :     // add transformation matrix to be used in vcl's metaact.cxx for
    2088             :     // rotate and scale operations
    2089           0 :     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           0 :     mem.Flush();
    2094             : 
    2095           0 :     mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const sal_uInt8*) mem.GetData(), mem.GetEndOfData() ) );
    2096           0 :     mpGDIMetaFile->UseCanvas( true );
    2097           0 : }
    2098             : 
    2099           0 : 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           0 :     mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS", 0, static_cast<const sal_uInt8*>(pBuffer), nLength ) );
    2103           0 : }
    2104             : 
    2105             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10