LCOV - code coverage report
Current view: top level - vcl/source/filter/wmf - wmfwr.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1063 0.0 %
Date: 2014-04-14 Functions: 0 61 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10