LCOV - code coverage report
Current view: top level - vcl/source/filter/wmf - enhwmf.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 1 744 0.1 %
Date: 2014-04-14 Functions: 2 20 10.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "winmtf.hxx"
      21             : #include <osl/endian.h>
      22             : #include <basegfx/matrix/b2dhommatrix.hxx>
      23             : #include <boost/bind.hpp>
      24             : #include <vcl/dibtools.hxx>
      25             : #include <boost/scoped_array.hpp>
      26             : 
      27             : using namespace std;
      28             : 
      29             : // GDI-Array
      30             : 
      31             : #define EMR_HEADER                      1
      32             : #define EMR_POLYBEZIER                  2
      33             : #define EMR_POLYGON                     3
      34             : #define EMR_POLYLINE                    4
      35             : #define EMR_POLYBEZIERTO                5
      36             : #define EMR_POLYLINETO                  6
      37             : #define EMR_POLYPOLYLINE                7
      38             : #define EMR_POLYPOLYGON                 8
      39             : #define EMR_SETWINDOWEXTEX              9
      40             : #define EMR_SETWINDOWORGEX              10
      41             : #define EMR_SETVIEWPORTEXTEX            11
      42             : #define EMR_SETVIEWPORTORGEX            12
      43             : #define EMR_SETBRUSHORGEX               13
      44             : #define EMR_EOF                         14
      45             : #define EMR_SETPIXELV                   15
      46             : #define EMR_SETMAPPERFLAGS              16
      47             : #define EMR_SETMAPMODE                  17
      48             : #define EMR_SETBKMODE                   18
      49             : #define EMR_SETPOLYFILLMODE             19
      50             : #define EMR_SETROP2                     20
      51             : #define EMR_SETSTRETCHBLTMODE           21
      52             : #define EMR_SETTEXTALIGN                22
      53             : #define EMR_SETCOLORADJUSTMENT          23
      54             : #define EMR_SETTEXTCOLOR                24
      55             : #define EMR_SETBKCOLOR                  25
      56             : #define EMR_OFFSETCLIPRGN               26
      57             : #define EMR_MOVETOEX                    27
      58             : #define EMR_SETMETARGN                  28
      59             : #define EMR_EXCLUDECLIPRECT             29
      60             : #define EMR_INTERSECTCLIPRECT           30
      61             : #define EMR_SCALEVIEWPORTEXTEX          31
      62             : #define EMR_SCALEWINDOWEXTEX            32
      63             : #define EMR_SAVEDC                      33
      64             : #define EMR_RESTOREDC                   34
      65             : #define EMR_SETWORLDTRANSFORM           35
      66             : #define EMR_MODIFYWORLDTRANSFORM        36
      67             : #define EMR_SELECTOBJECT                37
      68             : #define EMR_CREATEPEN                   38
      69             : #define EMR_CREATEBRUSHINDIRECT         39
      70             : #define EMR_DELETEOBJECT                40
      71             : #define EMR_ANGLEARC                    41
      72             : #define EMR_ELLIPSE                     42
      73             : #define EMR_RECTANGLE                   43
      74             : #define EMR_ROUNDRECT                   44
      75             : #define EMR_ARC                         45
      76             : #define EMR_CHORD                       46
      77             : #define EMR_PIE                         47
      78             : #define EMR_SELECTPALETTE               48
      79             : #define EMR_CREATEPALETTE               49
      80             : #define EMR_SETPALETTEENTRIES           50
      81             : #define EMR_RESIZEPALETTE               51
      82             : #define EMR_REALIZEPALETTE              52
      83             : #define EMR_EXTFLOODFILL                53
      84             : #define EMR_LINETO                      54
      85             : #define EMR_ARCTO                       55
      86             : #define EMR_POLYDRAW                    56
      87             : #define EMR_SETARCDIRECTION             57
      88             : #define EMR_SETMITERLIMIT               58
      89             : #define EMR_BEGINPATH                   59
      90             : #define EMR_ENDPATH                     60
      91             : #define EMR_CLOSEFIGURE                 61
      92             : #define EMR_FILLPATH                    62
      93             : #define EMR_STROKEANDFILLPATH           63
      94             : #define EMR_STROKEPATH                  64
      95             : #define EMR_FLATTENPATH                 65
      96             : #define EMR_WIDENPATH                   66
      97             : #define EMR_SELECTCLIPPATH              67
      98             : #define EMR_ABORTPATH                   68
      99             : 
     100             : #define EMR_GDICOMMENT                  70
     101             : #define EMR_FILLRGN                     71
     102             : #define EMR_FRAMERGN                    72
     103             : #define EMR_INVERTRGN                   73
     104             : #define EMR_PAINTRGN                    74
     105             : #define EMR_EXTSELECTCLIPRGN            75
     106             : #define EMR_BITBLT                      76
     107             : #define EMR_STRETCHBLT                  77
     108             : #define EMR_MASKBLT                     78
     109             : #define EMR_PLGBLT                      79
     110             : #define EMR_SETDIBITSTODEVICE           80
     111             : #define EMR_STRETCHDIBITS               81
     112             : #define EMR_EXTCREATEFONTINDIRECTW      82
     113             : #define EMR_EXTTEXTOUTA                 83
     114             : #define EMR_EXTTEXTOUTW                 84
     115             : #define EMR_POLYBEZIER16                85
     116             : #define EMR_POLYGON16                   86
     117             : #define EMR_POLYLINE16                  87
     118             : #define EMR_POLYBEZIERTO16              88
     119             : #define EMR_POLYLINETO16                89
     120             : #define EMR_POLYPOLYLINE16              90
     121             : #define EMR_POLYPOLYGON16               91
     122             : #define EMR_POLYDRAW16                  92
     123             : #define EMR_CREATEMONOBRUSH             93
     124             : #define EMR_CREATEDIBPATTERNBRUSHPT     94
     125             : #define EMR_EXTCREATEPEN                95
     126             : #define EMR_POLYTEXTOUTA                96
     127             : #define EMR_POLYTEXTOUTW                97
     128             : 
     129             : // WINDOWS VERSION >= 0x400
     130             : #define EMR_SETICMMODE                  98
     131             : #define EMR_CREATECOLORSPACE            99
     132             : #define EMR_SETCOLORSPACE              100
     133             : #define EMR_DELETECOLORSPACE           101
     134             : #define EMR_GLSRECORD                  102
     135             : #define EMR_GLSBOUNDEDRECORD           103
     136             : #define EMR_PIXELFORMAT                104
     137             : 
     138             : // WINDOWS VERSION >= 0x500
     139             : #define EMR_DRAWESCAPE                 105
     140             : #define EMR_EXTESCAPE                  106
     141             : #define EMR_STARTDOC                   107
     142             : #define EMR_SMALLTEXTOUT               108
     143             : #define EMR_FORCEUFIMAPPING            109
     144             : #define EMR_NAMEDESCAPE                110
     145             : #define EMR_COLORCORRECTPALETTE        111
     146             : #define EMR_SETICMPROFILEA             112
     147             : #define EMR_SETICMPROFILEW             113
     148             : #define EMR_ALPHABLEND                 114
     149             : #define EMR_ALPHADIBBLEND              115
     150             : #define EMR_TRANSPARENTBLT             116
     151             : #define EMR_TRANSPARENTDIB             117
     152             : #define EMR_GRADIENTFILL               118
     153             : #define EMR_SETLINKEDUFIS              119
     154             : #define EMR_SETTEXTJUSTIFICATION       120
     155             : 
     156             : #ifdef OSL_BIGENDIAN
     157             : // little endian <-> big endian switch
     158             : static float GetSwapFloat( SvStream& rSt )
     159             : {
     160             :     float   fTmp;
     161             :     sal_Int8* pPtr = (sal_Int8*)&fTmp;
     162             :     rSt.ReadSChar( pPtr[3] );
     163             :     rSt.ReadSChar( pPtr[2] );
     164             :     rSt.ReadSChar( pPtr[1] );
     165             :     rSt.ReadSChar( pPtr[0] );
     166             :     return fTmp;
     167             : }
     168             : #endif
     169             : 
     170             : struct BLENDFUNCTION{
     171             :     unsigned char aBlendOperation;
     172             :     unsigned char aBlendFlags;
     173             :     unsigned char aSrcConstantAlpha;
     174             :     unsigned char aAlphaFormat;
     175             : 
     176             :     friend SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun );
     177             : };
     178             : 
     179           0 : SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun )
     180             : {
     181           0 :     rIn.ReadUChar( rBlendFun.aBlendOperation ).ReadUChar( rBlendFun.aBlendFlags ).ReadUChar( rBlendFun.aSrcConstantAlpha ).ReadUChar( rBlendFun.aAlphaFormat );
     182           0 :     return rIn;
     183             : }
     184             : 
     185           0 : SvStream& operator>>( SvStream& rIn, XForm& rXForm )
     186             : {
     187             :     if ( sizeof( float ) != 4 )
     188             :     {
     189             :         OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
     190             :         rXForm = XForm();
     191             :     }
     192             :     else
     193             :     {
     194             : #ifdef OSL_BIGENDIAN
     195             :     rXForm.eM11 = GetSwapFloat( rIn );
     196             :     rXForm.eM12 = GetSwapFloat( rIn );
     197             :     rXForm.eM21 = GetSwapFloat( rIn );
     198             :     rXForm.eM22 = GetSwapFloat( rIn );
     199             :     rXForm.eDx = GetSwapFloat( rIn );
     200             :     rXForm.eDy = GetSwapFloat( rIn );
     201             : #else
     202           0 :     rIn.ReadFloat( rXForm.eM11 ).ReadFloat( rXForm.eM12 ).ReadFloat( rXForm.eM21 ).ReadFloat( rXForm.eM22 )
     203           0 :            .ReadFloat( rXForm.eDx ).ReadFloat( rXForm.eDy );
     204             : #endif
     205             :     }
     206           0 :     return rIn;
     207             : }
     208             : 
     209           0 : static bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt32 nLen )
     210             : {
     211           0 :     bool bOk = false;
     212           0 :     if ( nLen )
     213             :     {
     214             :         sal_uInt32 nHdSize, nType, nCount, nRgnSize, i;
     215           0 :         rSt.ReadUInt32( nHdSize )
     216           0 :            .ReadUInt32( nType )
     217           0 :            .ReadUInt32( nCount )
     218           0 :            .ReadUInt32( nRgnSize );
     219             : 
     220           0 :         if ( nCount && ( nType == RDH_RECTANGLES ) &&
     221           0 :                 ( nLen >= ( ( nCount << 4 ) + ( nHdSize - 16 ) ) ) )
     222             :         {
     223             :             sal_Int32 nx1, ny1, nx2, ny2;
     224             : 
     225           0 :             for ( i = 0; i < nCount; i++ )
     226             :             {
     227           0 :                 rSt.ReadInt32( nx1 ).ReadInt32( ny1 ).ReadInt32( nx2 ).ReadInt32( ny2 );
     228             : 
     229           0 :                 Rectangle aRect( Point( nx1, ny1 ), Point( nx2, ny2 ) );
     230           0 :                 Polygon aPolygon( aRect );
     231           0 :                 PolyPolygon aPolyPolyOr1( aPolygon );
     232           0 :                 PolyPolygon aPolyPolyOr2( rPolyPoly );
     233           0 :                 rPolyPoly.GetUnion( aPolyPolyOr1, aPolyPolyOr2 );
     234           0 :                 rPolyPoly = aPolyPolyOr2;
     235           0 :             }
     236           0 :             bOk = true;
     237             :         }
     238             :     }
     239           0 :     return bOk;
     240             : }
     241             : 
     242           0 : void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC)
     243             : {
     244           0 :     if (!bEMFPlus) {
     245           0 :         pOut->PassEMFPlusHeaderInfo();
     246             : 
     247             : #if OSL_DEBUG_LEVEL > 1
     248             :         // debug code - write the stream to debug file /tmp/emf-stream.emf
     249             :         int pos = pWMF->Tell();
     250             :         pWMF->Seek(0);
     251             :         SvFileStream file( OUString( "/tmp/emf-stream.emf" ), STREAM_WRITE | STREAM_TRUNC );
     252             : 
     253             :         pWMF->WriteStream(file);
     254             :         file.Flush();
     255             :         file.Close();
     256             : 
     257             :         pWMF->Seek( pos );
     258             : #endif
     259             : 
     260             :     }
     261           0 :     bEMFPlus = true;
     262             : 
     263           0 :     sal_Size pos = pWMF->Tell();
     264           0 :     void *buffer = malloc( length );
     265           0 :     pOut->PassEMFPlus( buffer, pWMF->Read( buffer, length ) );
     266           0 :     free( buffer );
     267           0 :     pWMF->Seek( pos );
     268             : 
     269           0 :     bHaveDC = false;
     270             : 
     271             :     OSL_ASSERT(length >= 4);
     272             :     // reduce by 32bit length itself, skip in SeekRel if
     273             :     // impossibly unavailable
     274           0 :     sal_uInt32 nRemainder = length >= 4 ? length-4 : length;
     275             : 
     276           0 :     const size_t nRequiredHeaderSize = 12;
     277           0 :     while (nRemainder >= nRequiredHeaderSize)
     278             :     {
     279           0 :         sal_uInt16 type(0), flags(0);
     280           0 :         sal_uInt32 size(0), dataSize(0);
     281             : 
     282           0 :         pWMF->ReadUInt16( type ).ReadUInt16( flags ).ReadUInt32( size ).ReadUInt32( dataSize );
     283           0 :         nRemainder -= nRequiredHeaderSize;
     284             : 
     285             :         SAL_INFO ("vcl.emf", "\t\tEMF+ record type: " << std::hex << type << std::dec);
     286             : 
     287             :         // GetDC
     288           0 :         if( type == 16388 ) {
     289           0 :             bHaveDC = true;
     290             :             SAL_INFO ("vcl.emf", "\t\tEMF+ lock DC (device context)");
     291             :         }
     292             : 
     293             :         // Get the length of the remaining data of this record based
     294             :         // on the alleged size
     295           0 :         sal_uInt32 nRemainingRecordData = size >= nRequiredHeaderSize ?
     296           0 :             size-nRequiredHeaderSize : 0;
     297             :         // clip to available size
     298           0 :         nRemainingRecordData = std::min(nRemainingRecordData, nRemainder);
     299           0 :         pWMF->SeekRel(nRemainingRecordData);
     300           0 :         nRemainder -= nRemainingRecordData;
     301             :     }
     302           0 :     pWMF->SeekRel(nRemainder);
     303           0 : }
     304             : 
     305             : /**
     306             :  * Reads polygons from the stream.
     307             :  * The \<class T> parameter is for the type of the points (sal_uInt32 or sal_uInt16).
     308             :  * The \<class Drawer> parameter is a boost binding for the method that will draw the polygon.
     309             :  * skipFirst: if the first point read is the 0th point or the 1st point in the array.
     310             :  * */
     311             : template <class T, class Drawer>
     312           0 : void EnhWMFReader::ReadAndDrawPolygon(Drawer drawer, const bool skipFirst)
     313             : {
     314           0 :     sal_uInt32 nPoints(0), nStartIndex(0);
     315           0 :     pWMF->SeekRel( 16 );
     316           0 :     pWMF->ReadUInt32( nPoints );
     317           0 :     if (skipFirst)
     318             :     {
     319           0 :         nPoints ++;
     320           0 :         nStartIndex ++;
     321             :     }
     322             : 
     323           0 :     Polygon aPolygon = ReadPolygon<T>(nStartIndex, nPoints);
     324           0 :     drawer(pOut, aPolygon, skipFirst, bRecordPath);
     325           0 : }
     326             : 
     327             : /**
     328             :  * Reads polygons from the stream.
     329             :  * The \<class T> parameter is for the type of the points
     330             :  * nStartIndex: which is the starting index in the polygon of the first point read
     331             :  * nPoints: number of points
     332             :  * pWMF: the stream containings the polygons
     333             :  * */
     334             : template <class T>
     335           0 : Polygon EnhWMFReader::ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints)
     336             : {
     337           0 :     bool bRecordOk = nPoints <= SAL_MAX_UINT16;
     338             :     SAL_WARN_IF(!bRecordOk, "vcl.filter", "polygon record has more polygons than we can handle");
     339           0 :     if (!bRecordOk)
     340           0 :         return Polygon();
     341             : 
     342           0 :     Polygon aPolygon(nPoints);
     343           0 :     for (sal_uInt16 i = nStartIndex ; i < nPoints && pWMF->good(); i++ )
     344             :     {
     345             :         T nX, nY;
     346           0 :         *pWMF >> nX >> nY;
     347           0 :         if (!pWMF->good())
     348           0 :             break;
     349           0 :         aPolygon[ i ] = Point( nX, nY );
     350             :     }
     351             : 
     352           0 :     return aPolygon;
     353             : }
     354             : 
     355             : /**
     356             :  * Reads a polyline from the WMF file and draws it
     357             :  * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
     358             :  * */
     359             : template <class T>
     360           0 : void EnhWMFReader::ReadAndDrawPolyLine()
     361             : {
     362             :     sal_uInt32  nPoints;
     363           0 :     sal_Int32   i, nPoly(0), nGesPoints(0);
     364           0 :     pWMF->SeekRel( 0x10 );
     365             :     // Number of Polygons:
     366           0 :     pWMF->ReadInt32( nPoly ).ReadInt32( nGesPoints );
     367             : 
     368             :     // taking the amount of points of each polygon, retrieving the total number of points
     369           0 :     if ( pWMF->good() &&
     370             :          ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) &&
     371           0 :          ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() )
     372             :        )
     373             :     {
     374           0 :         boost::scoped_array<sal_uInt16> pnPoints(new sal_uInt16[ nPoly ]);
     375           0 :         for ( i = 0; i < nPoly && pWMF->good(); i++ )
     376             :         {
     377           0 :             pWMF->ReadUInt32( nPoints );
     378           0 :             pnPoints[ i ] = (sal_uInt16)nPoints;
     379             :         }
     380             :         // Get polygon points:
     381           0 :         for ( i = 0; ( i < nPoly ) && pWMF->good(); i++ )
     382             :         {
     383           0 :             Polygon aPolygon = ReadPolygon<T>(0, pnPoints[i]);
     384           0 :             pOut->DrawPolyLine( aPolygon, false, bRecordPath );
     385           0 :         }
     386             :     }
     387           0 : }
     388             : 
     389             : // these are referenced from inside the templates
     390             : 
     391           0 : SvStream& operator>>(SvStream& rStream, sal_Int16 &n)
     392             : {
     393           0 :     return rStream.ReadInt16(n);
     394             : }
     395             : 
     396           0 : SvStream& operator>>(SvStream& rStream, sal_Int32 &n)
     397             : {
     398           0 :     return rStream.ReadInt32(n);
     399             : }
     400             : 
     401             : /**
     402             :  * Reads a poly polygon from the WMF file and draws it.
     403             :  * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
     404             :  * */
     405             : template <class T>
     406           0 : void EnhWMFReader::ReadAndDrawPolyPolygon()
     407             : {
     408           0 :     sal_uInt32 nPoly(0), nGesPoints(0), nReadPoints(0);
     409           0 :     pWMF->SeekRel( 0x10 );
     410             :     // Number of polygons
     411           0 :     pWMF->ReadUInt32( nPoly ).ReadUInt32( nGesPoints );
     412           0 :     if ( pWMF->good() &&
     413             :         ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && //check against numeric overflowing
     414             :         ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) &&
     415           0 :         ( (  nPoly * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() ) ))
     416             :     {
     417             :         // Get number of points in each polygon
     418           0 :         boost::scoped_array<sal_uInt16> pnPoints(new sal_uInt16[ nPoly ]);
     419           0 :         for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i)
     420             :         {
     421           0 :             sal_uInt32 nPoints(0);
     422           0 :             pWMF->ReadUInt32( nPoints );
     423           0 :             pnPoints[ i ] = (sal_uInt16)nPoints;
     424             :         }
     425           0 :         if ( pWMF->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( nEndPos - pWMF->Tell() ) )
     426             :         {
     427             :             // Get polygon points
     428           0 :             PolyPolygon aPolyPoly(nPoly, nPoly);
     429           0 :             for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i)
     430             :             {
     431           0 :                 const sal_uInt16 nPointCount(pnPoints[i]);
     432           0 :                 boost::scoped_array<Point> pPtAry(new Point[nPointCount]);
     433           0 :                 for (sal_uInt16 j = 0; j < nPointCount && pWMF->good(); ++j)
     434             :                 {
     435           0 :                     T nX(0), nY(0);
     436           0 :                     *pWMF >> nX >> nY;
     437           0 :                     pPtAry[ j ] = Point( nX, nY );
     438           0 :                     ++nReadPoints;
     439             :                 }
     440             : 
     441           0 :                 aPolyPoly.Insert(Polygon(nPointCount, pPtAry.get()));
     442             :             }
     443             : 
     444           0 :             pOut->DrawPolyPolygon( aPolyPoly, bRecordPath );
     445             :         }
     446             : 
     447           0 :         OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)");
     448             : 
     449             :     }
     450           0 : }
     451             : 
     452           0 : bool EnhWMFReader::ReadEnhWMF()
     453             : {
     454           0 :     sal_uInt32  nStretchBltMode = 0;
     455           0 :     sal_uInt32  nRecType(0), nRecSize(0), nNextPos(0),
     456           0 :                 nW(0), nH(0), nColor(0), nIndex(0),
     457           0 :                 nDat32(0), nNom1(0), nDen1(0), nNom2(0), nDen2(0);
     458           0 :     sal_Int32   nX32(0), nY32(0), nx32(0), ny32(0);
     459             : 
     460           0 :     bool    bFlag(false), bStatus = ReadHeader();
     461           0 :     bool    bHaveDC = false;
     462             : 
     463           0 :     static bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == NULL );
     464             : 
     465           0 :     while( bStatus && nRecordCount-- && pWMF->good())
     466             :     {
     467           0 :         pWMF->ReadUInt32( nRecType ).ReadUInt32( nRecSize );
     468             : 
     469           0 :         if ( !pWMF->good() || ( nRecSize < 8 ) || ( nRecSize & 3 ) )     // Parameters are always divisible by 4
     470             :         {
     471           0 :             bStatus = false;
     472           0 :             break;
     473             :         }
     474             : 
     475           0 :         nNextPos = pWMF->Tell() + ( nRecSize - 8 );
     476             : 
     477           0 :         if ( !pWMF->good() || nNextPos > nEndPos )
     478             :         {
     479           0 :             bStatus = false;
     480           0 :             break;
     481             :         }
     482             : 
     483           0 :         if(  !aBmpSaveList.empty()
     484           0 :           && ( nRecType != EMR_STRETCHBLT )
     485           0 :           && ( nRecType != EMR_STRETCHDIBITS )
     486             :           ) {
     487           0 :             pOut->ResolveBitmapActions( aBmpSaveList );
     488             :         }
     489             : 
     490           0 :         bFlag = false;
     491             : 
     492             :         SAL_INFO ("vcl.emf", "0x" << std::hex << (nNextPos - nRecSize) <<  "-0x" << nNextPos << " record type: " << std::dec << nRecType << " size: " <<  nRecSize << std::dec);
     493             : 
     494           0 :         if( bEnableEMFPlus && nRecType == EMR_GDICOMMENT ) {
     495             :             sal_uInt32 length;
     496             : 
     497           0 :             pWMF->ReadUInt32( length );
     498             : 
     499             :             SAL_INFO("vcl.emf", "\tGDI comment, length: " << length);
     500             : 
     501           0 :             if( pWMF->good() && length >= 4 ) {
     502             :                 sal_uInt32 id;
     503             : 
     504           0 :                 pWMF->ReadUInt32( id );
     505             : 
     506             :                 SAL_INFO ("vcl.emf", "\t\tbegin " << (char)(id & 0xff) << (char)((id & 0xff00) >> 8) << (char)((id & 0xff0000) >> 16) << (char)((id & 0xff000000) >> 24) << " id: 0x" << std::hex << id << std::dec);
     507             : 
     508             :                 // EMF+ comment (FIXME: BE?)
     509           0 :                 if( id == 0x2B464D45 && nRecSize >= 12 )
     510           0 :                     ReadEMFPlusComment( length, bHaveDC );
     511             :                 // GDIC comment, doesn't do anything useful yet
     512           0 :                 else if( id == 0x43494447 && nRecSize >= 12 ) {
     513             :                     // TODO: ReadGDIComment()
     514             :                 } else {
     515             :                     SAL_INFO ("vcl.emf", "\t\tunknown id: 0x" << std::hex << id << std::dec);
     516             :                 }
     517           0 :             }
     518             :         }
     519           0 :         else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
     520             :         {
     521           0 :             switch( nRecType )
     522             :             {
     523             :                 case EMR_POLYBEZIERTO :
     524           0 :                     ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, _2, _3, _4), true);
     525           0 :                 break;
     526             :                 case EMR_POLYBEZIER :
     527           0 :                     ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, _2, _3, _4), false);
     528           0 :                 break;
     529             : 
     530             :                 case EMR_POLYGON :
     531           0 :                     ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolygon, _1, _2, _3, _4), false);
     532           0 :                 break;
     533             : 
     534             :                 case EMR_POLYLINETO :
     535           0 :                     ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, _3, _4), true);
     536           0 :                 break;
     537             :                 case EMR_POLYLINE :
     538           0 :                     ReadAndDrawPolygon<sal_Int32>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, _3, _4), false);
     539           0 :                 break;
     540             : 
     541             :                 case EMR_POLYPOLYLINE :
     542           0 :                     ReadAndDrawPolyLine<sal_Int32>();
     543           0 :                 break;
     544             : 
     545             :                 case EMR_POLYPOLYGON :
     546           0 :                     ReadAndDrawPolyPolygon<sal_Int32>();
     547           0 :                 break;
     548             : 
     549             :                 case EMR_SETWINDOWEXTEX :
     550             :                 {                                                       // #75383#
     551           0 :                     pWMF->ReadUInt32( nW ).ReadUInt32( nH );
     552           0 :                     pOut->SetWinExt( Size( nW, nH ), true);
     553             :                 }
     554           0 :                 break;
     555             : 
     556             :                 case EMR_SETWINDOWORGEX :
     557             :                 {
     558           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
     559           0 :                     pOut->SetWinOrg( Point( nX32, nY32 ), true);
     560             :                 }
     561           0 :                 break;
     562             : 
     563             :                 case EMR_SCALEWINDOWEXTEX :
     564             :                 {
     565           0 :                     pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
     566           0 :                     pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
     567             :                 }
     568           0 :                 break;
     569             : 
     570             :                 case EMR_SETVIEWPORTORGEX :
     571             :                 {
     572           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
     573           0 :                     pOut->SetDevOrg( Point( nX32, nY32 ) );
     574             :                 }
     575           0 :                 break;
     576             : 
     577             :                 case EMR_SCALEVIEWPORTEXTEX :
     578             :                 {
     579           0 :                     pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
     580           0 :                     pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
     581             :                 }
     582           0 :                 break;
     583             : 
     584             :                 case EMR_SETVIEWPORTEXTEX :
     585             :                 {
     586           0 :                     pWMF->ReadUInt32( nW ).ReadUInt32( nH );
     587           0 :                     pOut->SetDevExt( Size( nW, nH ) );
     588             :                 }
     589           0 :                 break;
     590             : 
     591             :                 case EMR_EOF :
     592           0 :                     nRecordCount = 0;           // #76846#
     593           0 :                 break;
     594             : 
     595             :                 case EMR_SETPIXELV :
     596             :                 {
     597           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
     598           0 :                     pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() );
     599             :                 }
     600           0 :                 break;
     601             : 
     602             :                 case EMR_SETMAPMODE :
     603             :                 {
     604             :                     sal_uInt32 nMapMode;
     605           0 :                     pWMF->ReadUInt32( nMapMode );
     606           0 :                     pOut->SetMapMode( nMapMode );
     607             :                 }
     608           0 :                 break;
     609             : 
     610             :                 case EMR_SETBKMODE :
     611             :                 {
     612           0 :                     pWMF->ReadUInt32( nDat32 );
     613           0 :                     pOut->SetBkMode( nDat32 );
     614             :                 }
     615           0 :                 break;
     616             : 
     617             :                 case EMR_SETPOLYFILLMODE :
     618           0 :                 break;
     619             : 
     620             :                 case EMR_SETROP2 :
     621             :                 {
     622           0 :                     pWMF->ReadUInt32( nDat32 );
     623           0 :                     pOut->SetRasterOp( nDat32 );
     624             :                 }
     625           0 :                 break;
     626             : 
     627             :                 case EMR_SETSTRETCHBLTMODE :
     628             :                 {
     629           0 :                     pWMF->ReadUInt32( nStretchBltMode );
     630             :                 }
     631           0 :                 break;
     632             : 
     633             :                 case EMR_SETTEXTALIGN :
     634             :                 {
     635           0 :                     pWMF->ReadUInt32( nDat32 );
     636           0 :                     pOut->SetTextAlign( nDat32 );
     637             :                 }
     638           0 :                 break;
     639             : 
     640             :                 case EMR_SETTEXTCOLOR :
     641             :                 {
     642           0 :                     pOut->SetTextColor( ReadColor() );
     643             :                 }
     644           0 :                 break;
     645             : 
     646             :                 case EMR_SETBKCOLOR :
     647             :                 {
     648           0 :                     pOut->SetBkColor( ReadColor() );
     649             :                 }
     650           0 :                 break;
     651             : 
     652             :                 case EMR_OFFSETCLIPRGN :
     653             :                 {
     654           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
     655           0 :                     pOut->MoveClipRegion( Size( nX32, nY32 ) );
     656             :                 }
     657           0 :                 break;
     658             : 
     659             :                 case EMR_MOVETOEX :
     660             :                 {
     661           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
     662           0 :                     pOut->MoveTo( Point( nX32, nY32 ), bRecordPath );
     663             :                 }
     664           0 :                 break;
     665             : 
     666             :                 case EMR_INTERSECTCLIPRECT :
     667             :                 {
     668           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
     669           0 :                     pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
     670             :                 }
     671           0 :                 break;
     672             : 
     673             :                 case EMR_SAVEDC :
     674             :                 {
     675           0 :                     pOut->Push();
     676             :                 }
     677           0 :                 break;
     678             : 
     679             :                 case EMR_RESTOREDC :
     680             :                 {
     681           0 :                     pOut->Pop();
     682             :                 }
     683           0 :                 break;
     684             : 
     685             :                 case EMR_SETWORLDTRANSFORM :
     686             :                 {
     687           0 :                     XForm aTempXForm;
     688           0 :                     *pWMF >> aTempXForm;
     689           0 :                     pOut->SetWorldTransform( aTempXForm );
     690             :                 }
     691           0 :                 break;
     692             : 
     693             :                 case EMR_MODIFYWORLDTRANSFORM :
     694             :                 {
     695             :                     sal_uInt32  nMode;
     696           0 :                     XForm   aTempXForm;
     697           0 :                     *pWMF >> aTempXForm;
     698           0 :                     pWMF->ReadUInt32( nMode );
     699           0 :                     pOut->ModifyWorldTransform( aTempXForm, nMode );
     700             :                 }
     701           0 :                 break;
     702             : 
     703             :                 case EMR_SELECTOBJECT :
     704             :                 {
     705           0 :                     pWMF->ReadUInt32( nIndex );
     706           0 :                     pOut->SelectObject( nIndex );
     707             :                 }
     708           0 :                 break;
     709             : 
     710             :                 case EMR_CREATEPEN :
     711             :                 {
     712           0 :                     pWMF->ReadUInt32( nIndex );
     713           0 :                     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     714             :                     {
     715             : 
     716           0 :                         LineInfo    aLineInfo;
     717             :                         sal_uInt32      nStyle;
     718           0 :                         Size        aSize;
     719             :                         // #fdo39428 Remove SvStream operator>>(long&)
     720           0 :                         sal_Int32 nTmpW(0), nTmpH(0);
     721             : 
     722           0 :                         pWMF->ReadUInt32( nStyle ).ReadInt32( nTmpW ).ReadInt32( nTmpH );
     723           0 :                         aSize.Width() = nTmpW;
     724           0 :                         aSize.Height() = nTmpH;
     725             : 
     726           0 :                         if ( aSize.Width() )
     727           0 :                             aLineInfo.SetWidth( aSize.Width() );
     728             : 
     729           0 :                         bool bTransparent = false;
     730           0 :                         switch( nStyle & 0xFF )
     731             :                         {
     732             :                             case PS_DASHDOTDOT :
     733           0 :                                 aLineInfo.SetStyle( LINE_DASH );
     734           0 :                                 aLineInfo.SetDashCount( 1 );
     735           0 :                                 aLineInfo.SetDotCount( 2 );
     736           0 :                                 aLineInfo.SetDashLen( 150 );
     737           0 :                                 aLineInfo.SetDotLen( 30 );
     738           0 :                                 aLineInfo.SetDistance( 50 );
     739           0 :                             break;
     740             :                             case PS_DASHDOT :
     741           0 :                                 aLineInfo.SetStyle( LINE_DASH );
     742           0 :                                 aLineInfo.SetDashCount( 1 );
     743           0 :                                 aLineInfo.SetDotCount( 1 );
     744           0 :                                 aLineInfo.SetDashLen( 150 );
     745           0 :                                 aLineInfo.SetDotLen( 30 );
     746           0 :                                 aLineInfo.SetDistance( 90 );
     747           0 :                             break;
     748             :                             case PS_DOT :
     749           0 :                                 aLineInfo.SetStyle( LINE_DASH );
     750           0 :                                 aLineInfo.SetDashCount( 0 );
     751           0 :                                 aLineInfo.SetDotCount( 1 );
     752           0 :                                 aLineInfo.SetDotLen( 30 );
     753           0 :                                 aLineInfo.SetDistance( 50 );
     754           0 :                             break;
     755             :                             case PS_DASH :
     756           0 :                                 aLineInfo.SetStyle( LINE_DASH );
     757           0 :                                 aLineInfo.SetDashCount( 1 );
     758           0 :                                 aLineInfo.SetDotCount( 0 );
     759           0 :                                 aLineInfo.SetDashLen( 225 );
     760           0 :                                 aLineInfo.SetDistance( 100 );
     761           0 :                             break;
     762             :                             case PS_NULL :
     763           0 :                                 bTransparent = true;
     764           0 :                                 aLineInfo.SetStyle( LINE_NONE );
     765           0 :                             break;
     766             :                             case PS_INSIDEFRAME :
     767             :                             case PS_SOLID :
     768             :                             default :
     769           0 :                                 aLineInfo.SetStyle( LINE_SOLID );
     770             :                         }
     771           0 :                         switch( nStyle & 0xF00 )
     772             :                         {
     773             :                             case PS_ENDCAP_ROUND :
     774           0 :                                 aLineInfo.SetLineCap( com::sun::star::drawing::LineCap_ROUND );
     775           0 :                             break;
     776             :                             case PS_ENDCAP_SQUARE :
     777           0 :                                 aLineInfo.SetLineCap( com::sun::star::drawing::LineCap_SQUARE );
     778           0 :                             break;
     779             :                             case PS_ENDCAP_FLAT :
     780             :                             default :
     781           0 :                                 aLineInfo.SetLineCap( com::sun::star::drawing::LineCap_BUTT );
     782             :                         }
     783           0 :                         switch( nStyle & 0xF000 )
     784             :                         {
     785             :                             case PS_JOIN_ROUND :
     786           0 :                                 aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_ROUND );
     787           0 :                             break;
     788             :                             case PS_JOIN_MITER :
     789           0 :                                 aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_MITER );
     790           0 :                             break;
     791             :                             case PS_JOIN_BEVEL :
     792           0 :                                 aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_BEVEL );
     793           0 :                             break;
     794             :                             default :
     795           0 :                                 aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_NONE );
     796             :                         }
     797           0 :                         pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
     798             :                     }
     799             :                 }
     800           0 :                 break;
     801             : 
     802             :                 case EMR_EXTCREATEPEN :
     803             :                 {
     804             :                     sal_Int32   elpHatch;
     805             :                     sal_uInt32  offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries;
     806           0 :                     Color       aColorRef;
     807             : 
     808           0 :                     pWMF->ReadUInt32( nIndex );
     809           0 :                     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     810             :                     {
     811           0 :                         pWMF->ReadUInt32( offBmi ).ReadUInt32( cbBmi ).ReadUInt32( offBits ).ReadUInt32( cbBits ). ReadUInt32( nStyle ).ReadUInt32( nWidth ).ReadUInt32( nBrushStyle );
     812           0 :                          aColorRef = ReadColor();
     813           0 :                          pWMF->ReadInt32( elpHatch ).ReadUInt32( elpNumEntries );
     814             : 
     815           0 :                         LineInfo    aLineInfo;
     816           0 :                         if ( nWidth )
     817           0 :                             aLineInfo.SetWidth( nWidth );
     818             : 
     819           0 :                         bool bTransparent = false;
     820           0 :                         sal_uInt16 nDashCount = 0;
     821           0 :                         sal_uInt16 nDotCount = 0;
     822             : 
     823           0 :                         switch( nStyle & PS_STYLE_MASK )
     824             :                         {
     825             :                             case PS_DASHDOTDOT :
     826           0 :                                 nDotCount++;
     827             :                             case PS_DASHDOT :
     828           0 :                                 nDashCount++;
     829             :                             case PS_DOT :
     830           0 :                                 nDotCount++;
     831           0 :                             break;
     832             :                             case PS_DASH :
     833           0 :                                 nDashCount++;
     834           0 :                             break;
     835             :                             case PS_NULL :
     836           0 :                                 bTransparent = true;
     837           0 :                                 aLineInfo.SetStyle( LINE_NONE );
     838           0 :                             break;
     839             : 
     840             :                             case PS_INSIDEFRAME :
     841             :                             case PS_SOLID :
     842             :                             default :
     843           0 :                                 aLineInfo.SetStyle( LINE_SOLID );
     844             :                         }
     845           0 :                         if ( nDashCount | nDotCount )
     846             :                         {
     847           0 :                             aLineInfo.SetStyle( LINE_DASH );
     848           0 :                             aLineInfo.SetDashCount( nDashCount );
     849           0 :                             aLineInfo.SetDotCount( nDotCount );
     850             :                         }
     851           0 :                         pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( aColorRef, aLineInfo, bTransparent ) );
     852             :                     }
     853             :                 }
     854           0 :                 break;
     855             : 
     856             :                 case EMR_CREATEBRUSHINDIRECT :
     857             :                 {
     858             :                     sal_uInt32  nStyle;
     859           0 :                     pWMF->ReadUInt32( nIndex );
     860           0 :                     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     861             :                     {
     862           0 :                         pWMF->ReadUInt32( nStyle );
     863           0 :                         pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? true : false ) );
     864             :                     }
     865             :                 }
     866           0 :                 break;
     867             : 
     868             :                 case EMR_DELETEOBJECT :
     869             :                 {
     870           0 :                     pWMF->ReadUInt32( nIndex );
     871           0 :                     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
     872           0 :                         pOut->DeleteObject( nIndex );
     873             :                 }
     874           0 :                 break;
     875             : 
     876             :                 case EMR_ELLIPSE :
     877             :                 {
     878           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
     879           0 :                     pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) );
     880             :                 }
     881           0 :                 break;
     882             : 
     883             :                 case EMR_RECTANGLE :
     884             :                 {
     885           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
     886           0 :                     pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
     887             :                 }
     888           0 :                 break;
     889             : 
     890             :                 case EMR_ROUNDRECT :
     891             :                 {
     892           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nW ).ReadUInt32( nH );
     893           0 :                     Size aSize( Size( nW, nH ) );
     894           0 :                     pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize );
     895             :                 }
     896           0 :                 break;
     897             : 
     898             :                 case EMR_ARC :
     899             :                 {
     900             :                     sal_uInt32 nStartX, nStartY, nEndX, nEndY;
     901           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
     902           0 :                     pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
     903             :                 }
     904           0 :                 break;
     905             : 
     906             :                 case EMR_CHORD :
     907             :                 {
     908             :                     sal_uInt32 nStartX, nStartY, nEndX, nEndY;
     909           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
     910           0 :                     pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
     911             :                 }
     912           0 :                 break;
     913             : 
     914             :                 case EMR_PIE :
     915             :                 {
     916             :                     sal_uInt32 nStartX, nStartY, nEndX, nEndY;
     917           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
     918           0 :                     const Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 ));
     919             : 
     920             :                     // #i73608# OutputDevice deviates from WMF
     921             :                     // semantics. start==end means full ellipse here.
     922           0 :                     if( nStartX == nEndX && nStartY == nEndY )
     923           0 :                         pOut->DrawEllipse( aRect );
     924             :                     else
     925           0 :                         pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
     926             :                 }
     927           0 :                 break;
     928             : 
     929             :                 case EMR_LINETO :
     930             :                 {
     931           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
     932           0 :                     pOut->LineTo( Point( nX32, nY32 ), bRecordPath );
     933             :                 }
     934           0 :                 break;
     935             : 
     936             :                 case EMR_ARCTO :
     937             :                 {
     938             :                     sal_uInt32 nStartX, nStartY, nEndX, nEndY;
     939           0 :                     pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
     940           0 :                     pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), true );
     941             :                 }
     942           0 :                 break;
     943             : 
     944             :                 case EMR_BEGINPATH :
     945             :                 {
     946           0 :                     pOut->ClearPath();
     947           0 :                     bRecordPath = true;
     948             :                 }
     949           0 :                 break;
     950             : 
     951             :                 case EMR_ABORTPATH :
     952           0 :                     pOut->ClearPath();
     953             :                 case EMR_ENDPATH :
     954           0 :                     bRecordPath = false;
     955           0 :                 break;
     956             : 
     957             :                 case EMR_CLOSEFIGURE :
     958           0 :                     pOut->ClosePath();
     959           0 :                 break;
     960             : 
     961             :                 case EMR_FILLPATH :
     962           0 :                     pOut->StrokeAndFillPath( false, true );
     963           0 :                 break;
     964             : 
     965             :                 case EMR_STROKEANDFILLPATH :
     966           0 :                     pOut->StrokeAndFillPath( true, true );
     967           0 :                 break;
     968             : 
     969             :                 case EMR_STROKEPATH :
     970           0 :                     pOut->StrokeAndFillPath( true, false );
     971           0 :                 break;
     972             : 
     973             :                 case EMR_SELECTCLIPPATH :
     974             :                 {
     975             :                     sal_Int32 nClippingMode;
     976           0 :                     pWMF->ReadInt32( nClippingMode );
     977           0 :                     pOut->SetClipPath( pOut->GetPathObj(), nClippingMode, true );
     978             :                 }
     979           0 :                 break;
     980             : 
     981             :                 case EMR_EXTSELECTCLIPRGN :
     982             :                 {
     983             :                     sal_Int32 iMode, cbRgnData;
     984           0 :                     pWMF->ReadInt32( cbRgnData )
     985           0 :                          .ReadInt32( iMode );
     986             : 
     987           0 :                     PolyPolygon aPolyPoly;
     988           0 :                     if ( cbRgnData )
     989           0 :                         ImplReadRegion( aPolyPoly, *pWMF, nRecSize );
     990           0 :                     pOut->SetClipPath( aPolyPoly, iMode, true );
     991             :                 }
     992           0 :                 break;
     993             : 
     994             :                 case EMR_ALPHABLEND:
     995             :                 {
     996           0 :                     sal_Int32 xDest(0), yDest(0), cxDest(0), cyDest(0);
     997             : 
     998             :                     BLENDFUNCTION aFunc;
     999           0 :                     sal_Int32 xSrc(0), ySrc(0), cxSrc(0), cySrc(0);
    1000           0 :                     XForm xformSrc;
    1001           0 :                     sal_uInt32 BkColorSrc(0), iUsageSrc(0), offBmiSrc(0);
    1002           0 :                     sal_uInt32 cbBmiSrc(0), offBitsSrc(0), cbBitsSrc(0);
    1003             : 
    1004           0 :                     sal_uInt32   nStart = pWMF->Tell() - 8;
    1005           0 :                     pWMF->SeekRel( 0x10 );
    1006             : 
    1007           0 :                     pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest );
    1008           0 :                     *pWMF >> aFunc;
    1009           0 :                     pWMF->ReadInt32( xSrc ).ReadInt32( ySrc );
    1010           0 :                     *pWMF >> xformSrc;
    1011           0 :                     pWMF->ReadUInt32( BkColorSrc ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc )
    1012           0 :                                .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc ).ReadInt32( cxSrc ).ReadInt32( cySrc ) ;
    1013             : 
    1014           0 :                     sal_uInt32  dwRop = SRCAND|SRCINVERT;
    1015             : 
    1016           0 :                     Bitmap      aBitmap;
    1017           0 :                     Rectangle   aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
    1018             : 
    1019           0 :                     if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
    1020           0 :                         bStatus = false;
    1021             :                     else
    1022             :                     {
    1023           0 :                         sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
    1024           0 :                         if ( nSize <= ( nEndPos - nStartPos ) )
    1025             :                         {
    1026           0 :                             char* pBuf = new char[ nSize ];
    1027           0 :                             SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
    1028           0 :                             aTmp.ObjectOwnsMemory( true );
    1029           0 :                             aTmp.WriteUChar( (sal_uInt8)'B' )
    1030           0 :                                 .WriteUChar( (sal_uInt8)'M' )
    1031           0 :                                 .WriteUInt32( (sal_uInt32)cbBitsSrc )
    1032           0 :                                 .WriteUInt16( (sal_uInt16)0 )
    1033           0 :                                 .WriteUInt16( (sal_uInt16)0 )
    1034           0 :                                 .WriteUInt32( (sal_uInt32)cbBmiSrc + 14 );
    1035           0 :                             pWMF->Seek( nStart + offBmiSrc );
    1036           0 :                             pWMF->Read( pBuf + 14, cbBmiSrc );
    1037           0 :                             pWMF->Seek( nStart + offBitsSrc );
    1038           0 :                             pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
    1039           0 :                             aTmp.Seek( 0 );
    1040           0 :                             ReadDIB(aBitmap, aTmp, true);
    1041             : 
    1042             :                             // test if it is sensible to crop
    1043           0 :                             if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
    1044           0 :                                 ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
    1045           0 :                                     ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
    1046           0 :                                         ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
    1047             :                             {
    1048           0 :                                 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
    1049           0 :                                 aBitmap.Crop( aCropRect );
    1050             :                             }
    1051           0 :                             aBmpSaveList.push_back( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ) );
    1052             :                         }
    1053           0 :                     }
    1054             :                 }
    1055           0 :                 break;
    1056             : 
    1057             :                 case EMR_BITBLT :   // PASSTHROUGH INTENDED
    1058             :                 case EMR_STRETCHBLT :
    1059             :                 {
    1060             :                     sal_Int32   xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc;
    1061             :                     sal_uInt32  dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc;
    1062           0 :                     XForm   xformSrc;
    1063             : 
    1064           0 :                     sal_uInt32  nStart = pWMF->Tell() - 8;
    1065             : 
    1066           0 :                     pWMF->SeekRel( 0x10 );
    1067           0 :                     pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest ).ReadUInt32( dwRop ).ReadInt32( xSrc ).ReadInt32( ySrc )
    1068           0 :                             >> xformSrc;
    1069           0 :                     pWMF->ReadUInt32( nColor ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc )
    1070           0 :                                .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc );
    1071             : 
    1072           0 :                     if ( nRecType == EMR_STRETCHBLT )
    1073           0 :                         pWMF->ReadInt32( cxSrc ).ReadInt32( cySrc );
    1074             :                     else
    1075           0 :                         cxSrc = cySrc = 0;
    1076             : 
    1077           0 :                     Bitmap      aBitmap;
    1078           0 :                     Rectangle   aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
    1079             : 
    1080           0 :                     cxDest = abs( (int)cxDest );        // sj: i37894, size can be negative
    1081           0 :                     cyDest = abs( (int)cyDest );        // and also 122889
    1082             : 
    1083           0 :                     if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
    1084           0 :                         bStatus = false;
    1085             :                     else
    1086             :                     {
    1087           0 :                         sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
    1088           0 :                         if ( nSize <= ( nEndPos - nStartPos ) )
    1089             :                         {
    1090           0 :                             char* pBuf = new char[ nSize ];
    1091           0 :                             SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
    1092           0 :                             aTmp.ObjectOwnsMemory( true );
    1093           0 :                             aTmp.WriteUChar( (sal_uInt8)'B' )
    1094           0 :                                 .WriteUChar( (sal_uInt8)'M' )
    1095           0 :                                 .WriteUInt32( (sal_uInt32)cbBitsSrc )
    1096           0 :                                 .WriteUInt16( (sal_uInt16)0 )
    1097           0 :                                 .WriteUInt16( (sal_uInt16)0 )
    1098           0 :                                 .WriteUInt32( (sal_uInt32)cbBmiSrc + 14 );
    1099           0 :                             pWMF->Seek( nStart + offBmiSrc );
    1100           0 :                             pWMF->Read( pBuf + 14, cbBmiSrc );
    1101           0 :                             pWMF->Seek( nStart + offBitsSrc );
    1102           0 :                             pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
    1103           0 :                             aTmp.Seek( 0 );
    1104           0 :                             ReadDIB(aBitmap, aTmp, true);
    1105             : 
    1106             :                             // test if it is sensible to crop
    1107           0 :                             if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
    1108           0 :                                 ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
    1109           0 :                                     ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
    1110           0 :                                         ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
    1111             :                             {
    1112           0 :                                 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
    1113           0 :                                 aBitmap.Crop( aCropRect );
    1114             :                             }
    1115           0 :                             aBmpSaveList.push_back( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ) );
    1116             :                         }
    1117           0 :                     }
    1118             :                 }
    1119           0 :                 break;
    1120             : 
    1121             :                 case EMR_STRETCHDIBITS :
    1122             :                 {
    1123             :                     sal_Int32   xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest;
    1124             :                     sal_uInt32  offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop;
    1125           0 :                     sal_uInt32  nStart = pWMF->Tell() - 8;
    1126             : 
    1127           0 :                     pWMF->SeekRel( 0x10 );
    1128           0 :                     pWMF->ReadInt32( xDest )
    1129           0 :                          .ReadInt32( yDest )
    1130           0 :                          .ReadInt32( xSrc )
    1131           0 :                          .ReadInt32( ySrc )
    1132           0 :                          .ReadInt32( cxSrc )
    1133           0 :                          .ReadInt32( cySrc )
    1134           0 :                          .ReadUInt32( offBmiSrc )
    1135           0 :                          .ReadUInt32( cbBmiSrc )
    1136           0 :                          .ReadUInt32( offBitsSrc )
    1137           0 :                          .ReadUInt32( cbBitsSrc )
    1138           0 :                          .ReadUInt32( iUsageSrc )
    1139           0 :                          .ReadUInt32( dwRop )
    1140           0 :                          .ReadInt32( cxDest )
    1141           0 :                          .ReadInt32( cyDest );
    1142             : 
    1143           0 :                     Bitmap      aBitmap;
    1144           0 :                     Rectangle   aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
    1145             : 
    1146           0 :                     cxDest = abs( (int)cxDest );        // sj: i37894, size can be negative
    1147           0 :                     cyDest = abs( (int)cyDest );        // and also 122889
    1148             : 
    1149           0 :                     if (  ((SAL_MAX_UINT32 - 14)             < cbBitsSrc)
    1150           0 :                        || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc )
    1151             :                        )
    1152             :                     {
    1153           0 :                         bStatus = false;
    1154             :                     }
    1155             :                     else
    1156             :                     {
    1157           0 :                         sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
    1158           0 :                         if ( nSize <= ( nEndPos - nStartPos ) )
    1159             :                         {
    1160           0 :                             char* pBuf = new char[ nSize ];
    1161           0 :                             SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
    1162           0 :                             aTmp.ObjectOwnsMemory( true );
    1163           0 :                             aTmp.WriteUChar( (sal_uInt8)'B' )
    1164           0 :                                .WriteUChar( (sal_uInt8)'M' )
    1165           0 :                                .WriteUInt32( (sal_uInt32)cbBitsSrc )
    1166           0 :                                .WriteUInt16( (sal_uInt16)0 )
    1167           0 :                                .WriteUInt16( (sal_uInt16)0 )
    1168           0 :                                .WriteUInt32( (sal_uInt32)cbBmiSrc + 14 );
    1169           0 :                             pWMF->Seek( nStart + offBmiSrc );
    1170           0 :                             pWMF->Read( pBuf + 14, cbBmiSrc );
    1171           0 :                             pWMF->Seek( nStart + offBitsSrc );
    1172           0 :                             pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
    1173           0 :                             aTmp.Seek( 0 );
    1174           0 :                             ReadDIB(aBitmap, aTmp, true);
    1175             : 
    1176             :                             // test if it is sensible to crop
    1177           0 :                             if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
    1178           0 :                                 ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
    1179           0 :                                     ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
    1180           0 :                                         ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
    1181             :                             {
    1182           0 :                                 Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
    1183           0 :                                 aBitmap.Crop( aCropRect );
    1184             :                             }
    1185           0 :                         aBmpSaveList.push_back( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ) );
    1186             :                         }
    1187           0 :                     }
    1188             :                 }
    1189           0 :                 break;
    1190             : 
    1191             :                 case EMR_EXTCREATEFONTINDIRECTW :
    1192             :                 {
    1193           0 :                     pWMF->ReadUInt32( nIndex );
    1194           0 :                     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
    1195             :                     {
    1196           0 :                         LOGFONTW aLogFont;
    1197           0 :                         pWMF->ReadInt32( aLogFont.lfHeight )
    1198           0 :                              .ReadInt32( aLogFont.lfWidth )
    1199           0 :                              .ReadInt32( aLogFont.lfEscapement )
    1200           0 :                              .ReadInt32( aLogFont.lfOrientation )
    1201           0 :                              .ReadInt32( aLogFont.lfWeight )
    1202           0 :                              .ReadUChar( aLogFont.lfItalic )
    1203           0 :                              .ReadUChar( aLogFont.lfUnderline )
    1204           0 :                              .ReadUChar( aLogFont.lfStrikeOut )
    1205           0 :                              .ReadUChar( aLogFont.lfCharSet )
    1206           0 :                              .ReadUChar( aLogFont.lfOutPrecision )
    1207           0 :                              .ReadUChar( aLogFont.lfClipPrecision )
    1208           0 :                              .ReadUChar( aLogFont.lfQuality )
    1209           0 :                              .ReadUChar( aLogFont.lfPitchAndFamily );
    1210             : 
    1211             :                         sal_Unicode lfFaceName[ LF_FACESIZE ];
    1212             : 
    1213           0 :                         for ( int i = 0; i < LF_FACESIZE; i++ )
    1214             :                         {
    1215             :                             sal_uInt16 nChar;
    1216           0 :                             pWMF->ReadUInt16( nChar );
    1217           0 :                             lfFaceName[ i ] = nChar;
    1218             :                         }
    1219           0 :                         aLogFont.alfFaceName = OUString( lfFaceName );
    1220             : 
    1221             :                         // #i123216# Not used in the test case of #121382# (always identity in XForm), also
    1222             :                         // no hints in ms docu if FontSize should be scaled with WT. Using with the example
    1223             :                         // from #i123216# creates errors, so removing.
    1224             : 
    1225             :                         // // #i121382# Need to apply WorldTransform to FontHeight/Width; this should be completely
    1226             :                         // // changed to basegfx::B2DHomMatrix instead of 'struct XForm', but not now due to time
    1227             :                         // // constraints and dangers
    1228             :                         // const XForm& rXF = pOut->GetWorldTransform();
    1229             :                         // const basegfx::B2DHomMatrix aWT(rXF.eM11, rXF.eM21, rXF.eDx, rXF.eM12, rXF.eM22, rXF.eDy);
    1230             :                         // const basegfx::B2DVector aTransVec(aWT * basegfx::B2DVector(aLogFont.lfWidth, aLogFont.lfHeight));
    1231             :                         // aLogFont.lfWidth = aTransVec.getX();
    1232             :                         // aLogFont.lfHeight = aTransVec.getY();
    1233             : 
    1234           0 :                         pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) );
    1235             :                     }
    1236             :                 }
    1237           0 :                 break;
    1238             : 
    1239             :                 case EMR_EXTTEXTOUTA :
    1240           0 :                     bFlag = true;
    1241             :                 case EMR_EXTTEXTOUTW :
    1242             :                 {
    1243             :                     sal_Int32   nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale;
    1244             :                     sal_uInt32  nCurPos, nOffString, nOptions, offDx;
    1245             :                     sal_Int32   nLen;
    1246           0 :                     sal_Int32*  pDX = NULL;
    1247             : 
    1248           0 :                     nCurPos = pWMF->Tell() - 8;
    1249             : 
    1250           0 :                     pWMF->ReadInt32( nLeft ).ReadInt32( nTop ).ReadInt32( nRight ).ReadInt32( nBottom ).ReadInt32( nGfxMode ).ReadInt32( nXScale ).ReadInt32( nYScale )
    1251           0 :                        .ReadInt32( ptlReferenceX ).ReadInt32( ptlReferenceY ).ReadInt32( nLen ).ReadUInt32( nOffString ).ReadUInt32( nOptions );
    1252             : 
    1253           0 :                     pWMF->SeekRel( 0x10 );
    1254           0 :                     pWMF->ReadUInt32( offDx );
    1255             : 
    1256           0 :                     sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT;
    1257           0 :                     if ( nOptions & ETO_RTLREADING )
    1258           0 :                         nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
    1259           0 :                     pOut->SetTextLayoutMode( nTextLayoutMode );
    1260             :                     DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" );
    1261             : 
    1262           0 :                     Point aPos( ptlReferenceX, ptlReferenceY );
    1263           0 :                     if ( nLen && nLen < static_cast<sal_Int32>( SAL_MAX_UINT32 / sizeof(sal_Int32) ) )
    1264             :                     {
    1265           0 :                         if ( offDx && (( nCurPos + offDx + nLen * 4 ) <= nNextPos ) )
    1266             :                         {
    1267           0 :                             pWMF->Seek( nCurPos + offDx );
    1268           0 :                             if ( ( nLen * sizeof(sal_uInt32) ) <= ( nEndPos - pWMF->Tell() ) )
    1269             :                             {
    1270           0 :                                 pDX = new sal_Int32[ nLen ];
    1271             :                                 sal_Int32 i;
    1272           0 :                                 for ( i = 0; i < nLen; i++ )
    1273           0 :                                     pWMF->ReadInt32( pDX[ i ] );
    1274             :                             }
    1275             :                         }
    1276           0 :                         pWMF->Seek( nCurPos + nOffString );
    1277           0 :                         OUString aText;
    1278           0 :                         if ( bFlag )
    1279             :                         {
    1280           0 :                             if ( nLen <= static_cast<sal_Int32>( nEndPos - pWMF->Tell() ) )
    1281             :                             {
    1282           0 :                                 boost::scoped_array<sal_Char> pBuf(new sal_Char[ nLen ]);
    1283           0 :                                 pWMF->Read( pBuf.get(), nLen );
    1284           0 :                                 aText = OUString( pBuf.get(), (sal_uInt16)nLen, pOut->GetCharSet() );
    1285           0 :                                 pBuf.reset();
    1286             : 
    1287           0 :                                 if ( aText.getLength() != nLen )
    1288             :                                 {
    1289             :                                     sal_uInt16 i, j;
    1290           0 :                                     sal_Int32* pOldDx = pDX;
    1291           0 :                                     pDX = new sal_Int32[ aText.getLength() ];
    1292           0 :                                     for ( i = 0, j = 0; i < aText.getLength(); i++ )
    1293             :                                     {
    1294           0 :                                         sal_Unicode cUniChar = aText[i];
    1295           0 :                                         OString aCharacter(&cUniChar, 1, pOut->GetCharSet());
    1296           0 :                                         pDX[ i ] = 0;
    1297           0 :                                         for (sal_Int32 k = 0; ( k < aCharacter.getLength() ) && ( j < nLen ) && ( i < aText.getLength() ); ++k)
    1298           0 :                                             pDX[ i ] += pOldDx[ j++ ];
    1299           0 :                                     }
    1300           0 :                                     delete[] pOldDx;
    1301           0 :                                 }
    1302             :                             }
    1303             :                         }
    1304             :                         else
    1305             :                         {
    1306           0 :                             if ( ( nLen * sizeof(sal_Unicode) ) <= ( nEndPos - pWMF->Tell() ) )
    1307             :                             {
    1308           0 :                                 boost::scoped_array<sal_Unicode> pBuf(new sal_Unicode[ nLen ]);
    1309           0 :                                 pWMF->Read( pBuf.get(), nLen << 1 );
    1310             : #ifdef OSL_BIGENDIAN
    1311             :                                 sal_Char nTmp, *pTmp = (sal_Char*)( pBuf.get() + nLen );
    1312             :                                 while ( pTmp-- != (sal_Char*)pBuf.get() )
    1313             :                                 {
    1314             :                                     nTmp = *pTmp--;
    1315             :                                     pTmp[ 1 ] = *pTmp;
    1316             :                                     *pTmp = nTmp;
    1317             :                                 }
    1318             : #endif
    1319           0 :                                 aText = OUString(pBuf.get(), nLen);
    1320             :                             }
    1321             :                         }
    1322           0 :                         pOut->DrawText( aPos, aText, pDX, bRecordPath, nGfxMode );
    1323             :                     }
    1324           0 :                     delete[] pDX;
    1325             :                 }
    1326           0 :                 break;
    1327             : 
    1328             :                 case EMR_POLYBEZIERTO16 :
    1329           0 :                     ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, _2, _3, _4), true);
    1330           0 :                     break;
    1331             :                 case EMR_POLYBEZIER16 :
    1332           0 :                     ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyBezier, _1, _2, _3, _4), false);
    1333           0 :                 break;
    1334             : 
    1335             :                 case EMR_POLYGON16 :
    1336           0 :                     ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolygon, _1, _2, _3, _4), false);
    1337           0 :                 break;
    1338             : 
    1339             :                 case EMR_POLYLINETO16 :
    1340           0 :                     ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, _3, _4), true);
    1341           0 :                     break;
    1342             :                 case EMR_POLYLINE16 :
    1343           0 :                     ReadAndDrawPolygon<sal_Int16>(boost::bind(&WinMtfOutput::DrawPolyLine, _1, _2, _3, _4), false);
    1344           0 :                 break;
    1345             : 
    1346             :                 case EMR_POLYPOLYLINE16 :
    1347           0 :                     ReadAndDrawPolyLine<sal_Int16>();
    1348           0 :                     break;
    1349             : 
    1350             :                 case EMR_POLYPOLYGON16 :
    1351           0 :                     ReadAndDrawPolyPolygon<sal_Int16>();
    1352           0 :                 break;
    1353             : 
    1354             :                 case EMR_FILLRGN :
    1355             :                 {
    1356             :                     sal_uInt32 nLen;
    1357           0 :                     PolyPolygon aPolyPoly;
    1358           0 :                     pWMF->SeekRel( 0x10 );
    1359           0 :                     pWMF->ReadUInt32( nLen ).ReadUInt32( nIndex );
    1360             : 
    1361           0 :                     if ( ImplReadRegion( aPolyPoly, *pWMF, nRecSize ) )
    1362             :                     {
    1363           0 :                         pOut->Push();
    1364           0 :                         pOut->SelectObject( nIndex );
    1365           0 :                         pOut->DrawPolyPolygon( aPolyPoly, false );
    1366           0 :                         pOut->Pop();
    1367           0 :                     }
    1368             :                 }
    1369           0 :                 break;
    1370             : 
    1371             :                 case EMR_CREATEDIBPATTERNBRUSHPT :
    1372             :                 {
    1373           0 :                     sal_uInt32  nStart = pWMF->Tell() - 8;
    1374           0 :                     Bitmap aBitmap;
    1375             : 
    1376           0 :                     pWMF->ReadUInt32( nIndex );
    1377             : 
    1378           0 :                     if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
    1379             :                     {
    1380             :                         sal_uInt32 usage, offBmi, cbBmi, offBits, cbBits;
    1381             : 
    1382           0 :                         pWMF->ReadUInt32( usage );
    1383           0 :                         pWMF->ReadUInt32( offBmi );
    1384           0 :                         pWMF->ReadUInt32( cbBmi );
    1385           0 :                         pWMF->ReadUInt32( offBits );
    1386           0 :                         pWMF->ReadUInt32( cbBits );
    1387             : 
    1388           0 :                         if ( (cbBits > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBits < cbBmi) )
    1389           0 :                            bStatus = false;
    1390           0 :                         else if ( offBmi )
    1391             :                         {
    1392           0 :                             sal_uInt32  nSize = cbBmi + cbBits + 14;
    1393           0 :                             if ( nSize <= ( nEndPos - nStartPos ) )
    1394             :                             {
    1395           0 :                                 char*   pBuf = new char[ nSize ];
    1396             : 
    1397           0 :                                 SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
    1398           0 :                                 aTmp.ObjectOwnsMemory( true );
    1399           0 :                                 aTmp.WriteUChar( (sal_uInt8)'B' )
    1400           0 :                                     .WriteUChar( (sal_uInt8)'M' )
    1401           0 :                                     .WriteUInt32( (sal_uInt32)cbBits )
    1402           0 :                                     .WriteUInt16( (sal_uInt16)0 )
    1403           0 :                                     .WriteUInt16( (sal_uInt16)0 )
    1404           0 :                                     .WriteUInt32( (sal_uInt32)cbBmi + 14 );
    1405           0 :                                 pWMF->Seek( nStart + offBmi );
    1406           0 :                                 pWMF->Read( pBuf + 14, cbBmi );
    1407           0 :                                 pWMF->Seek( nStart + offBits );
    1408           0 :                                 pWMF->Read( pBuf + 14 + cbBmi, cbBits );
    1409           0 :                                 aTmp.Seek( 0 );
    1410           0 :                                 ReadDIB(aBitmap, aTmp, true);
    1411             :                             }
    1412             :                         }
    1413             :                     }
    1414             : 
    1415           0 :                     pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aBitmap ) );
    1416             :                 }
    1417           0 :                 break;
    1418             : 
    1419           0 :                 case EMR_MASKBLT :                  SAL_INFO("vcl.emf", "not implemented '" << "MaskBlt" << "'");                   break;
    1420           0 :                 case EMR_PLGBLT :                   SAL_INFO("vcl.emf", "not implemented '" << "PlgBlt" << "'");                    break;
    1421           0 :                 case EMR_SETDIBITSTODEVICE :        SAL_INFO("vcl.emf", "not implemented '" << "SetDIBitsToDevice" << "'");         break;
    1422           0 :                 case EMR_FRAMERGN :                 SAL_INFO("vcl.emf", "not implemented '" << "FrameRgn" << "'");                  break;
    1423           0 :                 case EMR_INVERTRGN :                SAL_INFO("vcl.emf", "not implemented '" << "InvertRgn" << "'");                 break;
    1424           0 :                 case EMR_PAINTRGN :                 SAL_INFO("vcl.emf", "not implemented '" << "PaintRgn" << "'");                  break;
    1425           0 :                 case EMR_FLATTENPATH :              SAL_INFO("vcl.emf", "not implemented '" << "FlattenPath" << "'");               break;
    1426           0 :                 case EMR_WIDENPATH :                SAL_INFO("vcl.emf", "not implemented '" << "WidenPath" << "'");                 break;
    1427           0 :                 case EMR_POLYDRAW :                 SAL_INFO("vcl.emf", "not implemented '" << "Polydraw" << "'");                  break;
    1428           0 :                 case EMR_SETARCDIRECTION :          SAL_INFO("vcl.emf", "not implemented '" << "SetArcDirection" << "'");           break;
    1429           0 :                 case EMR_SETPALETTEENTRIES :        SAL_INFO("vcl.emf", "not implemented '" << "SetPaletteEntries" << "'");         break;
    1430           0 :                 case EMR_RESIZEPALETTE :            SAL_INFO("vcl.emf", "not implemented '" << "ResizePalette" << "'");             break;
    1431           0 :                 case EMR_EXTFLOODFILL :             SAL_INFO("vcl.emf", "not implemented '" << "ExtFloodFill" << "'");              break;
    1432           0 :                 case EMR_ANGLEARC :                 SAL_INFO("vcl.emf", "not implemented '" << "AngleArc" << "'");                  break;
    1433           0 :                 case EMR_SETCOLORADJUSTMENT :       SAL_INFO("vcl.emf", "not implemented '" << "SetColorAdjustment" << "'");        break;
    1434           0 :                 case EMR_POLYDRAW16 :               SAL_INFO("vcl.emf", "not implemented '" << "PolyDraw16" << "'");                break;
    1435           0 :                 case EMR_POLYTEXTOUTA :             SAL_INFO("vcl.emf", "not implemented '" << "PolyTextOutA" << "'");              break;
    1436           0 :                 case EMR_POLYTEXTOUTW :             SAL_INFO("vcl.emf", "not implemented '" << "PolyTextOutW" << "'");              break;
    1437           0 :                 case EMR_CREATECOLORSPACE :         SAL_INFO("vcl.emf", "not implemented '" << "CreateColorSpace" << "'");          break;
    1438           0 :                 case EMR_SETCOLORSPACE :            SAL_INFO("vcl.emf", "not implemented '" << "SetColorSpace" << "'");             break;
    1439           0 :                 case EMR_DELETECOLORSPACE :         SAL_INFO("vcl.emf", "not implemented '" << "DeleteColorSpace" << "'");          break;
    1440           0 :                 case EMR_GLSRECORD :                SAL_INFO("vcl.emf", "not implemented '" << "GlsRecord" << "'");                 break;
    1441           0 :                 case EMR_GLSBOUNDEDRECORD :         SAL_INFO("vcl.emf", "not implemented '" << "GlsBoundRecord" << "'");            break;
    1442           0 :                 case EMR_PIXELFORMAT :              SAL_INFO("vcl.emf", "not implemented '" << "PixelFormat" << "'");               break;
    1443           0 :                 case EMR_DRAWESCAPE :               SAL_INFO("vcl.emf", "not implemented '" << "DrawEscape" << "'");                break;
    1444           0 :                 case EMR_EXTESCAPE :                SAL_INFO("vcl.emf", "not implemented '" << "ExtEscape" << "'");                 break;
    1445           0 :                 case EMR_STARTDOC :                 SAL_INFO("vcl.emf", "not implemented '" << "StartDoc" << "'");                  break;
    1446           0 :                 case EMR_SMALLTEXTOUT :             SAL_INFO("vcl.emf", "not implemented '" << "SmallTextOut" << "'");              break;
    1447           0 :                 case EMR_FORCEUFIMAPPING :          SAL_INFO("vcl.emf", "not implemented '" << "ForceUFIMapping" << "'");           break;
    1448           0 :                 case EMR_NAMEDESCAPE :              SAL_INFO("vcl.emf", "not implemented '" << "NamedEscape" << "'");               break;
    1449           0 :                 case EMR_COLORCORRECTPALETTE :      SAL_INFO("vcl.emf", "not implemented '" << "ColorCorrectPalette" << "'");       break;
    1450           0 :                 case EMR_SETICMPROFILEA :           SAL_INFO("vcl.emf", "not implemented '" << "SetICMProfileA" << "'");            break;
    1451           0 :                 case EMR_SETICMPROFILEW :           SAL_INFO("vcl.emf", "not implemented '" << "SetICMProfileW" << "'");            break;
    1452           0 :                 case EMR_TRANSPARENTBLT :           SAL_INFO("vcl.emf", "not implemented '" << "TransparenBlt" << "'");             break;
    1453           0 :                 case EMR_TRANSPARENTDIB :           SAL_INFO("vcl.emf", "not implemented '" << "TransparenDib" << "'");             break;
    1454           0 :                 case EMR_GRADIENTFILL :             SAL_INFO("vcl.emf", "not implemented '" << "GradientFill" << "'");              break;
    1455           0 :                 case EMR_SETLINKEDUFIS :            SAL_INFO("vcl.emf", "not implemented '" << "SetLinkedUFIS" << "'");             break;
    1456             : 
    1457           0 :                 case EMR_SETMAPPERFLAGS :           SAL_INFO("vcl.emf", "not implemented '" << "SetMapperFlags" << "'");            break;
    1458           0 :                 case EMR_SETICMMODE :               SAL_INFO("vcl.emf", "not implemented '" << "SetICMMode" << "'");                break;
    1459           0 :                 case EMR_CREATEMONOBRUSH :          SAL_INFO("vcl.emf", "not implemented '" << "CreateMonoBrush" << "'");           break;
    1460           0 :                 case EMR_SETBRUSHORGEX :            SAL_INFO("vcl.emf", "not implemented '" << "SetBrushOrgEx" << "'");             break;
    1461           0 :                 case EMR_SETMETARGN :               SAL_INFO("vcl.emf", "not implemented '" << "SetMetArgn" << "'");                break;
    1462           0 :                 case EMR_SETMITERLIMIT :            SAL_INFO("vcl.emf", "not implemented '" << "SetMiterLimit" << "'");             break;
    1463           0 :                 case EMR_EXCLUDECLIPRECT :          SAL_INFO("vcl.emf", "not implemented '" << "ExcludeClipRect" << "'");           break;
    1464           0 :                 case EMR_REALIZEPALETTE :           SAL_INFO("vcl.emf", "not implemented '" << "RealizePalette" << "'");            break;
    1465           0 :                 case EMR_SELECTPALETTE :            SAL_INFO("vcl.emf", "not implemented '" << "SelectPalette" << "'");             break;
    1466           0 :                 case EMR_CREATEPALETTE :            SAL_INFO("vcl.emf", "not implemented '" << "CreatePalette" << "'");             break;
    1467           0 :                 case EMR_ALPHADIBBLEND :            SAL_INFO("vcl.emf", "not implemented '" << "AlphaDibBlend" << "'");             break;
    1468           0 :                 case EMR_SETTEXTJUSTIFICATION :     SAL_INFO("vcl.emf", "not implemented '" << "SetTextJustification" << "'");      break;
    1469             : 
    1470             :                 case EMR_GDICOMMENT :
    1471             :                 case EMR_HEADER :               // has already been read at ReadHeader()
    1472           0 :                 break;
    1473             : 
    1474           0 :                 default :                           SAL_INFO("vcl.emf", "Unknown Meta Action");                                     break;
    1475             :             }
    1476             :         }
    1477           0 :         pWMF->Seek( nNextPos );
    1478             :     }
    1479           0 :     if( !aBmpSaveList.empty() )
    1480           0 :         pOut->ResolveBitmapActions( aBmpSaveList );
    1481             : 
    1482           0 :     if ( bStatus )
    1483           0 :         pWMF->Seek(nEndPos);
    1484             : 
    1485           0 :     return bStatus;
    1486             : };
    1487             : 
    1488           0 : bool EnhWMFReader::ReadHeader()
    1489             : {
    1490             :     sal_uInt32      nType, nSignature, nVersion;
    1491             :     sal_uInt32      nHeaderSize, nPalEntries;
    1492             :     sal_Int32       nLeft, nTop, nRight, nBottom;
    1493             : 
    1494             :     // Spare me the METAFILEHEADER here
    1495             :     // Reading the METAHEADER - EMR_HEADER ([MS-EMF] section 2.3.4.2 EMR_HEADER Record Types)
    1496           0 :     pWMF->ReadUInt32( nType ).ReadUInt32( nHeaderSize );
    1497           0 :     if ( nType != 1 ) { // per [MS-EMF] 2.3.4.2 EMF Header Record Types, type MUST be 0x00000001
    1498             :         SAL_WARN("vcl.emf", "EMF header type is not set to 0x00000001 - possibly corrupted file?");
    1499           0 :         return false;
    1500             :     }
    1501             : 
    1502             :     // Start reading the EMR_HEADER Header object
    1503             : 
    1504             :     // bound size (RectL object, see [MS-WMF] section 2.2.2.19)
    1505           0 :     Rectangle rclBounds;    // rectangle in logical units
    1506           0 :     pWMF->ReadInt32( nLeft ).ReadInt32( nTop ).ReadInt32( nRight ).ReadInt32( nBottom );
    1507           0 :     rclBounds.Left() = nLeft;
    1508           0 :     rclBounds.Top() = nTop;
    1509           0 :     rclBounds.Right() = nRight;
    1510           0 :     rclBounds.Bottom() = nBottom;
    1511             : 
    1512             :     // picture frame size (RectL object)
    1513           0 :     Rectangle rclFrame;     // rectangle in device units 1/100th mm
    1514           0 :     pWMF->ReadInt32( nLeft ).ReadInt32( nTop ).ReadInt32( nRight ).ReadInt32( nBottom );
    1515           0 :     rclFrame.Left() = nLeft;
    1516           0 :     rclFrame.Top() = nTop;
    1517           0 :     rclFrame.Right() = nRight;
    1518           0 :     rclFrame.Bottom() = nBottom;
    1519             : 
    1520           0 :     pWMF->ReadUInt32( nSignature );
    1521             : 
    1522             :     // nSignature MUST be the ASCII characters "FME", see [WS-EMF] 2.2.9 Header Object
    1523             :     // and 2.1.14 FormatSignature Enumeration
    1524           0 :     if ( nSignature != 0x464d4520 ) {
    1525             :         SAL_WARN("vcl.emf", "EMF\t\tSignature is not 0x464d4520 (\"FME\") - possibly corrupted file?");
    1526           0 :         return false;
    1527             :     }
    1528             : 
    1529           0 :     pWMF->ReadUInt32( nVersion );  // according to [WS-EMF] 2.2.9, this SHOULD be 0x0001000, however
    1530             :                         // Microsoft note that not even Windows checks this...
    1531           0 :     if ( nVersion != 0x00010000 ) {
    1532             :         SAL_WARN("vcl.emf", "EMF\t\tThis really should be 0x00010000, though not absolutely essential...");
    1533             :     }
    1534             : 
    1535           0 :     pWMF->ReadUInt32( nEndPos );                                   // size of metafile
    1536           0 :     nEndPos += nStartPos;
    1537             : 
    1538           0 :     sal_uInt32 nStrmPos = pWMF->Tell();                 // checking if nEndPos is valid
    1539           0 :     pWMF->Seek( STREAM_SEEK_TO_END );
    1540           0 :     sal_uInt32 nActualFileSize = pWMF->Tell();
    1541             : 
    1542           0 :     if ( nActualFileSize < nEndPos ) {
    1543             :         SAL_WARN("vcl.emf", "EMF\t\tEMF Header object records number of bytes as " << nEndPos
    1544             :                             << ", however the file size is actually " << nActualFileSize
    1545             :                             << " bytes. Possible file corruption?");
    1546           0 :         nEndPos = nActualFileSize;
    1547             :     }
    1548           0 :     pWMF->Seek( nStrmPos );
    1549             : 
    1550           0 :     pWMF->ReadInt32( nRecordCount );
    1551             : 
    1552           0 :     if ( !nRecordCount ) {
    1553             :         SAL_WARN("vcl.emf", "EMF\t\tEMF Header object shows record counter as 0! This shouldn't "
    1554             :                             "be possible... indicator of possible file corruption?");
    1555           0 :         return false;
    1556             :     }
    1557             : 
    1558             :     // the number of "handles", or graphics objects used in the metafile
    1559             : 
    1560             :     sal_uInt16 nHandlesCount;
    1561           0 :     pWMF->ReadUInt16( nHandlesCount );
    1562             : 
    1563             :     // the next 2 bytes are reserved, but according to [MS-EMF] section 2.2.9
    1564             :     // it MUST be 0x000 and MUST be ignored... the thing is, having such a specific
    1565             :     // value is actually pretty useful in checking if there is possible corruption
    1566             : 
    1567             :     sal_uInt16 nReserved;
    1568           0 :     pWMF->ReadUInt16( nReserved );
    1569             : 
    1570           0 :     if ( nReserved != 0x0000 ) {
    1571             :         SAL_WARN("vcl.emf", "EMF\t\tEMF Header object's reserved field is NOT 0x0000... possible "
    1572             :                             "corruption?");
    1573             :     }
    1574             : 
    1575             :     // The next 4 bytes specifies the number of characters in the metafile description.
    1576             :     // The 4 bytes after that specific the offset from this record that contains the
    1577             :     // metafile description... zero means no description string.
    1578             :     // For now, we ignore it.
    1579             : 
    1580           0 :     pWMF->SeekRel( 0x8 );
    1581             : 
    1582             :     sal_Int32 nPixX, nPixY, nMillX, nMillY;
    1583           0 :     pWMF->ReadUInt32( nPalEntries ).ReadInt32( nPixX ).ReadInt32( nPixY ).ReadInt32( nMillX ).ReadInt32( nMillY );
    1584             : 
    1585           0 :     pOut->SetrclFrame( rclFrame );
    1586           0 :     pOut->SetrclBounds( rclBounds );
    1587           0 :     pOut->SetRefPix( Size( nPixX, nPixY ) );
    1588           0 :     pOut->SetRefMill( Size( nMillX, nMillY ) );
    1589             : 
    1590           0 :     pWMF->Seek( nStartPos + nHeaderSize );
    1591           0 :     return true;
    1592             : }
    1593             : 
    1594           0 : Rectangle  EnhWMFReader::ReadRectangle( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 )
    1595             : {
    1596           0 :     Point aTL ( Point( x1, y1 ) );
    1597           0 :     Point aBR( Point( --x2, --y2 ) );
    1598           0 :     return Rectangle( aTL, aBR );
    1599             : }
    1600             : 
    1601           0 : EnhWMFReader::~EnhWMFReader()
    1602             : {
    1603             : 
    1604           3 : };
    1605             : 
    1606             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10