LCOV - code coverage report
Current view: top level - vcl/source/filter/wmf - wmfwr.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 715 1068 66.9 %
Date: 2015-06-13 12:38:46 Functions: 54 64 84.4 %
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 "sal/config.h"
      21             : 
      22             : #include <algorithm>
      23             : 
      24             : #include "wmfwr.hxx"
      25             : #include <unotools/fontcvt.hxx>
      26             : #include "emfwr.hxx"
      27             : #include <rtl/crc.h>
      28             : #include <rtl/strbuf.hxx>
      29             : #include <rtl/tencinfo.h>
      30             : #include <tools/bigint.hxx>
      31             : #include <tools/helpers.hxx>
      32             : #include <tools/tenccvt.hxx>
      33             : #include <tools/fract.hxx>
      34             : #include <osl/endian.h>
      35             : #include <vcl/dibtools.hxx>
      36             : #include <vcl/metric.hxx>
      37             : #include <basegfx/polygon/b2dpolygon.hxx>
      38             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      39             : #include <boost/scoped_array.hpp>
      40             : 
      41             : // MS Windows defines
      42             : 
      43             : #define W_META_SETBKMODE            0x0102
      44             : #define W_META_SETROP2              0x0104
      45             : #define W_META_SETSTRETCHBLTMODE    0x0107
      46             : #define W_META_SETTEXTCOLOR         0x0209
      47             : #define W_META_SETWINDOWORG         0x020B
      48             : #define W_META_SETWINDOWEXT         0x020C
      49             : #define W_META_LINETO               0x0213
      50             : #define W_META_MOVETO               0x0214
      51             : #define W_META_INTERSECTCLIPRECT    0x0416
      52             : #define W_META_ARC                  0x0817
      53             : #define W_META_ELLIPSE              0x0418
      54             : #define W_META_PIE                  0x081A
      55             : #define W_META_RECTANGLE            0x041B
      56             : #define W_META_ROUNDRECT            0x061C
      57             : #define W_META_SAVEDC               0x001E
      58             : #define W_META_SETPIXEL             0x041F
      59             : #define W_META_TEXTOUT              0x0521
      60             : #define W_META_POLYGON              0x0324
      61             : #define W_META_POLYLINE             0x0325
      62             : #define W_META_ESCAPE               0x0626
      63             : #define W_META_RESTOREDC            0x0127
      64             : #define W_META_SELECTOBJECT         0x012D
      65             : #define W_META_SETTEXTALIGN         0x012E
      66             : #define W_META_CHORD                0x0830
      67             : #define W_META_EXTTEXTOUT           0x0a32
      68             : #define W_META_POLYPOLYGON          0x0538
      69             : #define W_META_STRETCHDIB           0x0f43
      70             : #define W_META_DELETEOBJECT         0x01f0
      71             : #define W_META_CREATEPENINDIRECT    0x02FA
      72             : #define W_META_CREATEFONTINDIRECT   0x02FB
      73             : #define W_META_CREATEBRUSHINDIRECT  0x02FC
      74             : 
      75             : #define W_TRANSPARENT     1
      76             : #define W_OPAQUE          2
      77             : 
      78             : #define W_R2_NOT              6
      79             : #define W_R2_XORPEN           7
      80             : #define W_R2_COPYPEN          13
      81             : 
      82             : #define W_TA_NOUPDATECP      0x0000
      83             : #define W_TA_LEFT            0x0000
      84             : #define W_TA_RIGHT           0x0002
      85             : #define W_TA_TOP             0x0000
      86             : #define W_TA_BOTTOM          0x0008
      87             : #define W_TA_BASELINE        0x0018
      88             : #define W_TA_RTLREADING      0x0100
      89             : 
      90             : #define W_SRCCOPY             0x00CC0020L
      91             : #define W_SRCPAINT            0x00EE0086L
      92             : #define W_SRCAND              0x008800C6L
      93             : #define W_SRCINVERT           0x00660046L
      94             : #define W_DSTINVERT           0x00550009L
      95             : 
      96             : #define W_PS_SOLID            0
      97             : #define W_PS_DASH             1
      98             : #define W_PS_DOT              2
      99             : #define W_PS_DASHDOT          3
     100             : #define W_PS_DASHDOTDOT       4
     101             : #define W_PS_NULL             5
     102             : 
     103             : #define W_LF_FACESIZE       32
     104             : 
     105             : #define W_ANSI_CHARSET          0
     106             : 
     107             : #define W_DEFAULT_PITCH       0x00
     108             : #define W_FIXED_PITCH         0x01
     109             : #define W_VARIABLE_PITCH      0x02
     110             : 
     111             : #define W_FF_DONTCARE         0x00
     112             : #define W_FF_ROMAN            0x10
     113             : #define W_FF_SWISS            0x20
     114             : #define W_FF_MODERN           0x30
     115             : #define W_FF_SCRIPT           0x40
     116             : #define W_FF_DECORATIVE       0x50
     117             : 
     118             : #define W_FW_DONTCARE       0
     119             : #define W_FW_THIN           100
     120             : #define W_FW_LIGHT          300
     121             : #define W_FW_NORMAL         400
     122             : #define W_FW_MEDIUM         500
     123             : #define W_FW_SEMIBOLD       600
     124             : #define W_FW_BOLD           700
     125             : #define W_FW_ULTRALIGHT     200
     126             : #define W_FW_ULTRABOLD      800
     127             : #define W_FW_BLACK          900
     128             : 
     129             : #define W_BS_SOLID          0
     130             : #define W_BS_HOLLOW         1
     131             : 
     132             : #define W_MFCOMMENT         15
     133             : 
     134             : #define PRIVATE_ESCAPE_UNICODE          2
     135             : 
     136          41 : WMFWriter::WMFWriter()
     137             :     : bStatus(false)
     138             :     , nLastPercent(0)
     139             :     , pWMF(NULL)
     140             :     , pVirDev(NULL)
     141             :     , nMetafileHeaderPos(0)
     142             :     , nMaxRecordSize(0)
     143             :     , nActRecordPos(0)
     144             :     , eSrcRasterOp(ROP_OVERPAINT)
     145             :     , eSrcTextAlign(ALIGN_BASELINE)
     146             :     , bSrcIsClipping(false)
     147             :     , pAttrStack(NULL)
     148             :     , eSrcHorTextAlign(W_TA_LEFT)
     149             :     , eDstROP2(ROP_OVERPAINT)
     150             :     , eDstTextAlign(ALIGN_BASELINE)
     151             :     , eDstHorTextAlign(W_TA_LEFT)
     152             :     , bDstIsClipping(false)
     153             :     , nDstPenHandle(0)
     154             :     , nDstFontHandle(0)
     155             :     , nDstBrushHandle(0)
     156             :     , nNumberOfActions(0)
     157             :     , nNumberOfBitmaps(0)
     158             :     , nWrittenActions(0)
     159             :     , nWrittenBitmaps(0)
     160             :     , nActBitmapPercent(0)
     161          41 :     , bEmbedEMF(false)
     162             : {
     163          41 : }
     164             : 
     165        3091 : void WMFWriter::MayCallback()
     166             : {
     167        3091 :     if ( xStatusIndicator.is() )
     168             :     {
     169             :         sal_uLong nPercent;
     170             : 
     171             :         // we simply assume that 16386 actions match to a bitmap
     172             :         // (normally a metafile either contains only actions or some bitmaps and
     173             :         // almost no actions. In which case the ratio is less important)
     174             : 
     175           0 :         nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
     176           0 :                 *100
     177           0 :                 /((nNumberOfBitmaps<<14)+nNumberOfActions);
     178             : 
     179           0 :         if ( nPercent >= nLastPercent + 3 )
     180             :         {
     181           0 :             nLastPercent = nPercent;
     182           0 :             if( nPercent <= 100 )
     183           0 :                 xStatusIndicator->setValue( nPercent );
     184             :         }
     185             :     }
     186        3091 : }
     187             : 
     188          41 : void WMFWriter::CountActionsAndBitmaps( const GDIMetaFile & rMTF )
     189             : {
     190             :     size_t nAction, nActionCount;
     191             : 
     192          41 :     nActionCount = rMTF.GetActionSize();
     193             : 
     194        3123 :     for ( nAction=0; nAction < nActionCount; nAction++ )
     195             :     {
     196        3082 :         MetaAction* pMA = rMTF.GetAction( nAction );
     197             : 
     198        3082 :         switch( pMA->GetType() )
     199             :         {
     200             :             case MetaActionType::BMP:
     201             :             case MetaActionType::BMPSCALE:
     202             :             case MetaActionType::BMPSCALEPART:
     203             :             case MetaActionType::BMPEX:
     204             :             case MetaActionType::BMPEXSCALE:
     205             :             case MetaActionType::BMPEXSCALEPART:
     206           5 :                 nNumberOfBitmaps++;
     207           5 :             break;
     208        3077 :             default: break;
     209             :         }
     210        3082 :         nNumberOfActions++;
     211             :     }
     212          41 : }
     213             : 
     214        3788 : void WMFWriter::WritePointXY(const Point & rPoint)
     215             : {
     216        3788 :     Point aPt( OutputDevice::LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
     217        3788 :     pWMF->WriteInt16( aPt.X() ).WriteInt16( aPt.Y() );
     218        3788 : }
     219             : 
     220         385 : void WMFWriter::WritePointYX(const Point & rPoint)
     221             : {
     222         385 :     Point aPt( OutputDevice::LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
     223         385 :     pWMF->WriteInt16( aPt.Y() ).WriteInt16( aPt.X() );
     224         385 : }
     225             : 
     226          85 : sal_Int32 WMFWriter::ScaleWidth( sal_Int32 nDX )
     227             : {
     228          85 :     Size aSz( OutputDevice::LogicToLogic(Size(nDX,0),aSrcMapMode,aTargetMapMode) );
     229          85 :     return aSz.Width();
     230             : }
     231             : 
     232         196 : void WMFWriter::WriteSize(const Size & rSize)
     233             : {
     234         196 :     Size aSz( OutputDevice::LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
     235         196 :     pWMF->WriteInt16( aSz.Width() ).WriteInt16( aSz.Height() );
     236         196 : }
     237             : 
     238         473 : void WMFWriter::WriteHeightWidth(const Size & rSize)
     239             : {
     240         473 :     Size aSz( OutputDevice::LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
     241         473 :     pWMF->WriteInt16( aSz.Height() ).WriteInt16( aSz.Width() );
     242         473 : }
     243             : 
     244          54 : void WMFWriter::WriteRectangle(const Rectangle & rRect)
     245             : {
     246          54 :     WritePointYX(Point(rRect.Right()+1,rRect.Bottom()+1));
     247          54 :     WritePointYX(rRect.TopLeft());
     248          54 : }
     249             : 
     250         788 : void WMFWriter::WriteColor(const Color & rColor)
     251             : {
     252         788 :     pWMF->WriteUChar( rColor.GetRed() ).WriteUChar( rColor.GetGreen() ).WriteUChar( rColor.GetBlue() ).WriteUChar( 0 );
     253         788 : }
     254             : 
     255        4803 : void WMFWriter::WriteRecordHeader(sal_uInt32 nSizeWords, sal_uInt16 nType)
     256             : {
     257        4803 :     nActRecordPos=pWMF->Tell();
     258        4803 :     if (nSizeWords>nMaxRecordSize) nMaxRecordSize=nSizeWords;
     259        4803 :     pWMF->WriteUInt32( nSizeWords ).WriteUInt16( nType );
     260        4803 : }
     261             : 
     262        1217 : void WMFWriter::UpdateRecordHeader()
     263             : {
     264             :     sal_uLong nPos;
     265             :     sal_uInt32 nSize;
     266             : 
     267        1217 :     nPos=pWMF->Tell(); nSize=nPos-nActRecordPos;
     268        1217 :     if ((nSize & 1)!=0) {
     269           0 :         pWMF->WriteUChar( 0 );
     270           0 :         nPos++; nSize++;
     271             :     }
     272        1217 :     nSize/=2;
     273        1217 :     if (nSize>nMaxRecordSize) nMaxRecordSize=nSize;
     274        1217 :     pWMF->Seek(nActRecordPos);
     275        1217 :     pWMF->WriteUInt32( nSize );
     276        1217 :     pWMF->Seek(nPos);
     277        1217 : }
     278             : 
     279           0 : void WMFWriter::WMFRecord_Arc(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
     280             : {
     281           0 :     WriteRecordHeader(0x0000000b,W_META_ARC);
     282           0 :     WritePointYX(rEndPt);
     283           0 :     WritePointYX(rStartPt);
     284           0 :     WriteRectangle(rRect);
     285           0 : }
     286             : 
     287           0 : void WMFWriter::WMFRecord_Chord(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
     288             : {
     289           0 :     WriteRecordHeader(0x0000000b,W_META_CHORD);
     290           0 :     WritePointYX(rEndPt);
     291           0 :     WritePointYX(rStartPt);
     292           0 :     WriteRectangle(rRect);
     293           0 : }
     294             : 
     295         202 : void WMFWriter::WMFRecord_CreateBrushIndirect(const Color& rColor)
     296             : {
     297         202 :     WriteRecordHeader(0x00000007,W_META_CREATEBRUSHINDIRECT);
     298             : 
     299         202 :     if( rColor==Color(COL_TRANSPARENT) )
     300          14 :         pWMF->WriteUInt16( W_BS_HOLLOW );
     301             :     else
     302         188 :         pWMF->WriteUInt16( W_BS_SOLID );
     303             : 
     304         202 :     WriteColor( rColor );
     305         202 :     pWMF->WriteUInt16( 0 );
     306         202 : }
     307             : 
     308         423 : void WMFWriter::WMFRecord_CreateFontIndirect(const vcl::Font & rFont)
     309             : {
     310             :     sal_uInt16 nWeight,i;
     311             :     sal_uInt8 nPitchFamily;
     312             : 
     313         423 :     WriteRecordHeader(0x00000000,W_META_CREATEFONTINDIRECT);
     314         423 :     WriteHeightWidth(Size(rFont.GetSize().Width(),-rFont.GetSize().Height()));
     315         423 :     pWMF->WriteInt16( rFont.GetOrientation() ).WriteInt16( rFont.GetOrientation() );
     316             : 
     317         423 :     switch (rFont.GetWeight()) {
     318           0 :         case WEIGHT_THIN:       nWeight=W_FW_THIN;       break;
     319           0 :         case WEIGHT_ULTRALIGHT: nWeight=W_FW_ULTRALIGHT; break;
     320           0 :         case WEIGHT_LIGHT:      nWeight=W_FW_LIGHT;      break;
     321           0 :         case WEIGHT_SEMILIGHT:  nWeight=W_FW_LIGHT;      break;
     322         382 :         case WEIGHT_NORMAL:     nWeight=W_FW_NORMAL;     break;
     323           0 :         case WEIGHT_MEDIUM:     nWeight=W_FW_MEDIUM;     break;
     324           0 :         case WEIGHT_SEMIBOLD:   nWeight=W_FW_SEMIBOLD;   break;
     325           0 :         case WEIGHT_BOLD:       nWeight=W_FW_BOLD;       break;
     326           0 :         case WEIGHT_ULTRABOLD:  nWeight=W_FW_ULTRABOLD;  break;
     327           0 :         case WEIGHT_BLACK:      nWeight=W_FW_BLACK;      break;
     328          41 :         default:                nWeight=W_FW_DONTCARE;
     329             :     }
     330         423 :     pWMF->WriteUInt16( nWeight );
     331             : 
     332         423 :     if (rFont.GetItalic()==ITALIC_NONE)       pWMF->WriteUChar( 0 ); else  pWMF->WriteUChar( 1 );
     333         423 :     if (rFont.GetUnderline()==UNDERLINE_NONE) pWMF->WriteUChar( 0 ); else  pWMF->WriteUChar( 1 );
     334         423 :     if (rFont.GetStrikeout()==STRIKEOUT_NONE) pWMF->WriteUChar( 0 ); else  pWMF->WriteUChar( 1 );
     335             : 
     336         423 :     rtl_TextEncoding  eFontNameEncoding = rFont.GetCharSet();
     337         423 :     sal_uInt8         nCharSet = rtl_getBestWindowsCharsetFromTextEncoding( eFontNameEncoding );
     338         423 :     if ( eFontNameEncoding == RTL_TEXTENCODING_SYMBOL )
     339           0 :         eFontNameEncoding = RTL_TEXTENCODING_MS_1252;
     340         423 :     if ( nCharSet == 1 )
     341           0 :         nCharSet = W_ANSI_CHARSET;
     342         423 :     pWMF->WriteUChar( nCharSet );
     343             : 
     344         423 :     pWMF->WriteUChar( 0 ).WriteUChar( 0 ).WriteUChar( 0 );
     345             : 
     346         423 :     switch (rFont.GetPitch()) {
     347           0 :         case PITCH_FIXED:    nPitchFamily=W_FIXED_PITCH;    break;
     348           8 :         case PITCH_VARIABLE: nPitchFamily=W_VARIABLE_PITCH; break;
     349         415 :         default:             nPitchFamily=W_DEFAULT_PITCH;
     350             :     }
     351         423 :     switch (rFont.GetFamily()) {
     352           0 :         case FAMILY_DECORATIVE: nPitchFamily|=W_FF_DECORATIVE; break;
     353           0 :         case FAMILY_MODERN:     nPitchFamily|=W_FF_MODERN;     break;
     354         248 :         case FAMILY_ROMAN:      nPitchFamily|=W_FF_ROMAN;      break;
     355           0 :         case FAMILY_SCRIPT:     nPitchFamily|=W_FF_SCRIPT;     break;
     356           0 :         case FAMILY_SWISS:      nPitchFamily|=W_FF_SWISS;      break;
     357         175 :         default:                nPitchFamily|=W_FF_DONTCARE;
     358             :     }
     359         423 :     pWMF->WriteUChar( nPitchFamily );
     360             : 
     361         423 :     OString aFontName(OUStringToOString(rFont.GetName(), eFontNameEncoding));
     362       13959 :     for ( i = 0; i < W_LF_FACESIZE; i++ )
     363             :     {
     364       13536 :         sal_Char nChar = ( i < aFontName.getLength() ) ? aFontName[i] : 0;
     365       13536 :         pWMF->WriteChar( nChar );
     366             :     }
     367         423 :     UpdateRecordHeader();
     368         423 : }
     369             : 
     370         196 : void WMFWriter::WMFRecord_CreatePenIndirect(const Color& rColor, const LineInfo& rLineInfo )
     371             : {
     372         196 :     WriteRecordHeader(0x00000008,W_META_CREATEPENINDIRECT);
     373         196 :     sal_uInt16 nStyle = rColor == Color( COL_TRANSPARENT ) ? W_PS_NULL : W_PS_SOLID;
     374         196 :     switch( rLineInfo.GetStyle() )
     375             :     {
     376             :         case LINE_DASH :
     377             :         {
     378           0 :             if ( rLineInfo.GetDotCount() )
     379             :             {
     380           0 :                 if ( !rLineInfo.GetDashCount() )
     381           0 :                     nStyle = W_PS_DOT;
     382             :                 else
     383             :                 {
     384           0 :                     if ( rLineInfo.GetDotCount() == 1 )
     385           0 :                         nStyle = W_PS_DASHDOT;
     386             :                     else
     387           0 :                         nStyle = W_PS_DASHDOTDOT;
     388             :                 }
     389             :             }
     390             :             else
     391           0 :                 nStyle = W_PS_DASH;
     392             :         }
     393           0 :         break;
     394             :         case LINE_NONE :
     395           0 :             nStyle = W_PS_NULL;
     396           0 :         break;
     397             :         default:
     398         196 :         break;
     399             :     }
     400         196 :     pWMF->WriteUInt16( nStyle );
     401             : 
     402         196 :     WriteSize( Size( rLineInfo.GetWidth(), 0 ) );
     403         196 :     WriteColor( rColor );
     404         196 : }
     405             : 
     406         698 : void WMFWriter::WMFRecord_DeleteObject(sal_uInt16 nObjectHandle)
     407             : {
     408         698 :     WriteRecordHeader(0x00000004,W_META_DELETEOBJECT);
     409         698 :     pWMF->WriteUInt16( nObjectHandle );
     410         698 : }
     411             : 
     412           0 : void WMFWriter::WMFRecord_Ellipse(const Rectangle & rRect)
     413             : {
     414           0 :     WriteRecordHeader(0x00000007,W_META_ELLIPSE);
     415           0 :     WriteRectangle(rRect);
     416           0 : }
     417             : 
     418         122 : void WMFWriter::WMFRecord_Escape( sal_uInt32 nEsc, sal_uInt32 nLen, const sal_Int8* pData )
     419             : {
     420             : #ifdef OSL_BIGENDIAN
     421             :     sal_uInt32 nTmp = OSL_SWAPDWORD( nEsc );
     422             :     sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
     423             : #else
     424         122 :     sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
     425             : #endif
     426         122 :     if ( nLen )
     427         122 :         nCheckSum = rtl_crc32( nCheckSum, pData, nLen );
     428             : 
     429         122 :     WriteRecordHeader( 3 + 9 + ( ( nLen + 1 ) >> 1 ), W_META_ESCAPE );
     430         122 :     pWMF->WriteUInt16( W_MFCOMMENT )
     431         244 :          .WriteUInt16( nLen + 14 )      // we will always have a fourteen byte escape header:
     432         122 :          .WriteUInt16( 0x4f4f )         // OO
     433         122 :          .WriteUInt32( 0xa2c2a )        // evil magic number
     434         122 :          .WriteUInt32( nCheckSum )      // crc32 checksum about nEsc & pData
     435         244 :          .WriteUInt32( nEsc );          // escape number
     436         122 :     pWMF->Write( pData, nLen );
     437         122 :     if ( nLen & 1 )
     438           0 :         pWMF->WriteUChar( 0 );          // pad byte
     439         122 : }
     440             : 
     441             : /* if return value is true, then a complete unicode string and also a polygon replacement has been written,
     442             :     so there is no more action necessary
     443             : */
     444         349 : bool WMFWriter::WMFRecord_Escape_Unicode( const Point& rPoint, const OUString& rUniStr, const long* pDXAry )
     445             : {
     446         349 :     bool bEscapeUsed = false;
     447             : 
     448         349 :     sal_uInt32 i, nStringLen = rUniStr.getLength();
     449         349 :     if ( nStringLen )
     450             :     {
     451             :         // first we will check if a comment is necessary
     452         349 :         if ( aSrcFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL )     // symbol is always byte character, so there is no unicode loss
     453             :         {
     454         349 :             const sal_Unicode* pBuf = rUniStr.getStr();
     455         349 :             const rtl_TextEncoding aTextEncodingOrg = aSrcFont.GetCharSet();
     456         349 :             OString aByteStr(OUStringToOString(rUniStr, aTextEncodingOrg));
     457         698 :             OUString aUniStr2(OStringToOUString(aByteStr, aTextEncodingOrg));
     458         349 :             const sal_Unicode* pConversion = aUniStr2.getStr();  // this is the unicode array after bytestring <-> unistring conversion
     459         699 :             for ( i = 0; i < nStringLen; i++ )
     460             :             {
     461         407 :                 if ( *pBuf++ != *pConversion++ )
     462          57 :                     break;
     463             :             }
     464             : 
     465         349 :             if  ( i != nStringLen )                             // after conversion the characters are not original,
     466             :             {                                                   // try again, with determining a better charset from unicode char
     467          57 :                 pBuf = rUniStr.getStr();
     468          57 :                 const sal_Unicode* pCheckChar = pBuf;
     469          57 :                 rtl_TextEncoding aTextEncoding = getBestMSEncodingByChar(*pCheckChar); // try the first character
     470          59 :                 for ( i = 1; i < nStringLen; i++)
     471             :                 {
     472           4 :                     if (aTextEncoding != aTextEncodingOrg) // found something
     473           2 :                         break;
     474           2 :                     pCheckChar++;
     475           2 :                     aTextEncoding = getBestMSEncodingByChar(*pCheckChar); // try the next character
     476             :                 }
     477             : 
     478          57 :                 aByteStr = OUStringToOString(rUniStr,  aTextEncoding);
     479          57 :                 aUniStr2 = OStringToOUString(aByteStr, aTextEncoding);
     480          57 :                 pConversion = aUniStr2.getStr(); // this is the unicode array after bytestring <-> unistring conversion
     481          94 :                 for ( i = 0; i < nStringLen; i++ )
     482             :                 {
     483          61 :                     if ( *pBuf++ != *pConversion++ )
     484          24 :                         break;
     485             :                 }
     486          57 :                 if (i == nStringLen)
     487             :                 {
     488          33 :                     aSrcFont.SetCharSet (aTextEncoding);
     489          33 :                     SetAllAttr();
     490             :                 }
     491             :             }
     492             : 
     493         349 :             if ( ( i != nStringLen ) || IsStarSymbol( aSrcFont.GetName() ) )    // after conversion the characters are not original, so we
     494             :             {                                                                   // will store the unicode string and a polypoly replacement
     495         122 :                 Color aOldFillColor( aSrcFillColor );
     496         122 :                 Color aOldLineColor( aSrcLineColor );
     497         122 :                 aSrcLineInfo  = LineInfo();
     498         122 :                 aSrcFillColor = aSrcTextColor;
     499         122 :                 aSrcLineColor = Color( COL_TRANSPARENT );
     500         122 :                 SetLineAndFillAttr();
     501         122 :                 pVirDev->SetFont( aSrcFont );
     502         122 :                 std::vector<tools::PolyPolygon> aPolyPolyVec;
     503         122 :                 if ( pVirDev->GetTextOutlines( aPolyPolyVec, rUniStr ) )
     504             :                 {
     505         122 :                     sal_uInt32 nDXCount = pDXAry ? nStringLen : 0;
     506         122 :                     sal_uInt32 nSkipActions = aPolyPolyVec.size();
     507             :                     sal_Int32 nStrmLen = 8 +
     508         122 :                                            + sizeof( nStringLen ) + ( nStringLen * 2 )
     509         122 :                                            + sizeof( nDXCount ) + ( nDXCount * 4 )
     510         366 :                                            + sizeof( nSkipActions );
     511             : 
     512         122 :                     SvMemoryStream aMemoryStream( nStrmLen );
     513         122 :                     Point aPt( OutputDevice::LogicToLogic( rPoint, aSrcMapMode, aTargetMapMode ) );
     514         122 :                     aMemoryStream.WriteInt32( aPt.X() )
     515         244 :                                  .WriteInt32( aPt.Y() )
     516         122 :                                  .WriteUInt32( nStringLen );
     517         244 :                     for ( i = 0; i < nStringLen; i++ )
     518         122 :                         aMemoryStream.WriteUInt16( rUniStr[ i ] );
     519         122 :                     aMemoryStream.WriteUInt32( nDXCount );
     520         122 :                     for ( i = 0; i < nDXCount; i++ )
     521           0 :                         aMemoryStream.WriteInt32( pDXAry[ i ] );
     522         122 :                     aMemoryStream.WriteUInt32( nSkipActions );
     523         122 :                     WMFRecord_Escape( PRIVATE_ESCAPE_UNICODE, nStrmLen, static_cast<const sal_Int8*>(aMemoryStream.GetData()) );
     524             : 
     525         122 :                     std::vector<tools::PolyPolygon>::iterator aIter( aPolyPolyVec.begin() );
     526         366 :                     while ( aIter != aPolyPolyVec.end() )
     527             :                     {
     528         122 :                         tools::PolyPolygon aPolyPoly( *aIter++ );
     529         122 :                         aPolyPoly.Move( rPoint.X(), rPoint.Y() );
     530         122 :                         WMFRecord_PolyPolygon( aPolyPoly );
     531         122 :                     }
     532         122 :                     aSrcFillColor = aOldFillColor;
     533         122 :                     aSrcLineColor = aOldLineColor;
     534         122 :                     bEscapeUsed = true;
     535         122 :                 }
     536         349 :             }
     537             :         }
     538             :     }
     539         349 :     return bEscapeUsed;
     540             : }
     541             : 
     542         227 : void WMFWriter::WMFRecord_ExtTextOut( const Point& rPoint,
     543             :                                       const OUString& rString,
     544             :                                       const long* pDXAry )
     545             : {
     546         227 :     sal_Int32 nOriginalTextLen = rString.getLength();
     547             : 
     548         227 :     if ( (nOriginalTextLen <= 1) || (pDXAry == NULL) )
     549             :     {
     550         200 :         WMFRecord_TextOut(rPoint, rString);
     551         427 :         return;
     552             :     }
     553          27 :     rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
     554          27 :     OString aByteString(OUStringToOString(rString, eChrSet));
     555          27 :     TrueExtTextOut(rPoint, rString, aByteString, pDXAry);
     556             : }
     557             : 
     558          27 : void WMFWriter::TrueExtTextOut( const Point& rPoint, const OUString& rString,
     559             :                                 const OString& rByteString, const long* pDXAry )
     560             : {
     561          27 :     WriteRecordHeader( 0, W_META_EXTTEXTOUT );
     562          27 :     WritePointYX( rPoint );
     563          27 :     sal_uInt16 nNewTextLen = static_cast<sal_uInt16>(rByteString.getLength());
     564          27 :     pWMF->WriteUInt16( nNewTextLen ).WriteUInt16( 0 );
     565          27 :     write_uInt8s_FromOString(*pWMF, rByteString, nNewTextLen);
     566          27 :     if ( nNewTextLen & 1 )
     567          15 :         pWMF->WriteUChar( 0 );
     568             : 
     569          27 :     sal_Int32 nOriginalTextLen = rString.getLength();
     570          27 :     boost::scoped_array<sal_Int16> pConvertedDXAry(new sal_Int16[ nOriginalTextLen ]);
     571          27 :     sal_Int32 j = 0;
     572          27 :     pConvertedDXAry[ j++ ] = (sal_Int16)ScaleWidth( pDXAry[ 0 ] );
     573          58 :     for (sal_Int32 i = 1; i < ( nOriginalTextLen - 1 ); ++i)
     574          31 :         pConvertedDXAry[ j++ ] = (sal_Int16)ScaleWidth( pDXAry[ i ] - pDXAry[ i - 1 ] );
     575          27 :     pConvertedDXAry[ j ] = (sal_Int16)ScaleWidth( pDXAry[ nOriginalTextLen - 2 ] / ( nOriginalTextLen - 1 ) );
     576             : 
     577         112 :     for (sal_Int32 i = 0; i < nOriginalTextLen; ++i)
     578             :     {
     579          85 :         sal_Int16 nDx = pConvertedDXAry[ i ];
     580          85 :         pWMF->WriteInt16( nDx );
     581          85 :         if ( nOriginalTextLen < nNewTextLen )
     582             :         {
     583           0 :             sal_Unicode nUniChar = rString[i];
     584           0 :             OString aTemp(&nUniChar, 1, aSrcFont.GetCharSet());
     585           0 :             j = aTemp.getLength();
     586           0 :             while ( --j > 0 )
     587           0 :                 pWMF->WriteUInt16( 0 );
     588             :         }
     589             :     }
     590          27 :     pConvertedDXAry.reset();
     591          27 :     UpdateRecordHeader();
     592          27 : }
     593             : 
     594           0 : void WMFWriter::WMFRecord_LineTo(const Point & rPoint)
     595             : {
     596           0 :     WriteRecordHeader(0x00000005,W_META_LINETO);
     597           0 :     WritePointYX(rPoint);
     598           0 : }
     599             : 
     600           0 : void WMFWriter::WMFRecord_MoveTo(const Point & rPoint)
     601             : {
     602           0 :     WriteRecordHeader(0x00000005,W_META_MOVETO);
     603           0 :     WritePointYX(rPoint);
     604           0 : }
     605             : 
     606           0 : void WMFWriter::WMFRecord_Pie(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
     607             : {
     608           0 :     WriteRecordHeader(0x0000000b,W_META_PIE);
     609           0 :     WritePointYX(rEndPt);
     610           0 :     WritePointYX(rStartPt);
     611           0 :     WriteRectangle(rRect);
     612           0 : }
     613             : 
     614           0 : void WMFWriter::WMFRecord_Polygon(const Polygon & rPoly)
     615             : {
     616             :     sal_uInt16 nSize,i;
     617             : 
     618           0 :     Polygon aSimplePoly;
     619           0 :     if ( rPoly.HasFlags() )
     620           0 :         rPoly.AdaptiveSubdivide( aSimplePoly );
     621             :     else
     622           0 :         aSimplePoly = rPoly;
     623           0 :     nSize = aSimplePoly.GetSize();
     624           0 :     WriteRecordHeader(((sal_uLong)nSize)*2+4,W_META_POLYGON);
     625           0 :     pWMF->WriteUInt16( nSize );
     626           0 :     for (i=0; i<nSize; i++) WritePointXY(aSimplePoly.GetPoint(i));
     627           0 : }
     628             : 
     629          18 : void WMFWriter::WMFRecord_PolyLine(const Polygon & rPoly)
     630             : {
     631             :     sal_uInt16 nSize,i;
     632          18 :     Polygon aSimplePoly;
     633          18 :     if ( rPoly.HasFlags() )
     634           0 :         rPoly.AdaptiveSubdivide( aSimplePoly );
     635             :     else
     636          18 :         aSimplePoly = rPoly;
     637          18 :     nSize=aSimplePoly.GetSize();
     638          18 :     WriteRecordHeader(((sal_uLong)nSize)*2+4,W_META_POLYLINE);
     639          18 :     pWMF->WriteUInt16( nSize );
     640          18 :     for (i=0; i<nSize; i++) WritePointXY(aSimplePoly.GetPoint(i));
     641          18 : }
     642             : 
     643         134 : void WMFWriter::WMFRecord_PolyPolygon(const tools::PolyPolygon & rPolyPoly)
     644             : {
     645             :     const Polygon * pPoly;
     646             :     sal_uInt16 nCount,nSize,i,j;
     647             : 
     648         134 :     nCount=rPolyPoly.Count();
     649         134 :     tools::PolyPolygon aSimplePolyPoly( rPolyPoly );
     650         302 :     for ( i = 0; i < nCount; i++ )
     651             :     {
     652         168 :         if ( aSimplePolyPoly[ i ].HasFlags() )
     653             :         {
     654          59 :             Polygon aSimplePoly;
     655          59 :             aSimplePolyPoly[ i ].AdaptiveSubdivide( aSimplePoly );
     656          59 :             aSimplePolyPoly[ i ] = aSimplePoly;
     657             :         }
     658             :     }
     659         134 :     WriteRecordHeader(0,W_META_POLYPOLYGON);
     660         134 :     pWMF->WriteUInt16( nCount );
     661         134 :     for (i=0; i<nCount; i++) pWMF->WriteUInt16( (aSimplePolyPoly.GetObject(i).GetSize()) );
     662         302 :     for (i=0; i<nCount; i++) {
     663         168 :         pPoly=&(aSimplePolyPoly.GetObject(i));
     664         168 :         nSize=pPoly->GetSize();
     665         168 :         for (j=0; j<nSize; j++) WritePointXY(pPoly->GetPoint(j));
     666             :     }
     667         134 :     UpdateRecordHeader();
     668         134 : }
     669             : 
     670          20 : void WMFWriter::WMFRecord_Rectangle(const Rectangle & rRect)
     671             : {
     672          20 :     WriteRecordHeader( 0x00000007,W_META_RECTANGLE );
     673          20 :     WriteRectangle( rRect );
     674          20 : }
     675             : 
     676         398 : void WMFWriter::WMFRecord_RestoreDC()
     677             : {
     678         398 :     WriteRecordHeader(0x00000004,W_META_RESTOREDC);
     679         398 :     pWMF->WriteInt16( -1 );
     680         398 : }
     681             : 
     682           0 : void WMFWriter::WMFRecord_RoundRect(const Rectangle & rRect, long nHorzRound, long nVertRound)
     683             : {
     684           0 :     WriteRecordHeader(0x00000009,W_META_ROUNDRECT);
     685           0 :     WriteHeightWidth(Size(nHorzRound,nVertRound));
     686           0 :     WriteRectangle(rRect);
     687           0 : }
     688             : 
     689         398 : void WMFWriter::WMFRecord_SaveDC()
     690             : {
     691         398 :     WriteRecordHeader(0x00000003,W_META_SAVEDC);
     692         398 : }
     693             : 
     694         821 : void WMFWriter::WMFRecord_SelectObject(sal_uInt16 nObjectHandle)
     695             : {
     696         821 :     WriteRecordHeader(0x00000004,W_META_SELECTOBJECT);
     697         821 :     pWMF->WriteUInt16( nObjectHandle );
     698         821 : }
     699             : 
     700          41 : void WMFWriter::WMFRecord_SetBkMode(bool bTransparent)
     701             : {
     702          41 :     WriteRecordHeader(0x00000004,W_META_SETBKMODE);
     703          41 :     if (bTransparent) pWMF->WriteUInt16( W_TRANSPARENT );
     704           0 :     else                    pWMF->WriteUInt16( W_OPAQUE );
     705          41 : }
     706             : 
     707          41 : void WMFWriter::WMFRecord_SetStretchBltMode()
     708             : {
     709          41 :     WriteRecordHeader( 0x00000004, W_META_SETSTRETCHBLTMODE );
     710          41 :     pWMF->WriteUInt16( 3 ); // STRETCH_DELETESCANS
     711          41 : }
     712             : 
     713           0 : void WMFWriter::WMFRecord_SetPixel(const Point & rPoint, const Color & rColor)
     714             : {
     715           0 :     WriteRecordHeader(0x00000007,W_META_SETPIXEL);
     716           0 :     WriteColor(rColor);
     717           0 :     WritePointYX(rPoint);
     718           0 : }
     719             : 
     720          41 : void WMFWriter::WMFRecord_SetROP2(RasterOp eROP)
     721             : {
     722             :     sal_uInt16 nROP2;
     723             : 
     724          41 :     switch (eROP) {
     725           0 :         case ROP_INVERT: nROP2=W_R2_NOT;        break;
     726           0 :         case ROP_XOR:    nROP2=W_R2_XORPEN;     break;
     727          41 :         default:         nROP2=W_R2_COPYPEN;
     728             :     }
     729          41 :     WriteRecordHeader(0x00000004,W_META_SETROP2);
     730          41 :     pWMF->WriteUInt16( nROP2 );
     731          41 : }
     732             : 
     733          43 : void WMFWriter::WMFRecord_SetTextAlign(FontAlign eFontAlign, sal_uInt32 eHorTextAlign)
     734             : {
     735             :     sal_uInt16 nAlign;
     736             : 
     737          43 :     switch (eFontAlign) {
     738           2 :         case ALIGN_TOP:    nAlign=W_TA_TOP; break;
     739           0 :         case ALIGN_BOTTOM: nAlign=W_TA_BOTTOM; break;
     740          41 :         default:           nAlign=W_TA_BASELINE;
     741             :     }
     742          43 :     nAlign|=eHorTextAlign;
     743          43 :     nAlign|=W_TA_NOUPDATECP;
     744             : 
     745          43 :     WriteRecordHeader(0x00000004,W_META_SETTEXTALIGN);
     746          43 :     pWMF->WriteUInt16( nAlign );
     747          43 : }
     748             : 
     749         390 : void WMFWriter::WMFRecord_SetTextColor(const Color & rColor)
     750             : {
     751         390 :     WriteRecordHeader(0x00000005,W_META_SETTEXTCOLOR);
     752         390 :     WriteColor(rColor);
     753         390 : }
     754             : 
     755          41 : void WMFWriter::WMFRecord_SetWindowExt(const Size & rSize)
     756             : {
     757          41 :     WriteRecordHeader(0x00000005,W_META_SETWINDOWEXT);
     758          41 :     WriteHeightWidth(rSize);
     759          41 : }
     760             : 
     761          41 : void WMFWriter::WMFRecord_SetWindowOrg(const Point & rPoint)
     762             : {
     763          41 :     WriteRecordHeader(0x00000005,W_META_SETWINDOWORG);
     764          41 :     WritePointYX(rPoint);
     765          41 : }
     766             : 
     767           9 : void WMFWriter::WMFRecord_StretchDIB( const Point & rPoint, const Size & rSize,
     768             :                                       const Bitmap & rBitmap, sal_uInt32 nROP )
     769             : {
     770             :     sal_uLong nPosAnf,nPosEnd;
     771             : 
     772           9 :     nActBitmapPercent=50;
     773           9 :     MayCallback();
     774             : 
     775           9 :     WriteRecordHeader(0x00000000,W_META_STRETCHDIB);
     776             : 
     777             :     // The sequence in the metafile should be:
     778             :     // some parameters (length 22), then the bitmap without FILEHEADER.
     779             :     // As *pWMF << rBitmap generates a FILEHEADER of size 14,
     780             :     // we first write the bitmap at the right position
     781             :     // and overwrite later the FILEHEADER with the parameters.
     782           9 :     nPosAnf=pWMF->Tell(); // remember position, where parameters should be stored
     783           9 :     pWMF->WriteInt32( 0 ).WriteInt32( 0 ); // replenish 8 bytes (these 8 bytes +
     784             :                                            // 14 bytes superfluous FILEHEADER
     785             :                                            // = 22 bytes parameter)
     786             : 
     787             :     // write bitmap
     788           9 :     WriteDIB(rBitmap, *pWMF, false, true);
     789             : 
     790             :     // write the parameters:
     791           9 :     nPosEnd=pWMF->Tell();
     792           9 :     pWMF->Seek(nPosAnf);
     793             : 
     794             :     // determine raster-op, if nothing was passed
     795           9 :     if( !nROP )
     796             :     {
     797           1 :         switch( eSrcRasterOp )
     798             :         {
     799           0 :             case ROP_INVERT: nROP = W_DSTINVERT; break;
     800           0 :             case ROP_XOR:    nROP = W_SRCINVERT; break;
     801           1 :             default:         nROP = W_SRCCOPY;
     802             :         }
     803             :     }
     804             : 
     805           9 :     pWMF->WriteUInt32( nROP ).             WriteInt16( 0 ).             WriteInt16( rBitmap.GetSizePixel().Height() ).             WriteInt16( rBitmap.GetSizePixel().Width() ).             WriteInt16( 0 ).             WriteInt16( 0 );
     806             : 
     807           9 :     WriteHeightWidth(rSize);
     808           9 :     WritePointYX(rPoint);
     809           9 :     pWMF->Seek(nPosEnd);
     810             : 
     811           9 :     UpdateRecordHeader();
     812             : 
     813           9 :     nWrittenBitmaps++;
     814           9 :     nActBitmapPercent=0;
     815           9 : }
     816             : 
     817         200 : void WMFWriter::WMFRecord_TextOut(const Point & rPoint, const OUString & rStr)
     818             : {
     819         200 :     rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
     820         200 :     OString aString(OUStringToOString(rStr, eChrSet));
     821         200 :     TrueTextOut(rPoint, aString);
     822         200 : }
     823             : 
     824         200 : void WMFWriter::TrueTextOut(const Point & rPoint, const OString& rString)
     825             : {
     826         200 :     WriteRecordHeader(0,W_META_TEXTOUT);
     827             : 
     828         200 :     write_uInt16_lenPrefixed_uInt8s_FromOString(*pWMF, rString);
     829         200 :     sal_Int32 nLen = rString.getLength();
     830         200 :     if ((nLen&1)!=0) pWMF->WriteUChar( 0 );
     831         200 :     WritePointYX(rPoint);
     832         200 :     UpdateRecordHeader();
     833         200 : }
     834             : 
     835          41 : void WMFWriter::WMFRecord_EndOfFile()
     836             : {
     837          41 :     WriteRecordHeader(0x00000003,0x0000);
     838          41 : }
     839             : 
     840          34 : void WMFWriter::WMFRecord_IntersectClipRect( const Rectangle& rRect )
     841             : {
     842          34 :     WriteRecordHeader( 0x00000007, W_META_INTERSECTCLIPRECT );
     843          34 :     WriteRectangle(rRect);
     844          34 : }
     845             : 
     846         821 : sal_uInt16 WMFWriter::AllocHandle()
     847             : {
     848             :     sal_uInt16 i;
     849             : 
     850        2048 :     for (i=0; i<MAXOBJECTHANDLES; i++) {
     851        2048 :         if (!bHandleAllocated[i]) {
     852         821 :             bHandleAllocated[i]=true;
     853         821 :             return i;
     854             :         }
     855             :     }
     856           0 :     bStatus=false;
     857           0 :     return 0xffff;
     858             : }
     859             : 
     860         698 : void WMFWriter::FreeHandle(sal_uInt16 nObjectHandle)
     861             : {
     862         698 :     if (nObjectHandle<MAXOBJECTHANDLES) bHandleAllocated[nObjectHandle]=false;
     863         698 : }
     864             : 
     865         196 : void WMFWriter::CreateSelectDeletePen( const Color& rColor, const LineInfo& rLineInfo )
     866             : {
     867             :     sal_uInt16 nOldHandle;
     868             : 
     869         196 :     nOldHandle=nDstPenHandle;
     870         196 :     nDstPenHandle=AllocHandle();
     871         196 :     WMFRecord_CreatePenIndirect( rColor, rLineInfo );
     872         196 :     WMFRecord_SelectObject(nDstPenHandle);
     873         196 :     if (nOldHandle<MAXOBJECTHANDLES) {
     874         155 :         WMFRecord_DeleteObject(nOldHandle);
     875         155 :         FreeHandle(nOldHandle);
     876             :     }
     877         196 : }
     878             : 
     879         423 : void WMFWriter::CreateSelectDeleteFont(const vcl::Font & rFont)
     880             : {
     881             :     sal_uInt16 nOldHandle;
     882             : 
     883         423 :     nOldHandle=nDstFontHandle;
     884         423 :     nDstFontHandle=AllocHandle();
     885         423 :     WMFRecord_CreateFontIndirect(rFont);
     886         423 :     WMFRecord_SelectObject(nDstFontHandle);
     887         423 :     if (nOldHandle<MAXOBJECTHANDLES) {
     888         382 :         WMFRecord_DeleteObject(nOldHandle);
     889         382 :         FreeHandle(nOldHandle);
     890             :     }
     891         423 : }
     892             : 
     893         202 : void WMFWriter::CreateSelectDeleteBrush(const Color& rColor)
     894             : {
     895             :     sal_uInt16 nOldHandle;
     896             : 
     897         202 :     nOldHandle=nDstBrushHandle;
     898         202 :     nDstBrushHandle=AllocHandle();
     899         202 :     WMFRecord_CreateBrushIndirect(rColor);
     900         202 :     WMFRecord_SelectObject(nDstBrushHandle);
     901         202 :     if (nOldHandle<MAXOBJECTHANDLES) {
     902         161 :         WMFRecord_DeleteObject(nOldHandle);
     903         161 :         FreeHandle(nOldHandle);
     904             :     }
     905         202 : }
     906             : 
     907         952 : void WMFWriter::SetLineAndFillAttr()
     908             : {
     909         952 :     if ( eDstROP2 != eSrcRasterOp )
     910             :     {
     911           0 :         eDstROP2=eSrcRasterOp;
     912           0 :         WMFRecord_SetROP2(eDstROP2);
     913             :     }
     914         952 :     if ( ( aDstLineColor != aSrcLineColor ) || ( aDstLineInfo != aSrcLineInfo ) )
     915             :     {
     916         155 :         aDstLineColor = aSrcLineColor;
     917         155 :         aDstLineInfo  = aSrcLineInfo;
     918         155 :         CreateSelectDeletePen( aDstLineColor, aDstLineInfo );
     919             :     }
     920         952 :     if ( aDstFillColor != aSrcFillColor )
     921             :     {
     922         161 :         aDstFillColor = aSrcFillColor;
     923         161 :         CreateSelectDeleteBrush( aDstFillColor );
     924             :     }
     925         952 :     if ( bDstIsClipping != bSrcIsClipping ||
     926           0 :         (bSrcIsClipping && aDstClipRegion!=aSrcClipRegion)) {
     927           0 :         bDstIsClipping=bSrcIsClipping;
     928           0 :         aDstClipRegion=aSrcClipRegion;
     929             :     }
     930         952 : }
     931             : 
     932         780 : void WMFWriter::SetAllAttr()
     933             : {
     934         780 :     SetLineAndFillAttr();
     935         780 :     if ( aDstTextColor != aSrcTextColor )
     936             :     {
     937         349 :         aDstTextColor = aSrcTextColor;
     938         349 :         WMFRecord_SetTextColor(aDstTextColor);
     939             :     }
     940         780 :     if ( eDstTextAlign != eSrcTextAlign || eDstHorTextAlign != eSrcHorTextAlign )
     941             :     {
     942           2 :         eDstTextAlign = eSrcTextAlign;
     943           2 :         eDstHorTextAlign = eSrcHorTextAlign;
     944           2 :         WMFRecord_SetTextAlign( eDstTextAlign, eDstHorTextAlign );
     945             :     }
     946         780 :     if ( aDstFont != aSrcFont )
     947             :     {
     948         382 :         pVirDev->SetFont(aSrcFont);
     949         382 :         if ( aDstFont.GetName() != aSrcFont.GetName() )
     950             :         {
     951         349 :             FontCharMapPtr pFontCharMap;
     952         349 :             if ( pVirDev->GetFontCharMap( pFontCharMap ) )
     953             :             {
     954         349 :                 if ( ( pFontCharMap->GetFirstChar() & 0xff00 ) == 0xf000 )
     955           0 :                     aSrcFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
     956         349 :                 else if ( aSrcFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
     957           0 :                     aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
     958             :             }
     959             : 
     960         349 :             pFontCharMap = 0;
     961             :         }
     962             : 
     963         382 :         aDstFont = aSrcFont;
     964         382 :         CreateSelectDeleteFont(aDstFont);
     965             :     }
     966         780 : }
     967             : 
     968           0 : void WMFWriter::HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
     969             : {
     970           0 :     if(rLinePolygon.count())
     971             :     {
     972           0 :         basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
     973           0 :         basegfx::B2DPolyPolygon aFillPolyPolygon;
     974             : 
     975           0 :         rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
     976             : 
     977           0 :         if(aLinePolyPolygon.count())
     978             :         {
     979           0 :             aSrcLineInfo = rInfo;
     980           0 :             SetLineAndFillAttr();
     981             : 
     982           0 :             for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
     983             :             {
     984           0 :                 const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
     985           0 :                 WMFRecord_PolyLine(Polygon(aCandidate));
     986           0 :             }
     987             :         }
     988             : 
     989           0 :         if(aFillPolyPolygon.count())
     990             :         {
     991           0 :             const Color aOldLineColor(aSrcLineColor);
     992           0 :             const Color aOldFillColor(aSrcFillColor);
     993             : 
     994           0 :             aSrcLineColor = Color( COL_TRANSPARENT );
     995           0 :             aSrcFillColor = aOldLineColor;
     996           0 :             SetLineAndFillAttr();
     997             : 
     998           0 :             for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
     999             :             {
    1000           0 :                 const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
    1001           0 :                 WMFRecord_Polygon(Polygon(aPolygon));
    1002           0 :             }
    1003             : 
    1004           0 :             aSrcLineColor = aOldLineColor;
    1005           0 :             aSrcFillColor = aOldFillColor;
    1006           0 :             SetLineAndFillAttr();
    1007           0 :         }
    1008             :     }
    1009           0 : }
    1010             : 
    1011          41 : void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
    1012             : {
    1013          41 :     if( bStatus )
    1014             :     {
    1015          41 :         size_t nACount = rMTF.GetActionSize();
    1016             : 
    1017          41 :         WMFRecord_SetStretchBltMode();
    1018             : 
    1019        3123 :         for( size_t nA = 0; nA < nACount; nA++ )
    1020             :         {
    1021        3082 :             MetaAction* pMA = rMTF.GetAction( nA );
    1022             : 
    1023        3082 :             switch( pMA->GetType() )
    1024             :             {
    1025             :                 case MetaActionType::PIXEL:
    1026             :                 {
    1027           0 :                     const MetaPixelAction* pA = static_cast<const MetaPixelAction *>(pMA);
    1028           0 :                     aSrcLineInfo = LineInfo();
    1029           0 :                     SetLineAndFillAttr();
    1030           0 :                     WMFRecord_SetPixel( pA->GetPoint(), pA->GetColor() );
    1031             :                 }
    1032           0 :                 break;
    1033             : 
    1034             :                 case MetaActionType::POINT:
    1035             :                 {
    1036           0 :                     const MetaPointAction*  pA = static_cast<const MetaPointAction*>(pMA);
    1037           0 :                     const Point&            rPt = pA->GetPoint();
    1038           0 :                     aSrcLineInfo = LineInfo();
    1039           0 :                     SetLineAndFillAttr();
    1040           0 :                     WMFRecord_MoveTo( rPt);
    1041           0 :                     WMFRecord_LineTo( rPt );
    1042             :                 }
    1043           0 :                 break;
    1044             : 
    1045             :                 case MetaActionType::LINE:
    1046             :                 {
    1047           0 :                     const MetaLineAction* pA = static_cast<const MetaLineAction *>(pMA);
    1048           0 :                     if(pA->GetLineInfo().IsDefault())
    1049             :                     {
    1050           0 :                         aSrcLineInfo = pA->GetLineInfo();
    1051           0 :                         SetLineAndFillAttr();
    1052           0 :                         WMFRecord_MoveTo( pA->GetStartPoint() );
    1053           0 :                         WMFRecord_LineTo( pA->GetEndPoint() );
    1054             :                     }
    1055             :                     else
    1056             :                     {
    1057             :                         // LineInfo used; handle Dash/Dot and fat lines
    1058           0 :                         basegfx::B2DPolygon aPolygon;
    1059           0 :                         aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
    1060           0 :                         aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
    1061           0 :                         HandleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
    1062             :                     }
    1063             :                 }
    1064           0 :                 break;
    1065             : 
    1066             :                 case MetaActionType::RECT:
    1067             :                 {
    1068          20 :                     const MetaRectAction* pA = static_cast<const MetaRectAction*>(pMA);
    1069          20 :                     aSrcLineInfo = LineInfo();
    1070          20 :                     SetLineAndFillAttr();
    1071          20 :                     WMFRecord_Rectangle( pA->GetRect() );
    1072             :                 }
    1073          20 :                 break;
    1074             : 
    1075             :                 case MetaActionType::ROUNDRECT:
    1076             :                 {
    1077           0 :                     const MetaRoundRectAction* pA = static_cast<const MetaRoundRectAction*>(pMA);
    1078           0 :                     aSrcLineInfo = LineInfo();
    1079           0 :                     SetLineAndFillAttr();
    1080           0 :                     WMFRecord_RoundRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
    1081             :                 }
    1082           0 :                 break;
    1083             : 
    1084             :                 case MetaActionType::ELLIPSE:
    1085             :                 {
    1086           0 :                     const MetaEllipseAction* pA = static_cast<const MetaEllipseAction*>(pMA);
    1087           0 :                     aSrcLineInfo = LineInfo();
    1088           0 :                     SetLineAndFillAttr();
    1089           0 :                     WMFRecord_Ellipse( pA->GetRect() );
    1090             :                 }
    1091           0 :                 break;
    1092             : 
    1093             :                 case MetaActionType::ARC:
    1094             :                 {
    1095           0 :                     const MetaArcAction* pA = static_cast<const MetaArcAction*>(pMA);
    1096           0 :                     aSrcLineInfo = LineInfo();
    1097           0 :                     SetLineAndFillAttr();
    1098           0 :                     WMFRecord_Arc( pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint() );
    1099             :                 }
    1100           0 :                 break;
    1101             : 
    1102             :                 case MetaActionType::PIE:
    1103             :                 {
    1104           0 :                     const MetaPieAction* pA = static_cast<const MetaPieAction*>(pMA);
    1105           0 :                     aSrcLineInfo = LineInfo();
    1106           0 :                     SetLineAndFillAttr();
    1107           0 :                     WMFRecord_Pie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
    1108             :                 }
    1109           0 :                 break;
    1110             : 
    1111             :                 case MetaActionType::CHORD:
    1112             :                 {
    1113           0 :                     const MetaChordAction* pA = static_cast<const MetaChordAction*>(pMA);
    1114           0 :                     aSrcLineInfo = LineInfo();
    1115           0 :                     SetLineAndFillAttr();
    1116           0 :                     WMFRecord_Chord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
    1117             :                 }
    1118           0 :                 break;
    1119             : 
    1120             :                 case MetaActionType::POLYLINE:
    1121             :                 {
    1122          18 :                     const MetaPolyLineAction* pA = static_cast<const MetaPolyLineAction*>(pMA);
    1123          18 :                     const Polygon&              rPoly = pA->GetPolygon();
    1124             : 
    1125          18 :                     if( rPoly.GetSize() )
    1126             :                     {
    1127          18 :                         if(pA->GetLineInfo().IsDefault())
    1128             :                         {
    1129          18 :                             aSrcLineInfo = pA->GetLineInfo();
    1130          18 :                             SetLineAndFillAttr();
    1131          18 :                             WMFRecord_PolyLine( rPoly );
    1132             :                         }
    1133             :                         else
    1134             :                         {
    1135             :                             // LineInfo used; handle Dash/Dot and fat lines
    1136           0 :                             HandleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
    1137             :                         }
    1138             :                     }
    1139             :                 }
    1140          18 :                 break;
    1141             : 
    1142             :                 case MetaActionType::POLYGON:
    1143             :                 {
    1144           0 :                     const MetaPolygonAction* pA = static_cast<const MetaPolygonAction*>(pMA);
    1145           0 :                     aSrcLineInfo = LineInfo();
    1146           0 :                     SetLineAndFillAttr();
    1147           0 :                     WMFRecord_Polygon( pA->GetPolygon() );
    1148             :                 }
    1149           0 :                 break;
    1150             : 
    1151             :                 case MetaActionType::POLYPOLYGON:
    1152             :                 {
    1153          12 :                     const MetaPolyPolygonAction* pA = static_cast<const MetaPolyPolygonAction*>(pMA);
    1154          12 :                     aSrcLineInfo = LineInfo();
    1155          12 :                     SetLineAndFillAttr();
    1156          12 :                     WMFRecord_PolyPolygon( pA->GetPolyPolygon() );
    1157             :                 }
    1158          12 :                 break;
    1159             : 
    1160             :                 case MetaActionType::TEXTRECT:
    1161             :                 {
    1162           0 :                     const MetaTextRectAction * pA = static_cast<const MetaTextRectAction*>(pMA);
    1163           0 :                     OUString aTemp( pA->GetText() );
    1164           0 :                     aSrcLineInfo = LineInfo();
    1165           0 :                     SetAllAttr();
    1166             : 
    1167           0 :                     Point aPos( pA->GetRect().TopLeft() );
    1168           0 :                     if ( !WMFRecord_Escape_Unicode( aPos, aTemp, NULL ) )
    1169           0 :                         WMFRecord_TextOut( aPos, aTemp );
    1170             :                 }
    1171           0 :                 break;
    1172             : 
    1173             :                 case MetaActionType::TEXT:
    1174             :                 {
    1175           0 :                     const MetaTextAction * pA = static_cast<const MetaTextAction*>(pMA);
    1176           0 :                     OUString aTemp = pA->GetText().copy( pA->GetIndex(), std::min<sal_Int32>(pA->GetText().getLength() - pA->GetIndex(), pA->GetLen()) );
    1177           0 :                     aSrcLineInfo = LineInfo();
    1178           0 :                     SetAllAttr();
    1179           0 :                     if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, NULL ) )
    1180           0 :                         WMFRecord_TextOut( pA->GetPoint(), aTemp );
    1181             :                 }
    1182           0 :                 break;
    1183             : 
    1184             :                 case MetaActionType::TEXTARRAY:
    1185             :                 {
    1186           8 :                     const MetaTextArrayAction* pA = static_cast<const MetaTextArrayAction*>(pMA);
    1187             : 
    1188           8 :                     OUString aTemp = pA->GetText().copy( pA->GetIndex(), std::min<sal_Int32>(pA->GetText().getLength() - pA->GetIndex(), pA->GetLen()) );
    1189           8 :                     aSrcLineInfo = LineInfo();
    1190           8 :                     SetAllAttr();
    1191           8 :                     if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pA->GetDXArray() ) )
    1192           8 :                         WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pA->GetDXArray() );
    1193             :                 }
    1194           8 :                 break;
    1195             : 
    1196             :                 case MetaActionType::STRETCHTEXT:
    1197             :                 {
    1198         344 :                     const MetaStretchTextAction* pA = static_cast<const MetaStretchTextAction *>(pMA);
    1199         344 :                     OUString aTemp = pA->GetText().copy( pA->GetIndex(), std::min<sal_Int32>(pA->GetText().getLength() - pA->GetIndex(), pA->GetLen()) );
    1200             : 
    1201             :                     sal_uInt16 nLen,i;
    1202             :                     sal_Int32 nNormSize;
    1203             : 
    1204         344 :                     pVirDev->SetFont( aSrcFont );
    1205         344 :                     nLen = aTemp.getLength();
    1206         688 :                     boost::scoped_array<long> pDXAry(nLen ? new long[ nLen ] : NULL);
    1207         344 :                     nNormSize = pVirDev->GetTextArray( aTemp, pDXAry.get() );
    1208         344 :                     if (nLen && nNormSize == 0)
    1209             :                     {
    1210             :                         OSL_FAIL("Impossible div by 0 action: MetaStretchTextAction!");
    1211             :                     }
    1212             :                     else
    1213             :                     {
    1214         389 :                         for ( i = 0; i < ( nLen - 1 ); i++ )
    1215          48 :                             pDXAry[ i ] = pDXAry[ i ] * (sal_Int32)pA->GetWidth() / nNormSize;
    1216         341 :                         if ( ( nLen <= 1 ) || ( (sal_Int32)pA->GetWidth() == nNormSize ) )
    1217         318 :                             pDXAry.reset();
    1218         341 :                         aSrcLineInfo = LineInfo();
    1219         341 :                         SetAllAttr();
    1220         341 :                         if ( !WMFRecord_Escape_Unicode( pA->GetPoint(), aTemp, pDXAry.get() ) )
    1221         219 :                             WMFRecord_ExtTextOut( pA->GetPoint(), aTemp, pDXAry.get() );
    1222         344 :                     }
    1223             :                 }
    1224         344 :                 break;
    1225             : 
    1226             :                 case MetaActionType::BMP:
    1227             :                 {
    1228           0 :                     const MetaBmpAction* pA = static_cast<const MetaBmpAction *>(pMA);
    1229           0 :                     WMFRecord_StretchDIB( pA->GetPoint(), pA->GetBitmap().GetSizePixel(), pA->GetBitmap() );
    1230             :                 }
    1231           0 :                 break;
    1232             : 
    1233             :                 case MetaActionType::BMPSCALE:
    1234             :                 {
    1235           1 :                     const MetaBmpScaleAction* pA = static_cast<const MetaBmpScaleAction*>(pMA);
    1236           1 :                     WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
    1237             :                 }
    1238           1 :                 break;
    1239             : 
    1240             :                 case MetaActionType::BMPSCALEPART:
    1241             :                 {
    1242           0 :                     const MetaBmpScalePartAction*   pA = static_cast<const MetaBmpScalePartAction*>(pMA);
    1243           0 :                     Bitmap                          aTmp( pA->GetBitmap() );
    1244             : 
    1245           0 :                     if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
    1246           0 :                         WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aTmp );
    1247             :                 }
    1248           0 :                 break;
    1249             : 
    1250             :                 case MetaActionType::BMPEX:
    1251             :                 {
    1252           0 :                     const MetaBmpExAction*  pA = static_cast<const MetaBmpExAction *>(pMA);
    1253           0 :                     Bitmap                  aBmp( pA->GetBitmapEx().GetBitmap() );
    1254           0 :                     Bitmap                  aMsk( pA->GetBitmapEx().GetMask() );
    1255             : 
    1256           0 :                     if( !!aMsk )
    1257             :                     {
    1258           0 :                         aBmp.Replace( aMsk, COL_WHITE );
    1259           0 :                         aMsk.Invert();
    1260           0 :                         WMFRecord_StretchDIB( pA->GetPoint(), aMsk.GetSizePixel(), aBmp, W_SRCPAINT );
    1261           0 :                         WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp, W_SRCAND );
    1262             :                     }
    1263             :                     else
    1264           0 :                         WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp );
    1265             :                 }
    1266           0 :                 break;
    1267             : 
    1268             :                 case MetaActionType::BMPEXSCALE:
    1269             :                 {
    1270           4 :                     const MetaBmpExScaleAction* pA = static_cast<const MetaBmpExScaleAction*>(pMA);
    1271           4 :                     Bitmap                      aBmp( pA->GetBitmapEx().GetBitmap() );
    1272           8 :                     Bitmap                      aMsk( pA->GetBitmapEx().GetMask() );
    1273             : 
    1274           4 :                     if( !!aMsk )
    1275             :                     {
    1276           4 :                         aBmp.Replace( aMsk, COL_WHITE );
    1277           4 :                         aMsk.Invert();
    1278           4 :                         WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT );
    1279           4 :                         WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND );
    1280             :                     }
    1281             :                     else
    1282           4 :                         WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp );
    1283             :                 }
    1284           4 :                 break;
    1285             : 
    1286             :                 case MetaActionType::BMPEXSCALEPART:
    1287             :                 {
    1288           0 :                     const MetaBmpExScalePartAction* pA = static_cast<const MetaBmpExScalePartAction*>(pMA);
    1289           0 :                     BitmapEx                        aBmpEx( pA->GetBitmapEx() );
    1290           0 :                     aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
    1291           0 :                     Bitmap                          aBmp( aBmpEx.GetBitmap() );
    1292           0 :                     Bitmap                          aMsk( aBmpEx.GetMask() );
    1293             : 
    1294           0 :                     if( !!aMsk )
    1295             :                     {
    1296           0 :                         aBmp.Replace( aMsk, COL_WHITE );
    1297           0 :                         aMsk.Invert();
    1298           0 :                         WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aMsk, W_SRCPAINT );
    1299           0 :                         WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp, W_SRCAND );
    1300             :                     }
    1301             :                     else
    1302           0 :                         WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
    1303             :                 }
    1304           0 :                 break;
    1305             : 
    1306             :                 case MetaActionType::GRADIENT:
    1307             :                 {
    1308           0 :                     const MetaGradientAction*   pA = static_cast<const MetaGradientAction*>(pMA);
    1309           0 :                     GDIMetaFile                 aTmpMtf;
    1310             : 
    1311           0 :                     pVirDev->AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
    1312           0 :                     WriteRecords( aTmpMtf );
    1313             :                 }
    1314           0 :                 break;
    1315             : 
    1316             :                 case MetaActionType::HATCH:
    1317             :                 {
    1318           0 :                     const MetaHatchAction*  pA = static_cast<const MetaHatchAction*>(pMA);
    1319           0 :                     GDIMetaFile             aTmpMtf;
    1320             : 
    1321           0 :                     pVirDev->AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
    1322           0 :                     WriteRecords( aTmpMtf );
    1323             :                 }
    1324           0 :                 break;
    1325             : 
    1326             :                 case MetaActionType::WALLPAPER:
    1327             :                 {
    1328           0 :                     const MetaWallpaperAction*  pA = static_cast<const MetaWallpaperAction*>(pMA);
    1329           0 :                     const Color&                rColor = pA->GetWallpaper().GetColor();
    1330           0 :                     const Color                 aOldLineColor( aSrcLineColor );
    1331           0 :                     const Color                 aOldFillColor( aSrcFillColor );
    1332             : 
    1333           0 :                     aSrcLineColor = rColor;
    1334           0 :                     aSrcFillColor = rColor;
    1335           0 :                     aSrcLineInfo = LineInfo();
    1336           0 :                     SetLineAndFillAttr();
    1337           0 :                     WMFRecord_Rectangle( pA->GetRect() );
    1338           0 :                     aSrcLineColor = aOldLineColor;
    1339           0 :                     aSrcFillColor = aOldFillColor;
    1340             :                 }
    1341           0 :                 break;
    1342             : 
    1343             :                 case MetaActionType::ISECTRECTCLIPREGION:
    1344             :                 {
    1345          34 :                     const MetaISectRectClipRegionAction* pA = static_cast<const MetaISectRectClipRegionAction*>(pMA);
    1346          34 :                     WMFRecord_IntersectClipRect( pA->GetRect() );
    1347             :                 }
    1348          34 :                 break;
    1349             : 
    1350             :                 case MetaActionType::LINECOLOR:
    1351             :                 {
    1352          68 :                     const MetaLineColorAction* pA = static_cast<const MetaLineColorAction*>(pMA);
    1353             : 
    1354          68 :                     if( pA->IsSetting() )
    1355          36 :                         aSrcLineColor = pA->GetColor();
    1356             :                     else
    1357          32 :                         aSrcLineColor = Color( COL_TRANSPARENT );
    1358             :                 }
    1359          68 :                 break;
    1360             : 
    1361             :                 case MetaActionType::FILLCOLOR:
    1362             :                 {
    1363          50 :                     const MetaFillColorAction* pA = static_cast<const MetaFillColorAction*>(pMA);
    1364             : 
    1365          50 :                     if( pA->IsSetting() )
    1366          31 :                         aSrcFillColor = pA->GetColor();
    1367             :                     else
    1368          19 :                         aSrcFillColor = Color( COL_TRANSPARENT );
    1369             :                 }
    1370          50 :                 break;
    1371             : 
    1372             :                 case MetaActionType::TEXTCOLOR:
    1373             :                 {
    1374         375 :                     const MetaTextColorAction* pA = static_cast<const MetaTextColorAction*>(pMA);
    1375         375 :                     aSrcTextColor = pA->GetColor();
    1376             :                 }
    1377         375 :                 break;
    1378             : 
    1379             :                 case MetaActionType::TEXTFILLCOLOR:
    1380             :                 {
    1381         371 :                     const MetaTextFillColorAction* pA = static_cast<const MetaTextFillColorAction*>(pMA);
    1382         371 :                     if( pA->IsSetting() )
    1383           0 :                         aSrcFont.SetFillColor( pA->GetColor() );
    1384             :                     else
    1385         371 :                         aSrcFont.SetFillColor( Color( COL_TRANSPARENT ) );
    1386             :                 }
    1387         371 :                 break;
    1388             : 
    1389             :                 case MetaActionType::TEXTALIGN:
    1390             :                 {
    1391         370 :                     const MetaTextAlignAction* pA = static_cast<const MetaTextAlignAction*>(pMA);
    1392         370 :                     eSrcTextAlign = pA->GetTextAlign();
    1393             :                 }
    1394         370 :                 break;
    1395             : 
    1396             :                 case MetaActionType::MAPMODE:
    1397             :                 {
    1398           0 :                     const MetaMapModeAction* pA = static_cast<const MetaMapModeAction*>(pMA);
    1399             : 
    1400           0 :                     if (aSrcMapMode!=pA->GetMapMode())
    1401             :                     {
    1402           0 :                         if( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
    1403             :                         {
    1404           0 :                             MapMode aMM = pA->GetMapMode();
    1405           0 :                             Fraction aScaleX = aMM.GetScaleX();
    1406           0 :                             Fraction aScaleY = aMM.GetScaleY();
    1407             : 
    1408           0 :                             Point aOrigin = aSrcMapMode.GetOrigin();
    1409           0 :                             BigInt aX( aOrigin.X() );
    1410           0 :                             aX *= BigInt( aScaleX.GetDenominator() );
    1411           0 :                             if( aOrigin.X() >= 0 )
    1412           0 :                                 if( aScaleX.GetNumerator() >= 0 )
    1413           0 :                                     aX += BigInt( aScaleX.GetNumerator()/2 );
    1414             :                                 else
    1415           0 :                                     aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
    1416             :                             else
    1417           0 :                                 if( aScaleX.GetNumerator() >= 0 )
    1418           0 :                                     aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
    1419             :                                 else
    1420           0 :                                     aX += BigInt( aScaleX.GetNumerator()/2 );
    1421           0 :                             aX /= BigInt( aScaleX.GetNumerator() );
    1422           0 :                             aOrigin.X() = (long)aX + aMM.GetOrigin().X();
    1423           0 :                             BigInt aY( aOrigin.Y() );
    1424           0 :                             aY *= BigInt( aScaleY.GetDenominator() );
    1425           0 :                             if( aOrigin.Y() >= 0 )
    1426           0 :                                 if( aScaleY.GetNumerator() >= 0 )
    1427           0 :                                     aY += BigInt( aScaleY.GetNumerator()/2 );
    1428             :                                 else
    1429           0 :                                     aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
    1430             :                             else
    1431           0 :                                 if( aScaleY.GetNumerator() >= 0 )
    1432           0 :                                     aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
    1433             :                                 else
    1434           0 :                                     aY += BigInt( aScaleY.GetNumerator()/2 );
    1435           0 :                             aY /= BigInt( aScaleY.GetNumerator() );
    1436           0 :                             aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
    1437           0 :                             aSrcMapMode.SetOrigin( aOrigin );
    1438             : 
    1439           0 :                             aScaleX *= aSrcMapMode.GetScaleX();
    1440           0 :                             aScaleY *= aSrcMapMode.GetScaleY();
    1441           0 :                             aSrcMapMode.SetScaleX( aScaleX );
    1442           0 :                             aSrcMapMode.SetScaleY( aScaleY );
    1443             :                         }
    1444             :                         else
    1445           0 :                             aSrcMapMode=pA->GetMapMode();
    1446             :                     }
    1447             :                 }
    1448           0 :                 break;
    1449             : 
    1450             :                 case MetaActionType::FONT:
    1451             :                 {
    1452         370 :                     const MetaFontAction* pA = static_cast<const MetaFontAction*>(pMA);
    1453         370 :                     aSrcFont = pA->GetFont();
    1454             : 
    1455         740 :                     if ( (aSrcFont.GetCharSet() == RTL_TEXTENCODING_DONTKNOW)
    1456         370 :                          || (aSrcFont.GetCharSet() == RTL_TEXTENCODING_UNICODE) )
    1457             :                     {
    1458         369 :                         aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
    1459             :                     }
    1460         370 :                     eSrcTextAlign = aSrcFont.GetAlign();
    1461         370 :                     aSrcTextColor = aSrcFont.GetColor();
    1462         370 :                     aSrcFont.SetAlign( ALIGN_BASELINE );
    1463         370 :                     aSrcFont.SetColor( COL_WHITE );
    1464             :                 }
    1465         370 :                 break;
    1466             : 
    1467             :                 case MetaActionType::PUSH:
    1468             :                 {
    1469         398 :                     const MetaPushAction* pA = static_cast<const MetaPushAction*>(pMA);
    1470             : 
    1471         398 :                     WMFWriterAttrStackMember* pAt = new WMFWriterAttrStackMember;
    1472         398 :                     pAt->nFlags = pA->GetFlags();
    1473         398 :                     pAt->aClipRegion = aSrcClipRegion;
    1474         398 :                     pAt->aLineColor=aSrcLineColor;
    1475         398 :                     pAt->aFillColor=aSrcFillColor;
    1476         398 :                     pAt->eRasterOp=eSrcRasterOp;
    1477         398 :                     pAt->aFont=aSrcFont;
    1478         398 :                     pAt->eTextAlign=eSrcTextAlign;
    1479         398 :                     pAt->aTextColor=aSrcTextColor;
    1480         398 :                     pAt->aMapMode=aSrcMapMode;
    1481         398 :                     pAt->aLineInfo=aDstLineInfo;
    1482         398 :                     pAt->pSucc=pAttrStack;
    1483         398 :                     pAttrStack=pAt;
    1484             : 
    1485         398 :                     SetAllAttr();           // update ( now all source attributes are equal to the destination attributes )
    1486         398 :                     WMFRecord_SaveDC();
    1487             : 
    1488             :                 }
    1489         398 :                 break;
    1490             : 
    1491             :                 case MetaActionType::POP:
    1492             :                 {
    1493         398 :                     WMFWriterAttrStackMember * pAt=pAttrStack;
    1494             : 
    1495         398 :                     if( pAt )
    1496             :                     {
    1497         398 :                         aDstLineInfo = pAt->aLineInfo;
    1498         398 :                         aDstLineColor = pAt->aLineColor;
    1499         398 :                         if ( pAt->nFlags & PushFlags::LINECOLOR )
    1500         393 :                             aSrcLineColor = pAt->aLineColor;
    1501         398 :                         aDstFillColor = pAt->aFillColor;
    1502         398 :                         if ( pAt->nFlags & PushFlags::FILLCOLOR )
    1503         393 :                             aSrcFillColor = pAt->aFillColor;
    1504         398 :                         eDstROP2 = pAt->eRasterOp;
    1505         398 :                         if ( pAt->nFlags & PushFlags::RASTEROP )
    1506          30 :                             eSrcRasterOp = pAt->eRasterOp;
    1507         398 :                         aDstFont = pAt->aFont;
    1508         398 :                         if ( pAt->nFlags & PushFlags::FONT )
    1509         393 :                             aSrcFont = pAt->aFont;
    1510         398 :                         eDstTextAlign = pAt->eTextAlign;
    1511         398 :                         if ( pAt->nFlags & ( PushFlags::FONT | PushFlags::TEXTALIGN ) )
    1512         393 :                             eSrcTextAlign = pAt->eTextAlign;
    1513         398 :                         aDstTextColor = pAt->aTextColor;
    1514         398 :                         if ( pAt->nFlags & ( PushFlags::FONT | PushFlags::TEXTCOLOR ) )
    1515         393 :                             aSrcTextColor = pAt->aTextColor;
    1516         398 :                         if ( pAt->nFlags & PushFlags::MAPMODE )
    1517         393 :                             aSrcMapMode = pAt->aMapMode;
    1518         398 :                         aDstClipRegion = pAt->aClipRegion;
    1519         398 :                         if ( pAt->nFlags & PushFlags::CLIPREGION )
    1520          35 :                             aSrcClipRegion = pAt->aClipRegion;
    1521             : 
    1522         398 :                         WMFRecord_RestoreDC();
    1523         398 :                         pAttrStack = pAt->pSucc;
    1524         398 :                         delete pAt;
    1525             :                     }
    1526             :                 }
    1527         398 :                 break;
    1528             : 
    1529             :                 case MetaActionType::EPS :
    1530             :                 {
    1531           0 :                     const MetaEPSAction* pA = static_cast<const MetaEPSAction*>(pMA);
    1532           0 :                     const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
    1533             : 
    1534           0 :                     size_t nCount = aGDIMetaFile.GetActionSize();
    1535           0 :                     for ( size_t i = 0; i < nCount; i++ )
    1536             :                     {
    1537           0 :                         const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
    1538           0 :                         if ( pMetaAct->GetType() == MetaActionType::BMPSCALE )
    1539             :                         {
    1540           0 :                             const MetaBmpScaleAction* pBmpScaleAction = static_cast<const MetaBmpScaleAction*>(pMetaAct);
    1541           0 :                             WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
    1542           0 :                             break;
    1543             :                         }
    1544           0 :                     }
    1545             :                 }
    1546           0 :                 break;
    1547             : 
    1548             :                 case MetaActionType::RASTEROP:
    1549             :                 {
    1550           7 :                     const MetaRasterOpAction* pA = static_cast<const MetaRasterOpAction*>(pMA);
    1551           7 :                     eSrcRasterOp=pA->GetRasterOp();
    1552             :                 }
    1553           7 :                 break;
    1554             : 
    1555             :                 case MetaActionType::Transparent:
    1556             :                 {
    1557           0 :                     aSrcLineInfo = LineInfo();
    1558           0 :                     SetLineAndFillAttr();
    1559           0 :                     WMFRecord_PolyPolygon( static_cast<const MetaTransparentAction*>(pMA)->GetPolyPolygon() );
    1560             :                 }
    1561           0 :                 break;
    1562             : 
    1563             :                 case MetaActionType::FLOATTRANSPARENT:
    1564             :                 {
    1565           0 :                     const MetaFloatTransparentAction* pA = static_cast<const MetaFloatTransparentAction*>(pMA);
    1566             : 
    1567           0 :                     GDIMetaFile     aTmpMtf( pA->GetGDIMetaFile() );
    1568           0 :                     Point           aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
    1569           0 :                     const Size      aSrcSize( aTmpMtf.GetPrefSize() );
    1570           0 :                     const Point     aDestPt( pA->GetPoint() );
    1571           0 :                     const Size      aDestSize( pA->GetSize() );
    1572           0 :                     const double    fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
    1573           0 :                     const double    fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
    1574             :                     long            nMoveX, nMoveY;
    1575             : 
    1576           0 :                     aSrcLineInfo = LineInfo();
    1577           0 :                     SetAllAttr();
    1578             : 
    1579           0 :                     if( fScaleX != 1.0 || fScaleY != 1.0 )
    1580             :                     {
    1581           0 :                         aTmpMtf.Scale( fScaleX, fScaleY );
    1582           0 :                         aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
    1583             :                     }
    1584             : 
    1585           0 :                     nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
    1586             : 
    1587           0 :                     if( nMoveX || nMoveY )
    1588           0 :                         aTmpMtf.Move( nMoveX, nMoveY );
    1589             : 
    1590           0 :                     WriteRecords( aTmpMtf );
    1591             :                 }
    1592           0 :                 break;
    1593             : 
    1594             :                 case( MetaActionType::LAYOUTMODE ):
    1595             :                 {
    1596          60 :                     ComplexTextLayoutMode nLayoutMode = static_cast<const MetaLayoutModeAction*>(pMA)->GetLayoutMode();
    1597          60 :                     eSrcHorTextAlign = 0; // TA_LEFT
    1598          60 :                     if ((nLayoutMode & TEXT_LAYOUT_BIDI_RTL) != TEXT_LAYOUT_DEFAULT)
    1599             :                     {
    1600           0 :                         eSrcHorTextAlign = W_TA_RIGHT | W_TA_RTLREADING;
    1601             :                     }
    1602          60 :                     if ((nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_RIGHT) != TEXT_LAYOUT_DEFAULT)
    1603           0 :                         eSrcHorTextAlign |= W_TA_RIGHT;
    1604          60 :                     else if ((nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT) != TEXT_LAYOUT_DEFAULT)
    1605           0 :                         eSrcHorTextAlign &= ~W_TA_RIGHT;
    1606          60 :                     break;
    1607             :                 }
    1608             : 
    1609             :                 // Unsupported Actions
    1610             :                 case MetaActionType::MASK:
    1611             :                 case MetaActionType::MASKSCALE:
    1612             :                 case MetaActionType::MASKSCALEPART:
    1613             :                 {
    1614             :                     OSL_FAIL( "Unsupported action: MetaMask...Action!" );
    1615             :                 }
    1616           0 :                 break;
    1617             : 
    1618             :                 case MetaActionType::CLIPREGION:
    1619           0 :                 break;
    1620             : 
    1621             :                 case MetaActionType::ISECTREGIONCLIPREGION:
    1622             :                 {
    1623             :                     OSL_FAIL( "Unsupported action: MetaISectRegionClipRegionAction!" );
    1624             :                 }
    1625           0 :                 break;
    1626             : 
    1627             :                 case MetaActionType::MOVECLIPREGION:
    1628             :                 {
    1629             :                     OSL_FAIL( "Unsupported action: MetaMoveClipRegionAction!" );
    1630             :                 }
    1631           0 :                 break;
    1632             : 
    1633             :                 default:
    1634             :                 {
    1635             :                     OSL_FAIL(OStringBuffer(
    1636             :                         "WMFWriter::WriteRecords: unsupported MetaAction #" ).
    1637             :                          append(static_cast<sal_Int32>(pMA->GetType())).getStr());
    1638             :                 }
    1639         174 :                 break;
    1640             :           }
    1641             : 
    1642        3082 :           nWrittenActions++;
    1643        3082 :           MayCallback();
    1644             : 
    1645        3082 :           if (pWMF->GetError())
    1646           0 :             bStatus=false;
    1647             : 
    1648        3082 :           if(!bStatus)
    1649           0 :             break;
    1650             :         }
    1651             :     }
    1652          41 : }
    1653             : 
    1654          41 : void WMFWriter::WriteHeader( const GDIMetaFile &, bool bPlaceable )
    1655             : {
    1656          41 :     if( bPlaceable )
    1657             :     {
    1658             :         sal_uInt16  nCheckSum, nValue;
    1659          35 :         Size    aSize( OutputDevice::LogicToLogic(Size(1,1),MapMode(MAP_INCH), aTargetMapMode) );
    1660          35 :         sal_uInt16  nUnitsPerInch = (sal_uInt16) ( ( aSize.Width() + aSize.Height() ) >> 1 );
    1661             : 
    1662          35 :         nCheckSum=0;
    1663          35 :         nValue=0xcdd7;                              nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1664          35 :         nValue=0x9ac6;                              nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1665          35 :         nValue=0x0000;                              nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1666          35 :         nValue=0x0000;                              nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1667          35 :         nValue=0x0000;                              nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1668          35 :         nValue=(sal_uInt16) aTargetSize.Width();        nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1669          35 :         nValue=(sal_uInt16) aTargetSize.Height();       nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1670          35 :         nValue=nUnitsPerInch;                       nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1671          35 :         nValue=0x0000;                              nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1672          35 :         nValue=0x0000;                              nCheckSum^=nValue; pWMF->WriteUInt16( nValue );
    1673          35 :         pWMF->WriteUInt16( nCheckSum );
    1674             :     }
    1675             : 
    1676          41 :     nMetafileHeaderPos=pWMF->Tell();
    1677          41 :     pWMF->WriteUInt16( 0x0001 )           // type: file
    1678          41 :          .WriteUInt16( 0x0009 )           // header length in words
    1679          41 :          .WriteUInt16( 0x0300 )           // Version as BCD number
    1680          41 :          .WriteUInt32( 0x00000000 )      // file length (without 1st header), is later corrected by UpdateHeader()
    1681          41 :          .WriteUInt16( MAXOBJECTHANDLES ) // maxmimum number of simultaneous objects
    1682          41 :          .WriteUInt32( 0x00000000 )      // maximum record length, is later corrected by UpdateHeader()
    1683          41 :          .WriteUInt16( 0x0000 );          // reserved
    1684          41 : }
    1685             : 
    1686          41 : void WMFWriter::UpdateHeader()
    1687             : {
    1688             :     sal_uLong nPos;
    1689             :     sal_uInt32 nFileSize;
    1690             : 
    1691          41 :     nPos=pWMF->Tell();                 // endposition = total size of file
    1692          41 :     nFileSize=nPos-nMetafileHeaderPos; // subtract size of 1st header
    1693          41 :     if ((nFileSize&1)!=0) {            // if needed round to words
    1694           0 :         pWMF->WriteUChar( 0 );
    1695           0 :         nPos++;
    1696           0 :         nFileSize++;
    1697             :     }
    1698          41 :     nFileSize>>=1;                    // convert to number of words
    1699          41 :     pWMF->Seek(nMetafileHeaderPos+6); // to filesize entry in second header
    1700          41 :     pWMF->WriteUInt32( nFileSize );               // rectify file size
    1701          41 :     pWMF->SeekRel(2);                 // to max-recond-length-entry in second header
    1702          41 :     pWMF->WriteUInt32( nMaxRecordSize );          // and rectify
    1703          41 :     pWMF->Seek(nPos);
    1704          41 : }
    1705             : 
    1706          41 : bool WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream,
    1707             :                             FilterConfigItem* pFConfigItem, bool bPlaceable )
    1708             : {
    1709             :     WMFWriterAttrStackMember * pAt;
    1710             : 
    1711          41 :     bEmbedEMF = true;
    1712          41 :     bStatus=true;
    1713          41 :     pVirDev = VclPtr<VirtualDevice>::Create();
    1714             : 
    1715          41 :     if (pFConfigItem)
    1716             :     {
    1717          35 :         xStatusIndicator = pFConfigItem->GetStatusIndicator();
    1718          35 :         if ( xStatusIndicator.is() )
    1719             :         {
    1720           0 :             OUString aMsg;
    1721           0 :             xStatusIndicator->start( aMsg, 100 );
    1722             :         }
    1723             :     }
    1724          41 :     nLastPercent=0;
    1725             : 
    1726          41 :     pWMF=&rTargetStream;
    1727          41 :     pWMF->SetEndian(SvStreamEndian::LITTLE);
    1728             : 
    1729          41 :     nMaxRecordSize=0;
    1730             : 
    1731          41 :     aSrcMapMode=rMTF.GetPrefMapMode();
    1732             : 
    1733          41 :     if( bPlaceable )
    1734             :     {
    1735          35 :         aTargetMapMode = aSrcMapMode;
    1736          35 :         aTargetSize = rMTF.GetPrefSize();
    1737          35 :         sal_uInt16 nTargetDivisor = CalcSaveTargetMapMode(aTargetMapMode, aTargetSize);
    1738          35 :         aTargetSize.Width() /= nTargetDivisor;
    1739          35 :         aTargetSize.Height() /= nTargetDivisor;
    1740             :     }
    1741             :     else
    1742             :     {
    1743           6 :         aTargetMapMode = MapMode( MAP_INCH );
    1744             : 
    1745           6 :         const long      nUnit = pVirDev->LogicToPixel( Size( 1, 1 ), aTargetMapMode ).Width();
    1746           6 :         const Fraction  aFrac( 1, nUnit );
    1747             : 
    1748           6 :         aTargetMapMode.SetScaleX( aFrac );
    1749           6 :         aTargetMapMode.SetScaleY( aFrac );
    1750           6 :         aTargetSize = OutputDevice::LogicToLogic( rMTF.GetPrefSize(), aSrcMapMode, aTargetMapMode );
    1751             :     }
    1752             : 
    1753          41 :     pVirDev->SetMapMode( aTargetMapMode );
    1754             : 
    1755          41 :     pAttrStack=NULL;
    1756             : 
    1757         697 :     for (sal_uInt16 i=0; i<MAXOBJECTHANDLES; i++)
    1758         656 :         bHandleAllocated[i]=false;
    1759             : 
    1760          41 :     nDstPenHandle=0xffff;
    1761          41 :     nDstFontHandle=0xffff;
    1762          41 :     nDstBrushHandle=0xffff;
    1763             : 
    1764          41 :     nNumberOfActions=0;
    1765          41 :     nNumberOfBitmaps=0;
    1766          41 :     nWrittenActions=0;
    1767          41 :     nWrittenBitmaps=0;
    1768          41 :     nActBitmapPercent=0;
    1769             : 
    1770          41 :     CountActionsAndBitmaps(rMTF);
    1771             : 
    1772          41 :     WriteHeader(rMTF,bPlaceable);
    1773          41 :     if( bEmbedEMF )
    1774          41 :         WriteEmbeddedEMF( rMTF );
    1775          41 :     WMFRecord_SetWindowOrg(Point(0,0));
    1776          41 :     WMFRecord_SetWindowExt(rMTF.GetPrefSize());
    1777          41 :     WMFRecord_SetBkMode( true );
    1778             : 
    1779          41 :     eDstROP2 = eSrcRasterOp = ROP_OVERPAINT;
    1780          41 :     WMFRecord_SetROP2(eDstROP2);
    1781             : 
    1782          41 :     aDstLineInfo = LineInfo();
    1783          41 :     aDstLineColor = aSrcLineColor = Color( COL_BLACK );
    1784          41 :     CreateSelectDeletePen( aDstLineColor, aDstLineInfo );
    1785             : 
    1786          41 :     aDstFillColor = aSrcFillColor = Color( COL_WHITE );
    1787          41 :     CreateSelectDeleteBrush( aDstFillColor );
    1788             : 
    1789          41 :     aDstClipRegion = aSrcClipRegion = vcl::Region();
    1790          41 :     bDstIsClipping = bSrcIsClipping = false;
    1791             : 
    1792          41 :     vcl::Font aFont;
    1793          41 :     aFont.SetCharSet( GetExtendedTextEncoding( RTL_TEXTENCODING_MS_1252 ) );
    1794          41 :     aFont.SetColor( Color( COL_WHITE ) );
    1795          41 :     aFont.SetAlign( ALIGN_BASELINE );
    1796          41 :     aDstFont = aSrcFont = aFont;
    1797          41 :     CreateSelectDeleteFont(aDstFont);
    1798             : 
    1799          41 :     eDstTextAlign = eSrcTextAlign = ALIGN_BASELINE;
    1800          41 :     eDstHorTextAlign = eSrcHorTextAlign = W_TA_LEFT;
    1801          41 :     WMFRecord_SetTextAlign( eDstTextAlign, eDstHorTextAlign );
    1802             : 
    1803          41 :     aDstTextColor = aSrcTextColor = Color( COL_WHITE );
    1804          41 :     WMFRecord_SetTextColor(aDstTextColor);
    1805             : 
    1806             :     // Write records
    1807          41 :     WriteRecords(rMTF);
    1808             : 
    1809          41 :     WMFRecord_EndOfFile();
    1810          41 :     UpdateHeader();
    1811             : 
    1812          82 :     while(pAttrStack)
    1813             :     {
    1814           0 :         pAt=pAttrStack;
    1815           0 :         pAttrStack=pAt->pSucc;
    1816           0 :         delete pAt;
    1817             :     }
    1818             : 
    1819          41 :     pVirDev.disposeAndClear();
    1820             : 
    1821          41 :     if ( xStatusIndicator.is() )
    1822           0 :         xStatusIndicator->end();
    1823             : 
    1824          41 :     return bStatus;
    1825             : }
    1826             : 
    1827          35 : sal_uInt16 WMFWriter::CalcSaveTargetMapMode(MapMode& rMapMode,
    1828             :                                         const Size& rPrefSize)
    1829             : {
    1830          35 :     Fraction    aDivFrac(2, 1);
    1831          35 :     sal_uInt16      nDivisor = 1;
    1832             : 
    1833          35 :     Size aSize = OutputDevice::LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
    1834             : 
    1835          70 :     while( nDivisor <= 64 && (aSize.Width() > 32767 || aSize.Height() > 32767) )
    1836             :     {
    1837           0 :         Fraction aFrac = rMapMode.GetScaleX();
    1838             : 
    1839           0 :         aFrac *= aDivFrac;
    1840           0 :         rMapMode.SetScaleX(aFrac);
    1841           0 :         aFrac = rMapMode.GetScaleY();
    1842           0 :         aFrac *= aDivFrac;
    1843           0 :         rMapMode.SetScaleY(aFrac);
    1844           0 :         nDivisor <<= 1;
    1845           0 :         aSize = OutputDevice::LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
    1846           0 :     }
    1847             : 
    1848          35 :     return nDivisor;
    1849             : }
    1850             : 
    1851          41 : void WMFWriter::WriteEmbeddedEMF( const GDIMetaFile& rMTF )
    1852             : {
    1853          41 :     SvMemoryStream aStream;
    1854          82 :     EMFWriter aEMFWriter(aStream);
    1855             : 
    1856          41 :     if( aEMFWriter.WriteEMF( rMTF ) )
    1857             :     {
    1858          41 :         sal_Size nTotalSize = aStream.Tell();
    1859          41 :         if( nTotalSize > SAL_MAX_UINT32 )
    1860          41 :             return;
    1861          41 :         aStream.Seek( 0 );
    1862          41 :         sal_uInt32 nRemainingSize = static_cast< sal_uInt32 >( nTotalSize );
    1863          41 :         sal_uInt32 nRecCounts = ( (nTotalSize - 1) / 0x2000 ) + 1;
    1864          41 :         sal_uInt16 nCheckSum = 0, nWord;
    1865             : 
    1866          41 :         sal_uInt32 nPos = 0;
    1867             : 
    1868     1640116 :         while( nPos + 1 < nTotalSize )
    1869             :         {
    1870     1640034 :             aStream.ReadUInt16( nWord );
    1871     1640034 :             nCheckSum ^= nWord;
    1872     1640034 :             nPos += 2;
    1873             :         }
    1874             : 
    1875          41 :         nCheckSum = static_cast< sal_uInt16 >( nCheckSum * -1 );
    1876             : 
    1877          41 :         aStream.Seek( 0 );
    1878         506 :         while( nRemainingSize > 0 )
    1879             :         {
    1880             :             sal_uInt32 nCurSize;
    1881         424 :             if( nRemainingSize > 0x2000 )
    1882             :             {
    1883         383 :                 nCurSize = 0x2000;
    1884         383 :                 nRemainingSize -= 0x2000;
    1885             :             }
    1886             :             else
    1887             :             {
    1888          41 :                 nCurSize = nRemainingSize;
    1889          41 :                 nRemainingSize = 0;
    1890             :             }
    1891             :             WriteEMFRecord( aStream,
    1892             :                             nCurSize,
    1893             :                             nRemainingSize,
    1894             :                             nTotalSize,
    1895             :                             nRecCounts,
    1896         424 :                             nCheckSum );
    1897         424 :             nCheckSum = 0;
    1898             :         }
    1899          41 :     }
    1900             : }
    1901             : 
    1902         424 : void WMFWriter::WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize, sal_uInt32 nRemainingSize,
    1903             :                 sal_uInt32 nTotalSize, sal_uInt32 nRecCounts, sal_uInt16 nCheckSum )
    1904             : {
    1905             :    // according to http://msdn.microsoft.com/en-us/library/dd366152%28PROT.13%29.aspx
    1906         424 :    WriteRecordHeader( 0, W_META_ESCAPE );
    1907         424 :    pWMF->WriteUInt16( W_MFCOMMENT )         // same as META_ESCAPE_ENHANCED_METAFILE
    1908         848 :          .WriteUInt16( nCurSize + 34 )     // we will always have a 34 byte escape header:
    1909         424 :          .WriteUInt32( 0x43464D57 )        // WMFC
    1910         424 :          .WriteUInt32( 0x00000001 )        // Comment type
    1911         424 :          .WriteUInt32( 0x00010000 )        // version
    1912         848 :          .WriteUInt16( nCheckSum )                      // check sum
    1913         424 :          .WriteUInt32( 0 )                 // flags = 0
    1914         424 :          .WriteUInt32( nRecCounts )                     // total number of records
    1915         424 :          .WriteUInt32( nCurSize )                       // size of this record's data
    1916         424 :          .WriteUInt32( nRemainingSize )                 // remaining size of data in following records, missing in MSDN documentation
    1917         424 :          .WriteUInt32( nTotalSize );                    // total size of EMF stream
    1918             : 
    1919         424 :    pWMF->Write( static_cast< const sal_Char* >( rStream.GetData() ) + rStream.Tell(), nCurSize );
    1920         424 :    rStream.SeekRel( nCurSize );
    1921         424 :    UpdateRecordHeader();
    1922        1225 : }
    1923             : 
    1924             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11