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

Generated by: LCOV version 1.10