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

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

Generated by: LCOV version 1.10