LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/filter/wmf - emfwr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 370 769 48.1 %
Date: 2012-12-27 Functions: 23 32 71.9 %
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 "emfwr.hxx"
      21             : #include <rtl/strbuf.hxx>
      22             : #include <tools/helpers.hxx>
      23             : #include <basegfx/polygon/b2dpolygon.hxx>
      24             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      25             : #include <vcl/lineinfo.hxx>
      26             : 
      27             : // -----------
      28             : // - Defines -
      29             : // -----------
      30             : 
      31             : #define WIN_EMR_HEADER                      1
      32             : #define WIN_EMR_POLYBEZIER                  2
      33             : #define WIN_EMR_POLYGON                     3
      34             : #define WIN_EMR_POLYLINE                    4
      35             : #define WIN_EMR_POLYBEZIERTO                5
      36             : #define WIN_EMR_POLYLINETO                  6
      37             : #define WIN_EMR_POLYPOLYLINE                7
      38             : #define WIN_EMR_POLYPOLYGON                 8
      39             : #define WIN_EMR_SETWINDOWEXTEX              9
      40             : #define WIN_EMR_SETWINDOWORGEX              10
      41             : #define WIN_EMR_SETVIEWPORTEXTEX            11
      42             : #define WIN_EMR_SETVIEWPORTORGEX            12
      43             : #define WIN_EMR_SETBRUSHORGEX               13
      44             : #define WIN_EMR_EOF                         14
      45             : #define WIN_EMR_SETPIXELV                   15
      46             : #define WIN_EMR_SETMAPPERFLAGS              16
      47             : #define WIN_EMR_SETMAPMODE                  17
      48             : #define WIN_EMR_SETBKMODE                   18
      49             : #define WIN_EMR_SETPOLYFILLMODE             19
      50             : #define WIN_EMR_SETROP2                     20
      51             : #define WIN_EMR_SETSTRETCHBLTMODE           21
      52             : #define WIN_EMR_SETTEXTALIGN                22
      53             : #define WIN_EMR_SETCOLORADJUSTMENT          23
      54             : #define WIN_EMR_SETTEXTCOLOR                24
      55             : #define WIN_EMR_SETBKCOLOR                  25
      56             : #define WIN_EMR_OFFSETCLIPRGN               26
      57             : #define WIN_EMR_MOVETOEX                    27
      58             : #define WIN_EMR_SETMETARGN                  28
      59             : #define WIN_EMR_EXCLUDECLIPRECT             29
      60             : #define WIN_EMR_INTERSECTCLIPRECT           30
      61             : #define WIN_EMR_SCALEVIEWPORTEXTEX          31
      62             : #define WIN_EMR_SCALEWINDOWEXTEX            32
      63             : #define WIN_EMR_SAVEDC                      33
      64             : #define WIN_EMR_RESTOREDC                   34
      65             : #define WIN_EMR_SETWORLDTRANSFORM           35
      66             : #define WIN_EMR_MODIFYWORLDTRANSFORM        36
      67             : #define WIN_EMR_SELECTOBJECT                37
      68             : #define WIN_EMR_CREATEPEN                   38
      69             : #define WIN_EMR_CREATEBRUSHINDIRECT         39
      70             : #define WIN_EMR_DELETEOBJECT                40
      71             : #define WIN_EMR_ANGLEARC                    41
      72             : #define WIN_EMR_ELLIPSE                     42
      73             : #define WIN_EMR_RECTANGLE                   43
      74             : #define WIN_EMR_ROUNDRECT                   44
      75             : #define WIN_EMR_ARC                         45
      76             : #define WIN_EMR_CHORD                       46
      77             : #define WIN_EMR_PIE                         47
      78             : #define WIN_EMR_SELECTPALETTE               48
      79             : #define WIN_EMR_CREATEPALETTE               49
      80             : #define WIN_EMR_SETPALETTEENTRIES           50
      81             : #define WIN_EMR_RESIZEPALETTE               51
      82             : #define WIN_EMR_REALIZEPALETTE              52
      83             : #define WIN_EMR_EXTFLOODFILL                53
      84             : #define WIN_EMR_LINETO                      54
      85             : #define WIN_EMR_ARCTO                       55
      86             : #define WIN_EMR_POLYDRAW                    56
      87             : #define WIN_EMR_SETARCDIRECTION             57
      88             : #define WIN_EMR_SETMITERLIMIT               58
      89             : #define WIN_EMR_BEGINPATH                   59
      90             : #define WIN_EMR_ENDPATH                     60
      91             : #define WIN_EMR_CLOSEFIGURE                 61
      92             : #define WIN_EMR_FILLPATH                    62
      93             : #define WIN_EMR_STROKEANDFILLPATH           63
      94             : #define WIN_EMR_STROKEPATH                  64
      95             : #define WIN_EMR_FLATTENPATH                 65
      96             : #define WIN_EMR_WIDENPATH                   66
      97             : #define WIN_EMR_SELECTCLIPPATH              67
      98             : #define WIN_EMR_ABORTPATH                   68
      99             : 
     100             : #define WIN_EMR_GDICOMMENT                  70
     101             : #define WIN_EMR_FILLRGN                     71
     102             : #define WIN_EMR_FRAMERGN                    72
     103             : #define WIN_EMR_INVERTRGN                   73
     104             : #define WIN_EMR_PAINTRGN                    74
     105             : #define WIN_EMR_EXTSELECTCLIPRGN            75
     106             : #define WIN_EMR_BITBLT                      76
     107             : #define WIN_EMR_STRETCHBLT                  77
     108             : #define WIN_EMR_MASKBLT                     78
     109             : #define WIN_EMR_PLGBLT                      79
     110             : #define WIN_EMR_SETDIBITSTODEVICE           80
     111             : #define WIN_EMR_STRETCHDIBITS               81
     112             : #define WIN_EMR_EXTCREATEFONTINDIRECTW      82
     113             : #define WIN_EMR_EXTTEXTOUTA                 83
     114             : #define WIN_EMR_EXTTEXTOUTW                 84
     115             : #define WIN_EMR_POLYBEZIER16                85
     116             : #define WIN_EMR_POLYGON16                   86
     117             : #define WIN_EMR_POLYLINE16                  87
     118             : #define WIN_EMR_POLYBEZIERTO16              88
     119             : #define WIN_EMR_POLYLINETO16                89
     120             : #define WIN_EMR_POLYPOLYLINE16              90
     121             : #define WIN_EMR_POLYPOLYGON16               91
     122             : #define WIN_EMR_POLYDRAW16                  92
     123             : #define WIN_EMR_CREATEMONOBRUSH             93
     124             : #define WIN_EMR_CREATEDIBPATTERNBRUSHPT     94
     125             : #define WIN_EMR_EXTCREATEPEN                95
     126             : #define WIN_EMR_POLYTEXTOUTA                96
     127             : #define WIN_EMR_POLYTEXTOUTW                97
     128             : 
     129             : #define WIN_SRCCOPY                         0x00CC0020L
     130             : #define WIN_SRCPAINT                        0x00EE0086L
     131             : #define WIN_SRCAND                          0x008800C6L
     132             : #define WIN_SRCINVERT                       0x00660046L
     133             : #define WIN_EMR_COMMENT_EMFSPOOL            0x00000000L
     134             : #define WIN_EMR_COMMENT_EMFPLUS             0x2B464D45L
     135             : #define WIN_EMR_COMMENT_PUBLIC              0x43494447L
     136             : 
     137             : #define HANDLE_INVALID                      0xffffffff
     138             : #define MAXHANDLES                          65000
     139             : 
     140             : #define LINE_SELECT                         0x00000001
     141             : #define FILL_SELECT                         0x00000002
     142             : #define TEXT_SELECT                         0x00000004
     143             : 
     144             : /* Text Alignment Options */
     145             : #define TA_NOUPDATECP                       0
     146             : #define TA_UPDATECP                         1
     147             : 
     148             : #define TA_LEFT                             0
     149             : #define TA_RIGHT                            2
     150             : #define TA_CENTER                           6
     151             : 
     152             : #define TA_TOP                              0
     153             : #define TA_BOTTOM                           8
     154             : #define TA_BASELINE                         24
     155             : #define TA_RTLREADING                       256
     156             : #define TA_MASK     (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
     157             : 
     158             : #define MM_ANISOTROPIC                      8
     159             : 
     160             : typedef enum
     161             : {
     162             :   EmfPlusHeader                     = 0x4001,
     163             :   EmfPlusEndOfFile                  = 0x4002,
     164             :   EmfPlusComment                    = 0x4003,
     165             :   EmfPlusGetDC                      = 0x4004,
     166             :   EmfPlusMultiFormatStart           = 0x4005,
     167             :   EmfPlusMultiFormatSection         = 0x4006,
     168             :   EmfPlusMultiFormatEnd             = 0x4007,
     169             :   EmfPlusObject                     = 0x4008,
     170             :   EmfPlusClear                      = 0x4009,
     171             :   EmfPlusFillRects                  = 0x400A,
     172             :   EmfPlusDrawRects                  = 0x400B,
     173             :   EmfPlusFillPolygon                = 0x400C,
     174             :   EmfPlusDrawLines                  = 0x400D,
     175             :   EmfPlusFillEllipse                = 0x400E,
     176             :   EmfPlusDrawEllipse                = 0x400F,
     177             :   EmfPlusFillPie                    = 0x4010,
     178             :   EmfPlusDrawPie                    = 0x4011,
     179             :   EmfPlusDrawArc                    = 0x4012,
     180             :   EmfPlusFillRegion                 = 0x4013,
     181             :   EmfPlusFillPath                   = 0x4014,
     182             :   EmfPlusDrawPath                   = 0x4015,
     183             :   EmfPlusFillClosedCurve            = 0x4016,
     184             :   EmfPlusDrawClosedCurve            = 0x4017,
     185             :   EmfPlusDrawCurve                  = 0x4018,
     186             :   EmfPlusDrawBeziers                = 0x4019,
     187             :   EmfPlusDrawImage                  = 0x401A,
     188             :   EmfPlusDrawImagePoints            = 0x401B,
     189             :   EmfPlusDrawstring                 = 0x401C,
     190             :   EmfPlusSetRenderingOrigin         = 0x401D,
     191             :   EmfPlusSetAntiAliasMode           = 0x401E,
     192             :   EmfPlusSetTextRenderingHint       = 0x401F,
     193             :   EmfPlusSetTextContrast            = 0x4020,
     194             :   EmfPlusSetInterpolationMode       = 0x4021,
     195             :   EmfPlusSetPixelOffsetMode         = 0x4022,
     196             :   EmfPlusSetCompositingMode         = 0x4023,
     197             :   EmfPlusSetCompositingQuality      = 0x4024,
     198             :   EmfPlusSave                       = 0x4025,
     199             :   EmfPlusRestore                    = 0x4026,
     200             :   EmfPlusBeginContainer             = 0x4027,
     201             :   EmfPlusBeginContainerNoParams     = 0x4028,
     202             :   EmfPlusEndContainer               = 0x4029,
     203             :   EmfPlusSetWorldTransform          = 0x402A,
     204             :   EmfPlusResetWorldTransform        = 0x402B,
     205             :   EmfPlusMultiplyWorldTransform     = 0x402C,
     206             :   EmfPlusTranslateWorldTransform    = 0x402D,
     207             :   EmfPlusScaleWorldTransform        = 0x402E,
     208             :   EmfPlusRotateWorldTransform       = 0x402F,
     209             :   EmfPlusSetPageTransform           = 0x4030,
     210             :   EmfPlusResetClip                  = 0x4031,
     211             :   EmfPlusSetClipRect                = 0x4032,
     212             :   EmfPlusSetClipPath                = 0x4033,
     213             :   EmfPlusSetClipRegion              = 0x4034,
     214             :   EmfPlusOffsetClip                 = 0x4035,
     215             :   EmfPlusDrawDriverstring           = 0x4036,
     216             :   EmfPlusStrokeFillPath             = 0x4037,
     217             :   EmfPlusSerializableObject         = 0x4038,
     218             :   EmfPlusSetTSGraphics              = 0x4039,
     219             :   EmfPlusSetTSClip                  = 0x403A
     220             : } EmfPlusRecordType;
     221             : 
     222             : 
     223             : // -------------
     224             : // - EMFWriter -
     225             : // -------------
     226             : 
     227          90 : void EMFWriter::ImplBeginCommentRecord( sal_Int32 nCommentType )
     228             : {
     229          90 :     ImplBeginRecord( WIN_EMR_GDICOMMENT );
     230          90 :     m_rStm.SeekRel( 4 );
     231          90 :     m_rStm<< (sal_Int32) nCommentType;
     232          90 : }
     233             : 
     234          90 : void EMFWriter::ImplEndCommentRecord()
     235             : {
     236          90 :     if( mbRecordOpen )
     237             :     {
     238          90 :         sal_Int32 nActPos = m_rStm.Tell();
     239          90 :         m_rStm.Seek( mnRecordPos + 8 );
     240          90 :         m_rStm << (sal_uInt32)( nActPos - mnRecordPos - 0xc );
     241          90 :         m_rStm.Seek( nActPos );
     242             :     }
     243          90 :     ImplEndRecord();
     244          90 : }
     245             : 
     246         210 : void EMFWriter::ImplBeginPlusRecord( sal_uInt16 nType, sal_uInt16 nFlags )
     247             : {
     248             :     DBG_ASSERT( !mbRecordPlusOpen, "Another EMF+ record is already opened!" );
     249             : 
     250         210 :     if( !mbRecordPlusOpen )
     251             :     {
     252         210 :         mbRecordPlusOpen = sal_True;
     253         210 :         mnRecordPlusPos = m_rStm.Tell();
     254             : 
     255         210 :         m_rStm << (sal_uInt16) nType << (sal_uInt16) nFlags;
     256         210 :         m_rStm.SeekRel( 8 );
     257             :     }
     258         210 : }
     259             : 
     260             : // -----------------------------------------------------------------------------
     261             : 
     262         210 : void EMFWriter::ImplEndPlusRecord()
     263             : {
     264             :     DBG_ASSERT( mbRecordPlusOpen, "EMF+ Record was not opened!" );
     265             : 
     266         210 :     if( mbRecordPlusOpen )
     267             :     {
     268         210 :         sal_Int32 nActPos = m_rStm.Tell();
     269         210 :         sal_Int32 nSize = nActPos - mnRecordPlusPos;
     270         210 :         m_rStm.Seek( mnRecordPlusPos + 4 );
     271         210 :         m_rStm << (sal_uInt32)( nSize )         // Size
     272         420 :                << (sal_uInt32) ( nSize - 0xc ); // Data Size
     273         210 :         m_rStm.Seek( nActPos );
     274         210 :         mbRecordPlusOpen = sal_False;
     275             :     }
     276         210 : }
     277             : 
     278         210 : void EMFWriter::ImplPlusRecord( sal_uInt16 nType, sal_uInt16 nFlags )
     279             : {
     280         210 :     ImplBeginPlusRecord( nType, nFlags );
     281         210 :     ImplEndPlusRecord();
     282         210 : }
     283             : 
     284          30 : void EMFWriter::WriteEMFPlusHeader( const Size &rMtfSizePix, const Size &rMtfSizeLog )
     285             : {
     286          30 :     ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
     287             : 
     288          30 :     sal_Int32 nDPIX = rMtfSizePix.Width()*25;
     289          30 :     sal_Int32 nDivX = rMtfSizeLog.Width()/100;
     290          30 :     if (nDivX)
     291          30 :         nDPIX /= nDivX;    // DPI X
     292             : 
     293          30 :     sal_Int32 nDPIY = rMtfSizePix.Height()*25;
     294          30 :     sal_Int32 nDivY = rMtfSizeLog.Height()/100;
     295          30 :     if (nDivY)
     296          30 :         nDPIY /= nDivY; // DPI Y
     297             : 
     298          30 :     m_rStm<< (sal_Int16) EmfPlusHeader;
     299          30 :     m_rStm<< (sal_Int16) 0x01  // Flags - Dual Mode // TODO: Check this
     300          30 :           << (sal_Int32) 0x1C  // Size
     301          30 :           << (sal_Int32) 0x10  // Data Size
     302          30 :           << (sal_Int32) 0xdbc01002 // (lower 12bits) 1-> v1 2-> v1.1 // TODO: Check this
     303          30 :           << (sal_Int32) 0x01 // Video display
     304          30 :           << nDPIX
     305          30 :           << nDPIY;
     306          30 :     ImplEndCommentRecord();
     307             : 
     308             :     // Write more properties
     309          30 :     ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
     310          30 :     ImplPlusRecord( EmfPlusSetPixelOffsetMode, 0x0 );
     311          30 :     ImplPlusRecord( EmfPlusSetAntiAliasMode, 0x09 );      // TODO: Check actual values for AntiAlias
     312          30 :     ImplPlusRecord( EmfPlusSetCompositingQuality, 0x0100 ); // Default Quality
     313          30 :     ImplPlusRecord( EmfPlusSetPageTransform, 1 );
     314          30 :     ImplPlusRecord( EmfPlusSetInterpolationMode, 0x00 );  // Default
     315          30 :     ImplPlusRecord( EmfPlusGetDC, 0x00 );
     316          30 :     ImplEndCommentRecord();
     317          30 : }
     318             : 
     319          30 : void EMFWriter::ImplWritePlusEOF()
     320             : {
     321          30 :     ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
     322          30 :     ImplPlusRecord( EmfPlusEndOfFile, 0x0 );
     323          30 :     ImplEndCommentRecord();
     324          30 : }
     325             : 
     326           0 : void EMFWriter::ImplWritePlusColor( const Color& rColor, const sal_uInt32& nTrans )
     327             : {
     328           0 :     sal_uInt32 nAlpha = ((100-nTrans)*0xFF)/100;
     329           0 :     sal_uInt32 nCol = rColor.GetBlue();
     330             : 
     331           0 :     nCol |= ( (sal_uInt32) rColor.GetGreen() ) << 8;
     332           0 :     nCol |= ( (sal_uInt32) rColor.GetRed() ) << 16;
     333           0 :     nCol |= ( nAlpha << 24 );
     334           0 :     m_rStm << nCol;
     335           0 : }
     336             : 
     337           0 : void EMFWriter::ImplWritePlusPoint( const Point& rPoint )
     338             : {
     339             :     // Convert to pixels
     340           0 :     const Point aPoint(maVDev.LogicToPixel( rPoint, maDestMapMode ));
     341           0 :     m_rStm << (sal_uInt16) aPoint.X() << (sal_uInt16) aPoint.Y();
     342           0 : }
     343             : 
     344           0 : void EMFWriter::ImplWritePlusFillPolygonRecord( const Polygon& rPoly, const sal_uInt32& nTrans )
     345             : {
     346           0 :     ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
     347           0 :     if( rPoly.GetSize() )
     348             :     {
     349           0 :         ImplBeginPlusRecord( EmfPlusFillPolygon, 0xC000 ); // Sets the color as well
     350           0 :         ImplWritePlusColor( maVDev.GetFillColor(), nTrans );
     351           0 :         m_rStm << (sal_uInt32) rPoly.GetSize();
     352           0 :         for( sal_uInt16 i = 0; i < rPoly.GetSize(); i++ )
     353           0 :             ImplWritePlusPoint( rPoly[ i ] );
     354           0 :         ImplEndPlusRecord();
     355             :     }
     356           0 :     ImplEndCommentRecord();
     357           0 : }
     358             : 
     359          30 : sal_Bool EMFWriter::WriteEMF( const GDIMetaFile& rMtf, FilterConfigItem* pFilterConfigItem )
     360             : {
     361          30 :     const sal_uLong nHeaderPos = m_rStm.Tell();
     362             : 
     363          30 :     mpHandlesUsed = new sal_Bool[ MAXHANDLES ];
     364          30 :     memset( mpHandlesUsed, 0, MAXHANDLES * sizeof( sal_Bool ) );
     365          30 :     mnHorTextAlign = mnHandleCount = mnLastPercent = mnRecordPos = mnRecordCount = 0;
     366          30 :     mnRecordPlusPos = 0;
     367          30 :     mnLineHandle = mnFillHandle = mnTextHandle = HANDLE_INVALID;
     368          30 :     mbRecordOpen = sal_False;
     369          30 :     mbRecordPlusOpen = false;
     370             : 
     371             : 
     372          30 :     maVDev.EnableOutput( sal_False );
     373          30 :     maVDev.SetMapMode( rMtf.GetPrefMapMode() );
     374          30 :     mpFilterConfigItem = pFilterConfigItem;
     375             : 
     376             :     // don't work with pixel as destination map mode -> higher resolution preferrable
     377          30 :     maDestMapMode.SetMapUnit( MAP_100TH_MM );
     378             : 
     379          30 :     const Size aMtfSizePix( maVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
     380          30 :     const Size aMtfSizeLog( maVDev.LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
     381             : 
     382             :     // seek over header
     383             :     // use [MS-EMF 2.2.11] HeaderExtension2 Object, otherwise resulting EMF cannot be converted with GetWinMetaFileBits()
     384          30 :     m_rStm.SeekRel( 108 );
     385             : 
     386             :     // Write EMF+ Header
     387          30 :     WriteEMFPlusHeader( aMtfSizePix, aMtfSizeLog );
     388             : 
     389             :     // write initial values
     390             : 
     391             :     // set 100th mm map mode in EMF
     392          30 :     ImplBeginRecord( WIN_EMR_SETMAPMODE );
     393          30 :     m_rStm << (sal_Int32) MM_ANISOTROPIC;
     394          30 :     ImplEndRecord();
     395             : 
     396          30 :     ImplBeginRecord( WIN_EMR_SETVIEWPORTEXTEX );
     397          30 :     m_rStm << (sal_Int32) maVDev.ImplGetDPIX() << (sal_Int32) maVDev.ImplGetDPIY();
     398          30 :     ImplEndRecord();
     399             : 
     400          30 :     ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX );
     401          30 :     m_rStm << (sal_Int32) 2540 << (sal_Int32) 2540;
     402          30 :     ImplEndRecord();
     403             : 
     404          30 :     ImplBeginRecord( WIN_EMR_SETVIEWPORTORGEX );
     405          30 :     m_rStm << (sal_Int32) 0 << (sal_Int32) 0;
     406          30 :     ImplEndRecord();
     407             : 
     408          30 :     ImplBeginRecord( WIN_EMR_SETWINDOWORGEX );
     409          30 :     m_rStm << (sal_Int32) 0 << (sal_Int32) 0;
     410          30 :     ImplEndRecord();
     411             : 
     412          30 :     ImplWriteRasterOp( ROP_OVERPAINT );
     413             : 
     414          30 :     ImplBeginRecord( WIN_EMR_SETBKMODE );
     415          30 :     m_rStm << (sal_uInt32) 1; // TRANSPARENT
     416          30 :     ImplEndRecord();
     417             : 
     418             :     // write emf data
     419          30 :     ImplWrite( rMtf );
     420             : 
     421          30 :     ImplWritePlusEOF();
     422             : 
     423          30 :     ImplBeginRecord( WIN_EMR_EOF );
     424          30 :     m_rStm<< (sal_uInt32)0      // nPalEntries
     425          30 :             << (sal_uInt32)0x10     // offPalEntries
     426          30 :             << (sal_uInt32)0x14;    // nSizeLast
     427          30 :     ImplEndRecord();
     428             : 
     429             : 
     430             :     // write header
     431          30 :     const sal_uLong nEndPos = m_rStm.Tell(); m_rStm.Seek( nHeaderPos );
     432             : 
     433          30 :     m_rStm << (sal_uInt32) 0x00000001 << (sal_uInt32) 108   //use [MS-EMF 2.2.11] HeaderExtension2 Object
     434          60 :              << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) ( aMtfSizePix.Width() - 1 ) << (sal_Int32) ( aMtfSizePix.Height() - 1 )
     435          60 :              << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) ( aMtfSizeLog.Width() - 1 ) << (sal_Int32) ( aMtfSizeLog.Height() - 1 )
     436          60 :              << (sal_uInt32) 0x464d4520 << (sal_uInt32) 0x10000 << (sal_uInt32) ( nEndPos - nHeaderPos )
     437          60 :              << (sal_uInt32) mnRecordCount << (sal_uInt16) ( mnHandleCount + 1 ) << (sal_uInt16) 0 << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0
     438          60 :              << (sal_Int32) aMtfSizePix.Width() << (sal_Int32) aMtfSizePix.Height()
     439          60 :              << (sal_Int32) ( aMtfSizeLog.Width() / 100 ) << (sal_Int32) ( aMtfSizeLog.Height() / 100 )
     440          30 :              << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0
     441          60 :              << (sal_Int32) (  aMtfSizeLog.Width() * 10 ) << (sal_Int32) ( aMtfSizeLog.Height() * 10 ); //use [MS-EMF 2.2.11] HeaderExtension2 Object
     442             : 
     443          30 :     m_rStm.Seek( nEndPos );
     444          30 :     delete[] mpHandlesUsed;
     445             : 
     446          30 :     return( m_rStm.GetError() == ERRCODE_NONE );
     447             : }
     448             : 
     449             : // -----------------------------------------------------------------------------
     450             : 
     451         371 : sal_uLong EMFWriter::ImplAcquireHandle()
     452             : {
     453         371 :     sal_uLong nHandle = HANDLE_INVALID;
     454             : 
     455         799 :     for( sal_uLong i = 0; i < MAXHANDLES && ( HANDLE_INVALID == nHandle ); i++ )
     456             :     {
     457         428 :         if( !mpHandlesUsed[ i ] )
     458             :         {
     459         371 :             mpHandlesUsed[ i ] = sal_True;
     460             : 
     461         371 :             if( ( nHandle = i ) == mnHandleCount )
     462          52 :                 mnHandleCount++;
     463             :         }
     464             :     }
     465             : 
     466             :     DBG_ASSERT( nHandle != HANDLE_INVALID, "No more handles available" );
     467         371 :     return( nHandle != HANDLE_INVALID ? nHandle + 1 : HANDLE_INVALID );
     468             : }
     469             : 
     470             : // -----------------------------------------------------------------------------
     471             : 
     472         319 : void EMFWriter::ImplReleaseHandle( sal_uLong nHandle )
     473             : {
     474             :     DBG_ASSERT( nHandle && ( nHandle < MAXHANDLES ), "Handle out of range" );
     475         319 :     mpHandlesUsed[ nHandle - 1 ] = sal_False;
     476         319 : }
     477             : 
     478             : // -----------------------------------------------------------------------------
     479             : 
     480        3909 : void EMFWriter::ImplBeginRecord( sal_uInt32 nType )
     481             : {
     482             :     DBG_ASSERT( !mbRecordOpen, "Another record is already opened!" );
     483             : 
     484        3909 :     if( !mbRecordOpen )
     485             :     {
     486        3909 :         mbRecordOpen = sal_True;
     487        3909 :         mnRecordPos = m_rStm.Tell();
     488             : 
     489        3909 :         m_rStm << nType;
     490        3909 :         m_rStm.SeekRel( 4 );
     491             :     }
     492        3909 : }
     493             : 
     494             : // -----------------------------------------------------------------------------
     495             : 
     496        3909 : void EMFWriter::ImplEndRecord()
     497             : {
     498             :     DBG_ASSERT( mbRecordOpen, "Record was not opened!" );
     499             : 
     500        3909 :     if( mbRecordOpen )
     501             :     {
     502        3909 :         sal_Int32 nFillBytes, nActPos = m_rStm.Tell();
     503        3909 :         m_rStm.Seek( mnRecordPos + 4 );
     504        3909 :         nFillBytes = nActPos - mnRecordPos;
     505        3909 :         nFillBytes += 3;    // each record has to be dword aligned
     506        3909 :         nFillBytes ^= 3;
     507        3909 :         nFillBytes &= 3;
     508        3909 :         m_rStm << (sal_uInt32)( ( nActPos - mnRecordPos ) + nFillBytes );
     509        3909 :         m_rStm.Seek( nActPos );
     510        7818 :         while( nFillBytes-- )
     511           0 :             m_rStm << (sal_uInt8)0;
     512        3909 :         mnRecordCount++;
     513        3909 :         mbRecordOpen = sal_False;
     514             :     }
     515        3909 : }
     516             : 
     517             : // -----------------------------------------------------------------------------
     518             : 
     519         371 : sal_Bool EMFWriter::ImplPrepareHandleSelect( sal_uInt32& rHandle, sal_uLong nSelectType )
     520             : {
     521         371 :     if( rHandle != HANDLE_INVALID )
     522             :     {
     523         319 :         sal_uInt32 nStockObject = 0x80000000;
     524             : 
     525         319 :         if( LINE_SELECT == nSelectType )
     526           8 :             nStockObject |= 0x00000007;
     527         311 :         else if( FILL_SELECT == nSelectType )
     528           8 :             nStockObject |= 0x00000001;
     529         303 :         else if( TEXT_SELECT == nSelectType )
     530         303 :             nStockObject |= 0x0000000a;
     531             : 
     532             :         // select stock object first
     533         319 :         ImplBeginRecord( WIN_EMR_SELECTOBJECT );
     534         319 :         m_rStm << nStockObject;
     535         319 :         ImplEndRecord();
     536             : 
     537             :         // destroy handle of created object
     538         319 :         ImplBeginRecord( WIN_EMR_DELETEOBJECT );
     539         319 :         m_rStm << rHandle;
     540         319 :         ImplEndRecord();
     541             : 
     542             :         // mark handle as free
     543         319 :         ImplReleaseHandle( rHandle );
     544             :     }
     545             : 
     546         371 :     rHandle = ImplAcquireHandle();
     547             : 
     548         371 :     return( HANDLE_INVALID != rHandle );
     549             : }
     550             : 
     551             : // -----------------------------------------------------------------------------
     552             : 
     553          19 : void EMFWriter::ImplCheckLineAttr()
     554             : {
     555          19 :     if( mbLineChanged && ImplPrepareHandleSelect( mnLineHandle, LINE_SELECT ) )
     556             :     {
     557          19 :         sal_uInt32 nStyle = maVDev.IsLineColor() ? 0 : 5;
     558          19 :         sal_uInt32 nWidth = 0, nHeight = 0;
     559             : 
     560          19 :         ImplBeginRecord( WIN_EMR_CREATEPEN );
     561          19 :         m_rStm << mnLineHandle << nStyle << nWidth << nHeight;
     562          19 :         ImplWriteColor( maVDev.GetLineColor() );
     563          19 :         ImplEndRecord();
     564             : 
     565          19 :         ImplBeginRecord( WIN_EMR_SELECTOBJECT );
     566          19 :         m_rStm << mnLineHandle;
     567          19 :         ImplEndRecord();
     568             :     }
     569          19 : }
     570             : 
     571             : // -----------------------------------------------------------------------------
     572             : 
     573          19 : void EMFWriter::ImplCheckFillAttr()
     574             : {
     575          19 :     if( mbFillChanged && ImplPrepareHandleSelect( mnFillHandle, FILL_SELECT ) )
     576             :     {
     577          19 :         sal_uInt32 nStyle = maVDev.IsFillColor() ? 0 : 1;
     578          19 :         sal_uInt32 nPatternStyle = 0;
     579             : 
     580          19 :         ImplBeginRecord( WIN_EMR_CREATEBRUSHINDIRECT );
     581          19 :         m_rStm << mnFillHandle << nStyle;
     582          19 :         ImplWriteColor( maVDev.GetFillColor() );
     583          19 :         m_rStm << nPatternStyle;
     584          19 :         ImplEndRecord();
     585             : 
     586          19 :         ImplBeginRecord( WIN_EMR_SELECTOBJECT );
     587          19 :         m_rStm << mnFillHandle;
     588          19 :         ImplEndRecord();
     589             :     }
     590          19 : }
     591             : 
     592             : // -----------------------------------------------------------------------------
     593             : 
     594         333 : void EMFWriter::ImplCheckTextAttr()
     595             : {
     596         333 :     if( mbTextChanged && ImplPrepareHandleSelect( mnTextHandle, TEXT_SELECT ) )
     597             :     {
     598         333 :         const Font&     rFont = maVDev.GetFont();
     599         333 :         String          aFontName( rFont.GetName() );
     600             :         sal_Int32       nWeight;
     601             :         sal_uInt16      i;
     602             :         sal_uInt8       nPitchAndFamily;
     603             : 
     604         333 :         ImplBeginRecord( WIN_EMR_EXTCREATEFONTINDIRECTW );
     605         333 :         m_rStm << mnTextHandle;
     606         333 :         ImplWriteExtent( -rFont.GetSize().Height() );
     607         333 :         ImplWriteExtent( rFont.GetSize().Width() );
     608         333 :         m_rStm << (sal_Int32) rFont.GetOrientation() << (sal_Int32) rFont.GetOrientation();
     609             : 
     610         333 :         switch( rFont.GetWeight() )
     611             :         {
     612           0 :             case WEIGHT_THIN:       nWeight = 100; break;
     613           0 :             case WEIGHT_ULTRALIGHT: nWeight = 200; break;
     614           0 :             case WEIGHT_LIGHT:      nWeight = 300; break;
     615           0 :             case WEIGHT_SEMILIGHT:  nWeight = 300; break;
     616         333 :             case WEIGHT_NORMAL:     nWeight = 400; break;
     617           0 :             case WEIGHT_MEDIUM:     nWeight = 500; break;
     618           0 :             case WEIGHT_SEMIBOLD:   nWeight = 600; break;
     619           0 :             case WEIGHT_BOLD:       nWeight = 700; break;
     620           0 :             case WEIGHT_ULTRABOLD:  nWeight = 800; break;
     621           0 :             case WEIGHT_BLACK:      nWeight = 900; break;
     622           0 :             default:                nWeight = 0; break;
     623             :         }
     624             : 
     625         333 :         m_rStm << nWeight;
     626         333 :         m_rStm << (sal_uInt8) ( ( ITALIC_NONE == rFont.GetItalic() ) ? 0 : 1 );
     627         333 :         m_rStm << (sal_uInt8) ( ( UNDERLINE_NONE == rFont.GetUnderline() ) ? 0 : 1 );
     628         333 :         m_rStm << (sal_uInt8) ( ( STRIKEOUT_NONE == rFont.GetStrikeout() ) ? 0 : 1 );
     629         333 :         m_rStm << (sal_uInt8) ( ( RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet() ) ? 2 : 0 );
     630         333 :         m_rStm << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0;
     631             : 
     632         333 :         switch( rFont.GetPitch() )
     633             :         {
     634           0 :             case PITCH_FIXED:    nPitchAndFamily = 0x01; break;
     635           2 :             case PITCH_VARIABLE: nPitchAndFamily = 0x02; break;
     636         331 :             default:             nPitchAndFamily = 0x00; break;
     637             :         }
     638             : 
     639         333 :         switch( rFont.GetFamily() )
     640             :         {
     641           0 :             case FAMILY_DECORATIVE: nPitchAndFamily |= 0x50; break;
     642           0 :             case FAMILY_MODERN:     nPitchAndFamily |= 0x30; break;
     643         213 :             case FAMILY_ROMAN:      nPitchAndFamily |= 0x10; break;
     644           0 :             case FAMILY_SCRIPT:     nPitchAndFamily |= 0x40; break;
     645           2 :             case FAMILY_SWISS:      nPitchAndFamily |= 0x20; break;
     646         118 :             default: break;
     647             :         }
     648             : 
     649         333 :         m_rStm << nPitchAndFamily;
     650             : 
     651       10989 :         for( i = 0; i < 32; i++ )
     652       10656 :             m_rStm << (sal_Unicode) ( ( i < aFontName.Len() ) ? aFontName.GetChar( i ) : 0 );
     653             : 
     654             :         // dummy elfFullName
     655       21645 :         for( i = 0; i < 64; i++ )
     656       21312 :             m_rStm << (sal_Unicode) 0;
     657             : 
     658             :         // dummy elfStyle
     659       10989 :         for( i = 0; i < 32; i++ )
     660       10656 :             m_rStm << (sal_Unicode) 0;
     661             : 
     662             :         // dummy elfVersion, elfStyleSize, elfMatch, elfReserved
     663         333 :         m_rStm << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0 << (sal_uInt32) 0 ;
     664             : 
     665             :         // dummy elfVendorId
     666         333 :         m_rStm << (sal_uInt32) 0;
     667             : 
     668             :         // dummy elfCulture
     669         333 :         m_rStm << (sal_uInt32) 0;
     670             : 
     671             :         // dummy elfPanose
     672         333 :         m_rStm << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0 << (sal_uInt8) 0;
     673             : 
     674             :         // fill record to get a record size divideable by 4
     675         333 :         m_rStm << (sal_uInt16) 0;
     676             : 
     677         333 :         ImplEndRecord();
     678             : 
     679             :         // TextAlign
     680             :         sal_uInt32 nTextAlign;
     681             : 
     682         333 :         switch( rFont.GetAlign() )
     683             :         {
     684           0 :             case ALIGN_TOP:    nTextAlign = TA_TOP; break;
     685           0 :             case ALIGN_BOTTOM: nTextAlign = TA_BOTTOM; break;
     686         333 :             default:           nTextAlign = TA_BASELINE; break;
     687             :         }
     688         333 :         nTextAlign |= mnHorTextAlign;
     689             : 
     690         333 :         ImplBeginRecord( WIN_EMR_SETTEXTALIGN );
     691         333 :         m_rStm << nTextAlign;
     692         333 :         ImplEndRecord();
     693             : 
     694             :         // Text color
     695         333 :         ImplBeginRecord( WIN_EMR_SETTEXTCOLOR );
     696         333 :         ImplWriteColor( maVDev.GetTextColor() );
     697         333 :         ImplEndRecord();
     698             : 
     699         333 :         ImplBeginRecord( WIN_EMR_SELECTOBJECT );
     700         333 :         m_rStm << mnTextHandle;
     701         333 :         ImplEndRecord();
     702             :     }
     703         333 : }
     704             : 
     705             : // -----------------------------------------------------------------------------
     706             : 
     707         371 : void EMFWriter::ImplWriteColor( const Color& rColor )
     708             : {
     709         371 :     sal_uInt32 nCol = rColor.GetRed();
     710             : 
     711         371 :     nCol |= ( (sal_uInt32) rColor.GetGreen() ) << 8;
     712         371 :     nCol |= ( (sal_uInt32) rColor.GetBlue() ) << 16;
     713             : 
     714         371 :     m_rStm << nCol;
     715         371 : }
     716             : 
     717             : // -----------------------------------------------------------------------------
     718             : 
     719         414 : void EMFWriter::ImplWriteRasterOp( RasterOp eRop )
     720             : {
     721             :     sal_uInt32 nROP2;
     722             : 
     723         414 :     switch( eRop )
     724             :     {
     725           0 :         case ROP_INVERT: nROP2 = 6; break;
     726           0 :         case ROP_XOR:    nROP2 = 7; break;
     727         414 :         default:         nROP2 = 13;break;
     728             :     }
     729             : 
     730         414 :     ImplBeginRecord( WIN_EMR_SETROP2 );
     731         414 :     m_rStm << nROP2;
     732         414 :     ImplEndRecord();
     733         414 : }
     734             : 
     735             : // -----------------------------------------------------------------------------
     736             : 
     737        1044 : void EMFWriter::ImplWriteExtent( long nExtent )
     738             : {
     739        1044 :     nExtent = maVDev.LogicToLogic( Size( nExtent, 0 ), maVDev.GetMapMode(), maDestMapMode ).Width();
     740        1044 :     m_rStm << (sal_Int32) nExtent;
     741        1044 : }
     742             : 
     743             : // -----------------------------------------------------------------------------
     744             : 
     745         333 : void EMFWriter::ImplWritePoint( const Point& rPoint )
     746             : {
     747         333 :     const Point aPoint( maVDev.LogicToLogic( rPoint, maVDev.GetMapMode(), maDestMapMode ));
     748         333 :      m_rStm << (sal_Int32) aPoint.X() << (sal_Int32) aPoint.Y();
     749         333 : }
     750             : 
     751             : // -----------------------------------------------------------------------------
     752             : 
     753           0 : void EMFWriter::ImplWriteSize( const Size& rSize)
     754             : {
     755           0 :     const Size aSize( maVDev.LogicToLogic( rSize, maVDev.GetMapMode(), maDestMapMode ));
     756           0 :      m_rStm << (sal_Int32) aSize.Width() << (sal_Int32) aSize.Height();
     757           0 : }
     758             : 
     759             : // -----------------------------------------------------------------------------
     760             : 
     761         381 : void EMFWriter::ImplWriteRect( const Rectangle& rRect )
     762             : {
     763         381 :     const Rectangle aRect( maVDev.LogicToLogic ( rRect, maVDev.GetMapMode(), maDestMapMode ));
     764             :     m_rStm
     765         381 :         << static_cast<sal_Int32>(aRect.Left())
     766         762 :         << static_cast<sal_Int32>(aRect.Top())
     767         762 :         << static_cast<sal_Int32>(aRect.Right())
     768         762 :         << static_cast<sal_Int32>(aRect.Bottom());
     769         381 : }
     770             : 
     771             : // -----------------------------------------------------------------------------
     772             : 
     773           0 : void EMFWriter::ImplWritePolygonRecord( const Polygon& rPoly, sal_Bool bClose )
     774             : {
     775           0 :     if( rPoly.GetSize() )
     776             :     {
     777           0 :         if( rPoly.HasFlags() )
     778           0 :             ImplWritePath( rPoly, bClose );
     779             :         else
     780             :         {
     781           0 :             if( bClose )
     782           0 :                 ImplCheckFillAttr();
     783             : 
     784           0 :             ImplCheckLineAttr();
     785             : 
     786           0 :             ImplBeginRecord( bClose ? WIN_EMR_POLYGON : WIN_EMR_POLYLINE );
     787           0 :             ImplWriteRect( rPoly.GetBoundRect() );
     788           0 :             m_rStm << (sal_uInt32) rPoly.GetSize();
     789             : 
     790           0 :             for( sal_uInt16 i = 0; i < rPoly.GetSize(); i++ )
     791           0 :                 ImplWritePoint( rPoly[ i ] );
     792             : 
     793           0 :             ImplEndRecord();
     794             :         }
     795             :     }
     796           0 : }
     797             : 
     798             : // -----------------------------------------------------------------------------
     799             : 
     800           0 : void EMFWriter::ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly )
     801             : {
     802           0 :     sal_uInt16 n, i, nPolyCount = rPolyPoly.Count();
     803             : 
     804           0 :     if( nPolyCount )
     805             :     {
     806           0 :         if( 1 == nPolyCount )
     807           0 :             ImplWritePolygonRecord( rPolyPoly[ 0 ], sal_True );
     808             :         else
     809             :         {
     810           0 :             sal_Bool    bHasFlags = sal_False;
     811           0 :             sal_uInt32  nTotalPoints = 0;
     812             : 
     813           0 :             for( i = 0; i < nPolyCount; i++ )
     814             :             {
     815           0 :                 nTotalPoints += rPolyPoly[ i ].GetSize();
     816           0 :                 if ( rPolyPoly[ i ].HasFlags() )
     817           0 :                     bHasFlags = sal_True;
     818             :             }
     819           0 :             if( nTotalPoints )
     820             :             {
     821           0 :                 if ( bHasFlags )
     822           0 :                     ImplWritePath( rPolyPoly, sal_True );
     823             :                 else
     824             :                 {
     825           0 :                     ImplCheckFillAttr();
     826           0 :                     ImplCheckLineAttr();
     827             : 
     828           0 :                     ImplBeginRecord( WIN_EMR_POLYPOLYGON );
     829           0 :                     ImplWriteRect( rPolyPoly.GetBoundRect() );
     830           0 :                     m_rStm << (sal_uInt32)nPolyCount << nTotalPoints;
     831             : 
     832           0 :                     for( i = 0; i < nPolyCount; i++ )
     833           0 :                         m_rStm << (sal_uInt32)rPolyPoly[ i ].GetSize();
     834             : 
     835           0 :                     for( i = 0; i < nPolyCount; i++ )
     836             :                     {
     837           0 :                         const Polygon& rPoly = rPolyPoly[ i ];
     838             : 
     839           0 :                         for( n = 0; n < rPoly.GetSize(); n++ )
     840           0 :                             ImplWritePoint( rPoly[ n ] );
     841             :                     }
     842           0 :                     ImplEndRecord();
     843             :                 }
     844             :             }
     845             :         }
     846             :     }
     847           0 : }
     848             : 
     849             : // -----------------------------------------------------------------------------
     850             : 
     851           0 : void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed )
     852             : {
     853           0 :     if ( bClosed )
     854           0 :         ImplCheckFillAttr();
     855           0 :     ImplCheckLineAttr();
     856             : 
     857           0 :     ImplBeginRecord( WIN_EMR_BEGINPATH );
     858           0 :     ImplEndRecord();
     859             : 
     860           0 :     sal_uInt16 i, n, o, nPolyCount = rPolyPoly.Count();
     861           0 :     for ( i = 0; i < nPolyCount; i++ )
     862             :     {
     863           0 :         n = 0;
     864           0 :         const Polygon& rPoly = rPolyPoly[ i ];
     865           0 :         while ( n < rPoly.GetSize() )
     866             :         {
     867           0 :             if( n == 0 )
     868             :             {
     869           0 :                 ImplBeginRecord( WIN_EMR_MOVETOEX );
     870           0 :                 ImplWritePoint( rPoly[ 0 ] );
     871           0 :                 ImplEndRecord();
     872           0 :                 n++;
     873           0 :                 continue;
     874             :             }
     875             : 
     876           0 :             sal_uInt16 nBezPoints = 0;
     877             : 
     878           0 :             while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) )
     879           0 :                 nBezPoints += 3;
     880             : 
     881           0 :             if ( nBezPoints )
     882             :             {
     883           0 :                 ImplBeginRecord( WIN_EMR_POLYBEZIERTO );
     884           0 :                 Polygon aNewPoly( nBezPoints + 1 );
     885           0 :                 aNewPoly[ 0 ] = rPoly[ n - 1 ];
     886           0 :                 for ( o = 0; o < nBezPoints; o++ )
     887           0 :                     aNewPoly[ o + 1 ] = rPoly[ n + o ];
     888           0 :                 ImplWriteRect( aNewPoly.GetBoundRect() );
     889           0 :                 m_rStm << (sal_uInt32)nBezPoints;
     890           0 :                 for( o = 1; o < aNewPoly.GetSize(); o++ )
     891           0 :                     ImplWritePoint( aNewPoly[ o ] );
     892           0 :                 ImplEndRecord();
     893           0 :                 n = n + nBezPoints;
     894             :             }
     895             :             else
     896             :             {
     897           0 :                 sal_uInt16 nPoints = 1;
     898           0 :                 while( ( nPoints + n ) < rPoly.GetSize() && ( rPoly.GetFlags( nPoints + n ) != POLY_CONTROL ) )
     899           0 :                     nPoints++;
     900             : 
     901           0 :                 if ( nPoints > 1 )
     902             :                 {
     903           0 :                     ImplBeginRecord( WIN_EMR_POLYLINETO );
     904           0 :                     Polygon aNewPoly( nPoints + 1 );
     905           0 :                     aNewPoly[ 0 ] = rPoly[ n - 1];
     906           0 :                     for ( o = 1; o <= nPoints; o++ )
     907           0 :                         aNewPoly[ o ] = rPoly[ n - 1 + o ];
     908           0 :                     ImplWriteRect( aNewPoly.GetBoundRect() );
     909           0 :                     m_rStm << (sal_uInt32)( nPoints );
     910           0 :                     for( o = 1; o < aNewPoly.GetSize(); o++ )
     911           0 :                         ImplWritePoint( aNewPoly[ o ] );
     912           0 :                     ImplEndRecord();
     913             :                 }
     914             :                 else
     915             :                 {
     916           0 :                     ImplBeginRecord( WIN_EMR_LINETO );
     917           0 :                     ImplWritePoint( rPoly[ n ] );
     918           0 :                     ImplEndRecord();
     919             :                 }
     920           0 :                 n = n + nPoints;
     921             :             }
     922           0 :             if ( bClosed && ( n == rPoly.GetSize() ) )
     923             :             {
     924           0 :                 ImplBeginRecord( WIN_EMR_CLOSEFIGURE );
     925           0 :                 ImplEndRecord();
     926             :             }
     927             :         }
     928             :     }
     929           0 :     ImplBeginRecord( WIN_EMR_ENDPATH );
     930           0 :     ImplEndRecord();
     931           0 :     ImplBeginRecord( bClosed ? WIN_EMR_FILLPATH : WIN_EMR_STROKEPATH );
     932           0 :     ImplWriteRect( rPolyPoly.GetBoundRect() );
     933           0 :     ImplEndRecord();
     934           0 : }
     935             : 
     936             : // -----------------------------------------------------------------------------
     937             : 
     938           0 : void EMFWriter::ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt,
     939             :                                     const Size& rSz, sal_uInt32 nROP )
     940             : {
     941           0 :     if( !!rBmp )
     942             :     {
     943           0 :         SvMemoryStream  aMemStm( 65535, 65535 );
     944           0 :         const Size      aBmpSizePixel( rBmp.GetSizePixel() );
     945             : 
     946           0 :         ImplBeginRecord( WIN_EMR_STRETCHDIBITS );
     947           0 :         ImplWriteRect( Rectangle( rPt, rSz ) );
     948           0 :         ImplWritePoint( rPt );
     949           0 :         m_rStm << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) aBmpSizePixel.Width() << (sal_Int32) aBmpSizePixel.Height();
     950             : 
     951             :         // write offset positions and sizes later
     952           0 :         const sal_uLong nOffPos = m_rStm.Tell();
     953           0 :         m_rStm.SeekRel( 16 );
     954             : 
     955           0 :         m_rStm << (sal_uInt32) 0 << sal_Int32( ( ROP_XOR == maVDev.GetRasterOp() && WIN_SRCCOPY == nROP ) ? WIN_SRCINVERT : nROP );
     956           0 :         ImplWriteSize( rSz );
     957             : 
     958           0 :         rBmp.Write( aMemStm, sal_True, sal_False );
     959             : 
     960           0 :         sal_uInt32  nDIBSize = aMemStm.Tell(), nHeaderSize, nCompression, nColsUsed, nPalCount, nImageSize;
     961             :         sal_uInt16  nBitCount;
     962             : 
     963             :         // get DIB parameters
     964           0 :         aMemStm.Seek( 0 );
     965           0 :         aMemStm >> nHeaderSize;
     966           0 :         aMemStm.SeekRel( 10 );
     967           0 :         aMemStm >> nBitCount >> nCompression >> nImageSize;
     968           0 :         aMemStm.SeekRel( 8 );
     969           0 :         aMemStm >> nColsUsed;
     970             : 
     971             :         nPalCount = ( nBitCount <= 8 ) ? ( nColsUsed ? nColsUsed : ( 1 << (sal_uInt32) nBitCount ) ) :
     972           0 :                                          ( ( 3 == nCompression ) ? 12 : 0 );
     973             : 
     974           0 :         m_rStm.Write( aMemStm.GetData(), nDIBSize );
     975             : 
     976           0 :         const sal_uLong nEndPos = m_rStm.Tell();
     977           0 :         m_rStm.Seek( nOffPos );
     978           0 :         m_rStm << (sal_uInt32) 80 << (sal_uInt32)( nHeaderSize + ( nPalCount << 2 ) );
     979           0 :         m_rStm << (sal_uInt32)( 80 + ( nHeaderSize + ( nPalCount << 2 ) ) ) << nImageSize;
     980           0 :         m_rStm.Seek( nEndPos );
     981             : 
     982           0 :         ImplEndRecord();
     983             :     }
     984           0 : }
     985             : 
     986             : // -----------------------------------------------------------------------------
     987             : 
     988         333 : void EMFWriter::ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth )
     989             : {
     990         333 :     xub_StrLen nLen = rText.Len(), i;
     991             : 
     992         333 :     if( nLen )
     993             :     {
     994             :         sal_uInt32  nNormWidth;
     995             :         sal_Int32*  pOwnArray;
     996             :         sal_Int32*  pDX;
     997             : 
     998             :         // get text sizes
     999         333 :         if( pDXArray )
    1000             :         {
    1001           2 :             pOwnArray = NULL;
    1002           2 :             nNormWidth = maVDev.GetTextWidth( rText );
    1003           2 :             pDX = (sal_Int32*) pDXArray;
    1004             :         }
    1005             :         else
    1006             :         {
    1007         331 :             pOwnArray = new sal_Int32[ nLen ];
    1008         331 :             nNormWidth = maVDev.GetTextArray( rText, pOwnArray );
    1009         331 :             pDX = pOwnArray;
    1010             :         }
    1011             : 
    1012         333 :         if( nLen > 1 )
    1013             :         {
    1014          23 :             nNormWidth = pDX[ nLen - 2 ] + maVDev.GetTextWidth( rtl::OUString(rText.GetChar( nLen - 1 )) );
    1015             : 
    1016          23 :             if( nWidth && nNormWidth && ( nWidth != nNormWidth ) )
    1017             :             {
    1018          20 :                 const double fFactor = (double) nWidth / nNormWidth;
    1019             : 
    1020          60 :                 for( i = 0; i < ( nLen - 1 ); i++ )
    1021          40 :                     pDX[ i ] = FRound( pDX[ i ] * fFactor );
    1022             :             }
    1023             :         }
    1024             : 
    1025             :         // write text record
    1026         333 :         ImplBeginRecord( WIN_EMR_EXTTEXTOUTW );
    1027             : 
    1028         333 :         ImplWriteRect( Rectangle( rPos, Size( nNormWidth, maVDev.GetTextHeight() ) ) );
    1029         333 :         m_rStm << (sal_uInt32)1;
    1030         333 :         m_rStm << (sal_Int32) 0 << (sal_Int32) 0;
    1031         333 :         ImplWritePoint( rPos );
    1032         333 :         m_rStm << (sal_uInt32) nLen << (sal_uInt32) 76 << (sal_uInt32) 2;
    1033         333 :         m_rStm << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int32) 0;
    1034         333 :         m_rStm << (sal_uInt32) ( 76 + ( nLen << 1 ) + ( (nLen & 1 ) ? 2 : 0 ) );
    1035             : 
    1036             :         // write text
    1037         711 :         for( i = 0; i < nLen; i++ )
    1038         378 :             m_rStm << (sal_Unicode)rText.GetChar( i );
    1039             : 
    1040             :         // padding word
    1041         333 :         if( nLen & 1 )
    1042         326 :             m_rStm << (sal_uInt16) 0;
    1043             : 
    1044             :         // write DX array
    1045         333 :         ImplWriteExtent( pDX[ 0 ] );
    1046             : 
    1047         333 :         if( nLen > 1 )
    1048             :         {
    1049          45 :             for( i = 1; i < ( nLen - 1 ); i++ )
    1050          22 :                 ImplWriteExtent( pDX[ i ] - pDX[ i - 1 ] );
    1051             : 
    1052          23 :             ImplWriteExtent( pDX[ nLen - 2 ] / ( nLen - 1 ) );
    1053             :         }
    1054             : 
    1055         333 :         ImplEndRecord();
    1056         333 :         delete[] pOwnArray;
    1057             :     }
    1058         333 : }
    1059             : 
    1060             : // -----------------------------------------------------------------------------
    1061             : 
    1062           0 : void EMFWriter::Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
    1063             : {
    1064           0 :     if(rLinePolygon.count())
    1065             :     {
    1066           0 :         basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
    1067           0 :         basegfx::B2DPolyPolygon aFillPolyPolygon;
    1068             : 
    1069           0 :         rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
    1070             : 
    1071           0 :         if(aLinePolyPolygon.count())
    1072             :         {
    1073           0 :             for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
    1074             :             {
    1075           0 :                 const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
    1076           0 :                 ImplWritePolygonRecord( Polygon(aCandidate), sal_False );
    1077           0 :             }
    1078             :         }
    1079             : 
    1080           0 :         if(aFillPolyPolygon.count())
    1081             :         {
    1082           0 :             const Color aOldLineColor(maVDev.GetLineColor());
    1083           0 :             const Color aOldFillColor(maVDev.GetFillColor());
    1084             : 
    1085           0 :             maVDev.SetLineColor();
    1086           0 :             maVDev.SetFillColor(aOldLineColor);
    1087             : 
    1088           0 :             for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
    1089             :             {
    1090           0 :                 const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
    1091           0 :                 ImplWritePolyPolygonRecord(PolyPolygon(Polygon(aPolygon)));
    1092           0 :             }
    1093             : 
    1094           0 :             maVDev.SetLineColor(aOldLineColor);
    1095           0 :             maVDev.SetFillColor(aOldFillColor);
    1096           0 :         }
    1097             :     }
    1098           0 : }
    1099             : 
    1100             : // -----------------------------------------------------------------------------
    1101             : 
    1102          30 : void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
    1103             : {
    1104        2781 :     for( size_t j = 0, nActionCount = rMtf.GetActionSize(); j < nActionCount; j++ )
    1105             :     {
    1106        2751 :         const MetaAction*   pAction = rMtf.GetAction( j );
    1107        2751 :         const sal_uInt16        nType = pAction->GetType();
    1108             : 
    1109        2751 :         switch( nType )
    1110             :         {
    1111             :             case( META_PIXEL_ACTION ):
    1112             :             {
    1113           0 :                 const MetaPixelAction* pA = (const MetaPixelAction*) pAction;
    1114             : 
    1115           0 :                 ImplCheckLineAttr();
    1116           0 :                 ImplBeginRecord( WIN_EMR_SETPIXELV );
    1117           0 :                 ImplWritePoint( pA->GetPoint() );
    1118           0 :                 ImplWriteColor( pA->GetColor() );
    1119           0 :                 ImplEndRecord();
    1120             :             }
    1121           0 :             break;
    1122             : 
    1123             :             case( META_POINT_ACTION ):
    1124             :             {
    1125           0 :                 if( maVDev.IsLineColor() )
    1126             :                 {
    1127           0 :                     const MetaPointAction* pA = (const MetaPointAction*) pAction;
    1128             : 
    1129           0 :                     ImplCheckLineAttr();
    1130           0 :                     ImplBeginRecord( WIN_EMR_SETPIXELV );
    1131           0 :                     ImplWritePoint( pA->GetPoint() );
    1132           0 :                     ImplWriteColor( maVDev.GetLineColor() );
    1133           0 :                     ImplEndRecord();
    1134             :                 }
    1135             :             }
    1136           0 :             break;
    1137             : 
    1138             :             case( META_LINE_ACTION ):
    1139             :             {
    1140           0 :                 if( maVDev.IsLineColor() )
    1141             :                 {
    1142           0 :                     const MetaLineAction* pA = (const MetaLineAction*) pAction;
    1143             : 
    1144           0 :                     if(pA->GetLineInfo().IsDefault())
    1145             :                     {
    1146           0 :                         ImplCheckLineAttr();
    1147             : 
    1148           0 :                         ImplBeginRecord( WIN_EMR_MOVETOEX );
    1149           0 :                         ImplWritePoint( pA->GetStartPoint() );
    1150           0 :                         ImplEndRecord();
    1151             : 
    1152           0 :                         ImplBeginRecord( WIN_EMR_LINETO );
    1153           0 :                         ImplWritePoint( pA->GetEndPoint() );
    1154           0 :                         ImplEndRecord();
    1155             : 
    1156           0 :                         ImplBeginRecord( WIN_EMR_SETPIXELV );
    1157           0 :                         ImplWritePoint( pA->GetEndPoint() );
    1158           0 :                         ImplWriteColor( maVDev.GetLineColor() );
    1159           0 :                         ImplEndRecord();
    1160             :                     }
    1161             :                     else
    1162             :                     {
    1163             :                         // LineInfo used; handle Dash/Dot and fat lines
    1164           0 :                         basegfx::B2DPolygon aPolygon;
    1165           0 :                         aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
    1166           0 :                         aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
    1167           0 :                         Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
    1168             :                     }
    1169             :                 }
    1170             :             }
    1171           0 :             break;
    1172             : 
    1173             :             case( META_RECT_ACTION ):
    1174             :             {
    1175          19 :                 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
    1176             :                 {
    1177          19 :                     const MetaRectAction* pA = (const MetaRectAction*) pAction;
    1178             : 
    1179          19 :                     ImplCheckFillAttr();
    1180          19 :                     ImplCheckLineAttr();
    1181             : 
    1182          19 :                     ImplBeginRecord( WIN_EMR_RECTANGLE );
    1183          19 :                     ImplWriteRect( pA->GetRect() );
    1184          19 :                     ImplEndRecord();
    1185             :                 }
    1186             :             }
    1187          19 :             break;
    1188             : 
    1189             :             case( META_ROUNDRECT_ACTION ):
    1190             :             {
    1191           0 :                 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
    1192             :                 {
    1193           0 :                     const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction;
    1194             : 
    1195           0 :                     ImplCheckFillAttr();
    1196           0 :                     ImplCheckLineAttr();
    1197             : 
    1198           0 :                     ImplBeginRecord( WIN_EMR_ROUNDRECT );
    1199           0 :                     ImplWriteRect( pA->GetRect() );
    1200           0 :                     ImplWriteSize( Size( pA->GetHorzRound(), pA->GetVertRound() ) );
    1201           0 :                     ImplEndRecord();
    1202             :                 }
    1203             :             }
    1204           0 :             break;
    1205             : 
    1206             :             case( META_ELLIPSE_ACTION ):
    1207             :             {
    1208           0 :                 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
    1209             :                 {
    1210           0 :                     const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction;
    1211             : 
    1212           0 :                     ImplCheckFillAttr();
    1213           0 :                     ImplCheckLineAttr();
    1214             : 
    1215           0 :                     ImplBeginRecord( WIN_EMR_ELLIPSE );
    1216           0 :                     ImplWriteRect( pA->GetRect() );
    1217           0 :                     ImplEndRecord();
    1218             :                 }
    1219             :             }
    1220           0 :             break;
    1221             : 
    1222             :             case( META_ARC_ACTION ):
    1223             :             case( META_PIE_ACTION ):
    1224             :             case( META_CHORD_ACTION ):
    1225             :             case( META_POLYGON_ACTION ):
    1226             :             {
    1227           0 :                 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
    1228             :                 {
    1229           0 :                     Polygon aPoly;
    1230             : 
    1231           0 :                     switch( nType )
    1232             :                     {
    1233             :                         case( META_ARC_ACTION ):
    1234             :                         {
    1235           0 :                             const MetaArcAction* pA = (const MetaArcAction*) pAction;
    1236           0 :                             aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC );
    1237             :                         }
    1238           0 :                         break;
    1239             : 
    1240             :                         case( META_PIE_ACTION ):
    1241             :                         {
    1242           0 :                             const MetaPieAction* pA = (const MetaPieAction*) pAction;
    1243           0 :                             aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE );
    1244             :                         }
    1245           0 :                         break;
    1246             : 
    1247             :                         case( META_CHORD_ACTION ):
    1248             :                         {
    1249           0 :                             const MetaChordAction* pA = (const MetaChordAction*) pAction;
    1250           0 :                             aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD );
    1251             :                         }
    1252           0 :                         break;
    1253             : 
    1254             :                         case( META_POLYGON_ACTION ):
    1255           0 :                             aPoly = ( (const MetaPolygonAction*) pAction )->GetPolygon();
    1256           0 :                         break;
    1257             :                     }
    1258             : 
    1259           0 :                     ImplWritePolygonRecord( aPoly, nType != META_ARC_ACTION );
    1260             :                 }
    1261             :             }
    1262           0 :             break;
    1263             : 
    1264             :             case( META_POLYLINE_ACTION ):
    1265             :             {
    1266           0 :                 if( maVDev.IsLineColor() )
    1267             :                 {
    1268           0 :                     const MetaPolyLineAction*   pA = (const MetaPolyLineAction*) pAction;
    1269           0 :                     const Polygon&              rPoly = pA->GetPolygon();
    1270             : 
    1271           0 :                     if( rPoly.GetSize() )
    1272             :                     {
    1273           0 :                         if(pA->GetLineInfo().IsDefault())
    1274             :                         {
    1275           0 :                             ImplWritePolygonRecord( rPoly, sal_False );
    1276             :                         }
    1277             :                         else
    1278             :                         {
    1279             :                             // LineInfo used; handle Dash/Dot and fat lines
    1280           0 :                             Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
    1281             :                         }
    1282             :                     }
    1283             :                 }
    1284             :             }
    1285           0 :             break;
    1286             : 
    1287             :             case( META_POLYPOLYGON_ACTION ):
    1288             :             {
    1289           0 :                 if( maVDev.IsLineColor() || maVDev.IsFillColor() )
    1290           0 :                     ImplWritePolyPolygonRecord( ( (const MetaPolyPolygonAction*) pAction )->GetPolyPolygon() );
    1291             :             }
    1292           0 :             break;
    1293             : 
    1294             :             case( META_GRADIENT_ACTION ):
    1295             :             {
    1296           0 :                 const MetaGradientAction*   pA = (const MetaGradientAction*) pAction;
    1297           0 :                 GDIMetaFile                 aTmpMtf;
    1298             : 
    1299           0 :                 maVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
    1300           0 :                 ImplWrite( aTmpMtf );
    1301             :             }
    1302           0 :             break;
    1303             : 
    1304             :             case META_HATCH_ACTION:
    1305             :             {
    1306           0 :                 const MetaHatchAction*  pA = (const MetaHatchAction*) pAction;
    1307           0 :                 GDIMetaFile             aTmpMtf;
    1308             : 
    1309           0 :                 maVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
    1310           0 :                 ImplWrite( aTmpMtf );
    1311             :             }
    1312           0 :             break;
    1313             : 
    1314             :             case META_TRANSPARENT_ACTION:
    1315             :             {
    1316           0 :                 const PolyPolygon& rPolyPoly = ( (MetaTransparentAction*) pAction )->GetPolyPolygon();
    1317           0 :                 if( rPolyPoly.Count() )
    1318           0 :                     ImplWritePlusFillPolygonRecord( rPolyPoly[0], ( (MetaTransparentAction*)pAction)->GetTransparence() );
    1319           0 :                 ImplCheckFillAttr();
    1320           0 :                 ImplCheckLineAttr();
    1321           0 :                 ImplWritePolyPolygonRecord( rPolyPoly );
    1322             : 
    1323           0 :                 ImplBeginCommentRecord( WIN_EMR_COMMENT_EMFPLUS );
    1324           0 :                 ImplPlusRecord( EmfPlusGetDC, 0x00 );
    1325           0 :                 ImplEndCommentRecord();
    1326             :             }
    1327           0 :             break;
    1328             : 
    1329             :             case META_FLOATTRANSPARENT_ACTION:
    1330             :             {
    1331           0 :                 const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction;
    1332             : 
    1333           0 :                 GDIMetaFile     aTmpMtf( pA->GetGDIMetaFile() );
    1334           0 :                 Point           aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
    1335           0 :                 const Size      aSrcSize( aTmpMtf.GetPrefSize() );
    1336           0 :                 const Point     aDestPt( pA->GetPoint() );
    1337           0 :                 const Size      aDestSize( pA->GetSize() );
    1338           0 :                 const double    fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
    1339           0 :                 const double    fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
    1340             :                 long            nMoveX, nMoveY;
    1341             : 
    1342           0 :                 if( fScaleX != 1.0 || fScaleY != 1.0 )
    1343             :                 {
    1344           0 :                     aTmpMtf.Scale( fScaleX, fScaleY );
    1345           0 :                     aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
    1346             :                 }
    1347             : 
    1348           0 :                 nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
    1349             : 
    1350           0 :                 if( nMoveX || nMoveY )
    1351           0 :                     aTmpMtf.Move( nMoveX, nMoveY );
    1352             : 
    1353           0 :                 ImplCheckFillAttr();
    1354           0 :                 ImplCheckLineAttr();
    1355           0 :                 ImplCheckTextAttr();
    1356           0 :                 ImplWrite( aTmpMtf );
    1357             :             }
    1358           0 :             break;
    1359             : 
    1360             :             case( META_EPS_ACTION ):
    1361             :             {
    1362           0 :                 const MetaEPSAction*    pA = (const MetaEPSAction*) pAction;
    1363           0 :                 const GDIMetaFile       aSubstitute( pA->GetSubstitute() );
    1364             : 
    1365           0 :                 for( size_t i = 0, nCount = aSubstitute.GetActionSize(); i < nCount; i++ )
    1366             :                 {
    1367           0 :                     const MetaAction* pSubstAct = aSubstitute.GetAction( i );
    1368           0 :                     if( pSubstAct->GetType() == META_BMPSCALE_ACTION )
    1369             :                     {
    1370           0 :                         maVDev.Push( PUSH_ALL );
    1371           0 :                         ImplBeginRecord( WIN_EMR_SAVEDC );
    1372           0 :                         ImplEndRecord();
    1373             : 
    1374           0 :                         MapMode aMapMode( aSubstitute.GetPrefMapMode() );
    1375           0 :                         Size aOutSize( maVDev.LogicToLogic( pA->GetSize(), maVDev.GetMapMode(), aMapMode ) );
    1376           0 :                         aMapMode.SetScaleX( Fraction( aOutSize.Width(), aSubstitute.GetPrefSize().Width() ) );
    1377           0 :                         aMapMode.SetScaleY( Fraction( aOutSize.Height(), aSubstitute.GetPrefSize().Height() ) );
    1378           0 :                         aMapMode.SetOrigin( maVDev.LogicToLogic( pA->GetPoint(), maVDev.GetMapMode(), aMapMode ) );
    1379           0 :                         maVDev.SetMapMode( aMapMode );
    1380           0 :                         ImplWrite( aSubstitute );
    1381             : 
    1382           0 :                         maVDev.Pop();
    1383           0 :                         ImplBeginRecord( WIN_EMR_RESTOREDC );
    1384           0 :                         m_rStm << (sal_Int32) -1;
    1385           0 :                         ImplEndRecord();
    1386           0 :                         break;
    1387             :                     }
    1388           0 :                 }
    1389             :             }
    1390           0 :             break;
    1391             : 
    1392             :             case META_BMP_ACTION:
    1393             :             {
    1394           0 :                 const MetaBmpAction* pA = (const MetaBmpAction *) pAction;
    1395           0 :                 ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), maVDev.PixelToLogic( pA->GetBitmap().GetSizePixel() ), WIN_SRCCOPY );
    1396             :             }
    1397           0 :             break;
    1398             : 
    1399             :             case META_BMPSCALE_ACTION:
    1400             :             {
    1401           0 :                 const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
    1402           0 :                 ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
    1403             :             }
    1404           0 :             break;
    1405             : 
    1406             :             case META_BMPSCALEPART_ACTION:
    1407             :             {
    1408           0 :                 const MetaBmpScalePartAction*   pA = (const MetaBmpScalePartAction*) pAction;
    1409           0 :                 Bitmap                          aTmp( pA->GetBitmap() );
    1410             : 
    1411           0 :                 if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
    1412           0 :                     ImplWriteBmpRecord( aTmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
    1413             :             }
    1414           0 :             break;
    1415             : 
    1416             :             case META_BMPEX_ACTION:
    1417             :             {
    1418           0 :                 const MetaBmpExAction*  pA = (const MetaBmpExAction *) pAction;
    1419           0 :                 Bitmap                  aBmp( pA->GetBitmapEx().GetBitmap() );
    1420           0 :                 Bitmap                  aMsk( pA->GetBitmapEx().GetMask() );
    1421             : 
    1422           0 :                 if( !!aMsk )
    1423             :                 {
    1424           0 :                     aBmp.Replace( aMsk, COL_WHITE );
    1425           0 :                     aMsk.Invert();
    1426           0 :                     ImplWriteBmpRecord( aMsk, pA->GetPoint(), maVDev.PixelToLogic( aMsk.GetSizePixel() ), WIN_SRCPAINT );
    1427           0 :                     ImplWriteBmpRecord( aBmp, pA->GetPoint(), maVDev.PixelToLogic( aBmp.GetSizePixel() ), WIN_SRCAND );
    1428             :                 }
    1429             :                 else
    1430           0 :                     ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCCOPY );
    1431             :             }
    1432           0 :             break;
    1433             : 
    1434             :             case META_BMPEXSCALE_ACTION:
    1435             :             {
    1436           0 :                 const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
    1437           0 :                 Bitmap                      aBmp( pA->GetBitmapEx().GetBitmap() );
    1438           0 :                 Bitmap                      aMsk( pA->GetBitmapEx().GetMask() );
    1439             : 
    1440           0 :                 if( !!aMsk )
    1441             :                 {
    1442           0 :                     aBmp.Replace( aMsk, COL_WHITE );
    1443           0 :                     aMsk.Invert();
    1444           0 :                     ImplWriteBmpRecord( aMsk, pA->GetPoint(), pA->GetSize(), WIN_SRCPAINT );
    1445           0 :                     ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCAND );
    1446             :                 }
    1447             :                 else
    1448           0 :                     ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
    1449             :             }
    1450           0 :             break;
    1451             : 
    1452             :             case META_BMPEXSCALEPART_ACTION:
    1453             :             {
    1454           0 :                 const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction;
    1455           0 :                 BitmapEx                        aBmpEx( pA->GetBitmapEx() );
    1456           0 :                 aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
    1457           0 :                 Bitmap                          aBmp( aBmpEx.GetBitmap() );
    1458           0 :                 Bitmap                          aMsk( aBmpEx.GetMask() );
    1459             : 
    1460           0 :                 if( !!aMsk )
    1461             :                 {
    1462           0 :                     aBmp.Replace( aMsk, COL_WHITE );
    1463           0 :                     aMsk.Invert();
    1464           0 :                     ImplWriteBmpRecord( aMsk, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCPAINT );
    1465           0 :                     ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCAND );
    1466             :                 }
    1467             :                 else
    1468           0 :                     ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
    1469             :             }
    1470           0 :             break;
    1471             : 
    1472             :             case META_TEXT_ACTION:
    1473             :             {
    1474           0 :                 const MetaTextAction*   pA = (const MetaTextAction*) pAction;
    1475           0 :                 const String            aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
    1476             : 
    1477           0 :                 ImplCheckTextAttr();
    1478           0 :                 ImplWriteTextRecord( pA->GetPoint(), aText, NULL, 0 );
    1479             :             }
    1480           0 :             break;
    1481             : 
    1482             :             case META_TEXTRECT_ACTION:
    1483             :             {
    1484           0 :                 const MetaTextRectAction*   pA = (const MetaTextRectAction*) pAction;
    1485           0 :                 const String                aText( pA->GetText() );
    1486             : 
    1487           0 :                 ImplCheckTextAttr();
    1488           0 :                 ImplWriteTextRecord( pA->GetRect().TopLeft(), aText, NULL, 0 );
    1489             :             }
    1490           0 :             break;
    1491             : 
    1492             :             case META_TEXTARRAY_ACTION:
    1493             :             {
    1494           2 :                 const MetaTextArrayAction*  pA = (const MetaTextArrayAction*) pAction;
    1495           2 :                 const String                aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
    1496             : 
    1497           2 :                 ImplCheckTextAttr();
    1498           2 :                 ImplWriteTextRecord( pA->GetPoint(), aText, pA->GetDXArray(), 0 );
    1499             :             }
    1500           2 :             break;
    1501             : 
    1502             :             case META_STRETCHTEXT_ACTION:
    1503             :             {
    1504         331 :                 const MetaStretchTextAction*    pA = (const MetaStretchTextAction*) pAction;
    1505         331 :                 const String                    aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
    1506             : 
    1507         331 :                 ImplCheckTextAttr();
    1508         331 :                 ImplWriteTextRecord( pA->GetPoint(), aText, NULL, pA->GetWidth() );
    1509             :             }
    1510         331 :             break;
    1511             : 
    1512             :             case( META_LINECOLOR_ACTION ):
    1513             :             {
    1514          21 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1515          21 :                 mbLineChanged = sal_True;
    1516             :             }
    1517          21 :             break;
    1518             : 
    1519             :             case( META_FILLCOLOR_ACTION ):
    1520             :             {
    1521          19 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1522          19 :                 mbFillChanged = sal_True;
    1523             :             }
    1524          19 :             break;
    1525             : 
    1526             :             case( META_TEXTCOLOR_ACTION ):
    1527             :             case( META_TEXTLINECOLOR_ACTION ):
    1528             :             case( META_TEXTFILLCOLOR_ACTION ):
    1529             :             case( META_TEXTALIGN_ACTION ):
    1530             :             case( META_FONT_ACTION ):
    1531             :             {
    1532        1408 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1533        1408 :                 mbTextChanged = sal_True;
    1534             :             }
    1535        1408 :             break;
    1536             : 
    1537             :             case( META_ISECTRECTCLIPREGION_ACTION ):
    1538             :             {
    1539          29 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1540             : 
    1541          29 :                 ImplBeginRecord( WIN_EMR_INTERSECTCLIPRECT );
    1542          29 :                 ImplWriteRect( ( (MetaISectRectClipRegionAction*) pAction )->GetRect() );
    1543          29 :                 ImplEndRecord();
    1544             :             }
    1545          29 :             break;
    1546             : 
    1547             :             case( META_CLIPREGION_ACTION ):
    1548             :             case( META_ISECTREGIONCLIPREGION_ACTION ):
    1549             :             case( META_MOVECLIPREGION_ACTION ):
    1550             :             {
    1551           4 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1552             :             }
    1553           4 :             break;
    1554             : 
    1555             :             case( META_REFPOINT_ACTION ):
    1556             :             case( META_MAPMODE_ACTION ):
    1557           0 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1558           0 :             break;
    1559             : 
    1560             :             case( META_PUSH_ACTION ):
    1561             :             {
    1562         384 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1563             : 
    1564         384 :                 ImplBeginRecord( WIN_EMR_SAVEDC );
    1565         384 :                 ImplEndRecord();
    1566             :             }
    1567         384 :             break;
    1568             : 
    1569             :             case( META_POP_ACTION ):
    1570             :             {
    1571         384 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1572             : 
    1573         384 :                 ImplBeginRecord( WIN_EMR_RESTOREDC );
    1574         384 :                 m_rStm << (sal_Int32) -1;
    1575         384 :                 ImplEndRecord();
    1576             : 
    1577         384 :                 ImplWriteRasterOp( maVDev.GetRasterOp() );
    1578         384 :                 mbLineChanged = mbFillChanged = mbTextChanged = sal_True;
    1579             :             }
    1580         384 :             break;
    1581             : 
    1582             :             case( META_RASTEROP_ACTION ):
    1583             :             {
    1584           0 :                 ( (MetaAction*) pAction )->Execute( &maVDev );
    1585           0 :                 ImplWriteRasterOp( ( (MetaRasterOpAction*) pAction )->GetRasterOp() );
    1586             :             }
    1587           0 :             break;
    1588             : 
    1589             :             case( META_LAYOUTMODE_ACTION ):
    1590             :             {
    1591          60 :                 sal_uInt32 nLayoutMode = ( (MetaLayoutModeAction*) pAction )->GetLayoutMode();
    1592          60 :                 mnHorTextAlign = 0;
    1593          60 :                 if (nLayoutMode & TEXT_LAYOUT_BIDI_RTL)
    1594             :                 {
    1595           0 :                     mnHorTextAlign = TA_RIGHT | TA_RTLREADING;
    1596             :                 }
    1597          60 :                 if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_RIGHT)
    1598           0 :                     mnHorTextAlign |= TA_RIGHT;
    1599          60 :                 else if (nLayoutMode & TEXT_LAYOUT_TEXTORIGIN_LEFT)
    1600           0 :                     mnHorTextAlign &= ~TA_RIGHT;
    1601          60 :                 break;
    1602             :             }
    1603             : 
    1604             :             case( META_MASK_ACTION ):
    1605             :             case( META_MASKSCALE_ACTION ):
    1606             :             case( META_MASKSCALEPART_ACTION ):
    1607             :             case( META_WALLPAPER_ACTION ):
    1608             :             case( META_TEXTLINE_ACTION ):
    1609             :             case( META_COMMENT_ACTION ):
    1610             :             case( META_GRADIENTEX_ACTION ):
    1611             :             {
    1612             :                 // !!! >>> we don't want to support these actions
    1613             :             }
    1614           0 :             break;
    1615             : 
    1616             :             default:
    1617             :                 OSL_FAIL(rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM(
    1618             :                     "EMFWriter::ImplWriteActions: unsupported MetaAction #" )).
    1619             :                      append(static_cast<sal_Int32>(nType)).getStr());
    1620          90 :             break;
    1621             :         }
    1622             :     }
    1623          30 : }
    1624             : 
    1625             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10