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

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "winmtf.hxx"
      21             : #include <boost/scoped_array.hpp>
      22             : #include <vcl/gdimtf.hxx>
      23             : #include <vcl/wmf.hxx>
      24             : #include <rtl/crc.h>
      25             : #include <rtl/tencinfo.h>
      26             : #include <osl/endian.h>
      27             : #include <vcl/svapp.hxx>
      28             : #include <vcl/dibtools.hxx>
      29             : #include <boost/scoped_array.hpp>
      30             : 
      31             : // MS Windows defines
      32             : 
      33             : #define W_META_SETBKCOLOR           0x0201
      34             : #define W_META_SETBKMODE            0x0102
      35             : #define W_META_SETMAPMODE           0x0103
      36             : #define W_META_SETROP2              0x0104
      37             : #define W_META_SETRELABS            0x0105
      38             : #define W_META_SETPOLYFILLMODE      0x0106
      39             : #define W_META_SETSTRETCHBLTMODE    0x0107
      40             : #define W_META_SETTEXTCHAREXTRA     0x0108
      41             : #define W_META_SETTEXTCOLOR         0x0209
      42             : #define W_META_SETTEXTJUSTIFICATION 0x020A
      43             : #define W_META_SETWINDOWORG         0x020B
      44             : #define W_META_SETWINDOWEXT         0x020C
      45             : #define W_META_SETVIEWPORTORG       0x020D
      46             : #define W_META_SETVIEWPORTEXT       0x020E
      47             : #define W_META_OFFSETWINDOWORG      0x020F
      48             : #define W_META_SCALEWINDOWEXT       0x0410
      49             : #define W_META_OFFSETVIEWPORTORG    0x0211
      50             : #define W_META_SCALEVIEWPORTEXT     0x0412
      51             : #define W_META_LINETO               0x0213
      52             : #define W_META_MOVETO               0x0214
      53             : #define W_META_EXCLUDECLIPRECT      0x0415
      54             : #define W_META_INTERSECTCLIPRECT    0x0416
      55             : #define W_META_ARC                  0x0817
      56             : #define W_META_ELLIPSE              0x0418
      57             : #define W_META_FLOODFILL            0x0419
      58             : #define W_META_PIE                  0x081A
      59             : #define W_META_RECTANGLE            0x041B
      60             : #define W_META_ROUNDRECT            0x061C
      61             : #define W_META_PATBLT               0x061D
      62             : #define W_META_SAVEDC               0x001E
      63             : #define W_META_SETPIXEL             0x041F
      64             : #define W_META_OFFSETCLIPRGN        0x0220
      65             : #define W_META_TEXTOUT              0x0521
      66             : #define W_META_BITBLT               0x0922
      67             : #define W_META_STRETCHBLT           0x0B23
      68             : #define W_META_POLYGON              0x0324
      69             : #define W_META_POLYLINE             0x0325
      70             : #define W_META_ESCAPE               0x0626
      71             : #define W_META_RESTOREDC            0x0127
      72             : #define W_META_FILLREGION           0x0228
      73             : #define W_META_FRAMEREGION          0x0429
      74             : #define W_META_INVERTREGION         0x012A
      75             : #define W_META_PAINTREGION          0x012B
      76             : #define W_META_SELECTCLIPREGION     0x012C
      77             : #define W_META_SELECTOBJECT         0x012D
      78             : #define W_META_SETTEXTALIGN         0x012E
      79             : #define W_META_DRAWTEXT             0x062F
      80             : #define W_META_CHORD                0x0830
      81             : #define W_META_SETMAPPERFLAGS       0x0231
      82             : #define W_META_EXTTEXTOUT           0x0a32
      83             : #define W_META_SETDIBTODEV          0x0d33
      84             : #define W_META_SELECTPALETTE        0x0234
      85             : #define W_META_REALIZEPALETTE       0x0035
      86             : #define W_META_ANIMATEPALETTE       0x0436
      87             : #define W_META_SETPALENTRIES        0x0037
      88             : #define W_META_POLYPOLYGON          0x0538
      89             : #define W_META_RESIZEPALETTE        0x0139
      90             : #define W_META_DIBBITBLT            0x0940
      91             : #define W_META_DIBSTRETCHBLT        0x0b41
      92             : #define W_META_DIBCREATEPATTERNBRUSH 0x0142
      93             : #define W_META_STRETCHDIB           0x0f43
      94             : #define W_META_EXTFLOODFILL         0x0548
      95             : #define W_META_RESETDC              0x014C
      96             : #define W_META_STARTDOC             0x014D
      97             : #define W_META_STARTPAGE            0x004F
      98             : #define W_META_ENDPAGE              0x0050
      99             : #define W_META_ABORTDOC             0x0052
     100             : #define W_META_ENDDOC               0x005E
     101             : #define W_META_DELETEOBJECT         0x01f0
     102             : #define W_META_CREATEPALETTE        0x00f7
     103             : #define W_META_CREATEBRUSH          0x00F8
     104             : #define W_META_CREATEPATTERNBRUSH   0x01F9
     105             : #define W_META_CREATEPENINDIRECT    0x02FA
     106             : #define W_META_CREATEFONTINDIRECT   0x02FB
     107             : #define W_META_CREATEBRUSHINDIRECT  0x02FC
     108             : #define W_META_CREATEBITMAPINDIRECT 0x02FD
     109             : #define W_META_CREATEBITMAP         0x06FE
     110             : #define W_META_CREATEREGION         0x06FF
     111             : 
     112           0 : static void GetWinExtMax( const Point& rSource, Rectangle& rPlaceableBound, const sal_Int16 nMapMode )
     113             : {
     114           0 :     Point aSource( rSource );
     115           0 :     if ( nMapMode == MM_HIMETRIC )
     116           0 :         aSource.Y() = -rSource.Y();
     117           0 :     if ( aSource.X() < rPlaceableBound.Left() )
     118           0 :         rPlaceableBound.Left() = aSource.X();
     119           0 :     if ( aSource.X() > rPlaceableBound.Right() )
     120           0 :         rPlaceableBound.Right() = aSource.X();
     121           0 :     if ( aSource.Y() < rPlaceableBound.Top() )
     122           0 :         rPlaceableBound.Top() = aSource.Y();
     123           0 :     if ( aSource.Y() > rPlaceableBound.Bottom() )
     124           0 :         rPlaceableBound.Bottom() = aSource.Y();
     125           0 : }
     126             : 
     127           0 : static void GetWinExtMax( const Rectangle& rSource, Rectangle& rPlaceableBound, const sal_Int16 nMapMode )
     128             : {
     129           0 :     GetWinExtMax( rSource.TopLeft(), rPlaceableBound, nMapMode );
     130           0 :     GetWinExtMax( rSource.BottomRight(), rPlaceableBound, nMapMode );
     131           0 : }
     132             : 
     133           0 : inline Point WMFReader::ReadPoint()
     134             : {
     135           0 :     short nX = 0, nY = 0;
     136           0 :     pWMF->ReadInt16( nX ).ReadInt16( nY );
     137           0 :     return Point( nX, nY );
     138             : }
     139             : 
     140           0 : inline Point WMFReader::ReadYX()
     141             : {
     142           0 :     short nX = 0, nY = 0;
     143           0 :     pWMF->ReadInt16( nY ).ReadInt16( nX );
     144           0 :     return Point( nX, nY );
     145             : }
     146             : 
     147           0 : Rectangle WMFReader::ReadRectangle()
     148             : {
     149           0 :     Point aBR, aTL;
     150           0 :     aBR = ReadYX();
     151           0 :     aTL = ReadYX();
     152           0 :     aBR.X()--;
     153           0 :     aBR.Y()--;
     154           0 :     return Rectangle( aTL, aBR );
     155             : }
     156             : 
     157           0 : Size WMFReader::ReadYXExt()
     158             : {
     159           0 :     short nW=0, nH=0;
     160           0 :     pWMF->ReadInt16( nH ).ReadInt16( nW );
     161           0 :     return Size( nW, nH );
     162             : }
     163             : 
     164           0 : void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
     165             : {
     166           0 :     switch( nFunc )
     167             :     {
     168             :         case W_META_SETBKCOLOR:
     169             :         {
     170           0 :             pOut->SetBkColor( ReadColor() );
     171             :         }
     172           0 :         break;
     173             : 
     174             :         case W_META_SETBKMODE:
     175             :         {
     176           0 :             sal_uInt16 nDat = 0;
     177           0 :             pWMF->ReadUInt16( nDat );
     178           0 :             pOut->SetBkMode( nDat );
     179             :         }
     180           0 :         break;
     181             : 
     182             :         // !!!
     183             :         case W_META_SETMAPMODE:
     184             :         {
     185           0 :             sal_Int16 nMapMode = 0;
     186           0 :             pWMF->ReadInt16( nMapMode );
     187           0 :             pOut->SetMapMode( nMapMode );
     188             :         }
     189           0 :         break;
     190             : 
     191             :         case W_META_SETROP2:
     192             :         {
     193           0 :             sal_uInt16 nROP2 = 0;
     194           0 :             pWMF->ReadUInt16( nROP2 );
     195           0 :             pOut->SetRasterOp( nROP2 );
     196             :         }
     197           0 :         break;
     198             : 
     199             :         case W_META_SETTEXTCOLOR:
     200             :         {
     201           0 :             pOut->SetTextColor( ReadColor() );
     202             :         }
     203           0 :         break;
     204             : 
     205             :         case W_META_SETWINDOWORG:
     206             :         {
     207           0 :             pOut->SetWinOrg( ReadYX() );
     208             :         }
     209           0 :         break;
     210             : 
     211             :         case W_META_SETWINDOWEXT:
     212             :         {
     213           0 :             short nWidth = 0, nHeight = 0;
     214           0 :             pWMF->ReadInt16( nHeight ).ReadInt16( nWidth );
     215           0 :             pOut->SetWinExt( Size( nWidth, nHeight ) );
     216             :         }
     217           0 :         break;
     218             : 
     219             :         case W_META_OFFSETWINDOWORG:
     220             :         {
     221           0 :             short nXAdd = 0, nYAdd = 0;
     222           0 :             pWMF->ReadInt16( nYAdd ).ReadInt16( nXAdd );
     223           0 :             pOut->SetWinOrgOffset( nXAdd, nYAdd );
     224             :         }
     225           0 :         break;
     226             : 
     227             :         case W_META_SCALEWINDOWEXT:
     228             :         {
     229           0 :             short nXNum = 0, nXDenom = 0, nYNum = 0, nYDenom = 0;
     230           0 :             pWMF->ReadInt16( nYDenom ).ReadInt16( nYNum ).ReadInt16( nXDenom ).ReadInt16( nXNum );
     231           0 :             pOut->ScaleWinExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
     232             :         }
     233           0 :         break;
     234             : 
     235             :         case W_META_SETVIEWPORTORG:
     236             :         case W_META_SETVIEWPORTEXT:
     237           0 :         break;
     238             : 
     239             :         case W_META_OFFSETVIEWPORTORG:
     240             :         {
     241           0 :             short nXAdd = 0, nYAdd = 0;
     242           0 :             pWMF->ReadInt16( nYAdd ).ReadInt16( nXAdd );
     243           0 :             pOut->SetDevOrgOffset( nXAdd, nYAdd );
     244             :         }
     245           0 :         break;
     246             : 
     247             :         case W_META_SCALEVIEWPORTEXT:
     248             :         {
     249           0 :             short nXNum = 0, nXDenom = 0, nYNum = 0, nYDenom = 0;
     250           0 :             pWMF->ReadInt16( nYDenom ).ReadInt16( nYNum ).ReadInt16( nXDenom ).ReadInt16( nXNum );
     251           0 :             pOut->ScaleDevExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
     252             :         }
     253           0 :         break;
     254             : 
     255             :         case W_META_LINETO:
     256             :         {
     257           0 :             pOut->LineTo( ReadYX() );
     258             :         }
     259           0 :         break;
     260             : 
     261             :         case W_META_MOVETO:
     262             :         {
     263           0 :             pOut->MoveTo( ReadYX() );
     264             :         }
     265           0 :         break;
     266             : 
     267             :         case W_META_INTERSECTCLIPRECT:
     268             :         {
     269           0 :             pOut->IntersectClipRect( ReadRectangle() );
     270             :         }
     271           0 :         break;
     272             : 
     273             :         case W_META_RECTANGLE:
     274             :         {
     275           0 :             pOut->DrawRect( ReadRectangle() );
     276             :         }
     277           0 :         break;
     278             : 
     279             :         case W_META_ROUNDRECT:
     280             :         {
     281           0 :             Size aSize( ReadYXExt() );
     282           0 :             pOut->DrawRoundRect( ReadRectangle(), Size( aSize.Width() / 2, aSize.Height() / 2 ) );
     283             :         }
     284           0 :         break;
     285             : 
     286             :         case W_META_ELLIPSE:
     287             :         {
     288           0 :             pOut->DrawEllipse( ReadRectangle() );
     289             :         }
     290           0 :         break;
     291             : 
     292             :         case W_META_ARC:
     293             :         {
     294           0 :             Point aEnd( ReadYX() );
     295           0 :             Point aStart( ReadYX() );
     296           0 :             Rectangle aRect( ReadRectangle() );
     297           0 :             aRect.Justify();
     298           0 :             pOut->DrawArc( aRect, aStart, aEnd );
     299             :         }
     300           0 :         break;
     301             : 
     302             :         case W_META_PIE:
     303             :         {
     304           0 :             Point     aEnd( ReadYX() );
     305           0 :             Point     aStart( ReadYX() );
     306           0 :             Rectangle aRect( ReadRectangle() );
     307           0 :             aRect.Justify();
     308             : 
     309             :             // #i73608# OutputDevice deviates from WMF
     310             :             // semantics. start==end means full ellipse here.
     311           0 :             if( aStart == aEnd )
     312           0 :                 pOut->DrawEllipse( aRect );
     313             :             else
     314           0 :                 pOut->DrawPie( aRect, aStart, aEnd );
     315             :         }
     316           0 :         break;
     317             : 
     318             :         case W_META_CHORD:
     319             :         {
     320           0 :             Point aEnd( ReadYX() );
     321           0 :             Point aStart( ReadYX() );
     322           0 :             Rectangle aRect( ReadRectangle() );
     323           0 :             aRect.Justify();
     324           0 :             pOut->DrawChord( aRect, aStart, aEnd );
     325             :         }
     326           0 :         break;
     327             : 
     328             :         case W_META_POLYGON:
     329             :         {
     330           0 :             sal_uInt16 nPoints = 0;
     331           0 :             pWMF->ReadUInt16( nPoints );
     332           0 :             Polygon aPoly( nPoints );
     333           0 :             for( sal_uInt16 i = 0; i < nPoints; i++ )
     334           0 :                 aPoly[ i ] = ReadPoint();
     335           0 :             pOut->DrawPolygon( aPoly );
     336             :         }
     337           0 :         break;
     338             : 
     339             :         case W_META_POLYPOLYGON:
     340             :         {
     341           0 :             bool bRecordOk = true;
     342           0 :             sal_uInt16 nPolyCount(0);
     343             :             // Number of polygons:
     344           0 :             pWMF->ReadUInt16( nPolyCount );
     345           0 :             if (nPolyCount && pWMF->good())
     346             :             {
     347             :                 // Number of points of each polygon. Determine total number of points
     348           0 :                 boost::scoped_array<sal_uInt16> xPolygonPointCounts(new sal_uInt16[nPolyCount]);
     349           0 :                 sal_uInt16* pnPoints = xPolygonPointCounts.get();
     350           0 :                 PolyPolygon aPolyPoly(nPolyCount, nPolyCount);
     351           0 :                 sal_uInt16 nPoints = 0;
     352           0 :                 for (sal_uInt16 a = 0; a < nPolyCount && pWMF->good(); ++a)
     353             :                 {
     354           0 :                     pWMF->ReadUInt16( pnPoints[a] );
     355             : 
     356           0 :                     if (pnPoints[a] > SAL_MAX_UINT16 - nPoints)
     357             :                     {
     358           0 :                         bRecordOk = false;
     359           0 :                         break;
     360             :                     }
     361             : 
     362           0 :                     nPoints += pnPoints[a];
     363             :                 }
     364             : 
     365             :                 SAL_WARN_IF(!bRecordOk, "vcl.filter", "polypolygon record has more polygons than we can handle");
     366             : 
     367           0 :                 bRecordOk &= pWMF->good();
     368             : 
     369           0 :                 if (!bRecordOk)
     370             :                 {
     371           0 :                     pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
     372           0 :                     break;
     373             :                 }
     374             : 
     375             :                 // Polygon points are:
     376           0 :                 for (sal_uInt16 a = 0; a < nPolyCount && pWMF->good(); ++a)
     377             :                 {
     378           0 :                     const sal_uInt16 nPointCount(pnPoints[a]);
     379           0 :                     boost::scoped_array<Point> xPolygonPoints(new Point[nPointCount]);
     380           0 :                     Point* pPtAry = xPolygonPoints.get();
     381             : 
     382           0 :                     for(sal_uInt16 b(0); b < nPointCount && pWMF->good(); ++b)
     383             :                     {
     384           0 :                         pPtAry[b] = ReadPoint();
     385             :                     }
     386             : 
     387           0 :                     aPolyPoly.Insert(Polygon(nPointCount, pPtAry));
     388           0 :                 }
     389             : 
     390           0 :                 bRecordOk &= pWMF->good();
     391             : 
     392           0 :                 if (!bRecordOk)
     393             :                 {
     394           0 :                     pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
     395           0 :                     break;
     396             :                 }
     397             : 
     398           0 :                 pOut->DrawPolyPolygon( aPolyPoly );
     399             :             }
     400             :         }
     401           0 :         break;
     402             : 
     403             :         case W_META_POLYLINE:
     404             :         {
     405           0 :             sal_uInt16 nPoints = 0;
     406           0 :             pWMF->ReadUInt16( nPoints );
     407           0 :             Polygon aPoly( nPoints );
     408           0 :             for(sal_uInt16 i = 0; i < nPoints; i++ )
     409           0 :                 aPoly[ i ] = ReadPoint();
     410           0 :             pOut->DrawPolyLine( aPoly );
     411             :         }
     412           0 :         break;
     413             : 
     414             :         case W_META_SAVEDC:
     415             :         {
     416           0 :             pOut->Push();
     417             :         }
     418           0 :         break;
     419             : 
     420             :         case W_META_RESTOREDC:
     421             :         {
     422           0 :             pOut->Pop();
     423             :         }
     424           0 :         break;
     425             : 
     426             :         case W_META_SETPIXEL:
     427             :         {
     428           0 :             const Color aColor = ReadColor();
     429           0 :             pOut->DrawPixel( ReadYX(), aColor );
     430             :         }
     431           0 :         break;
     432             : 
     433             :         case W_META_OFFSETCLIPRGN:
     434             :         {
     435           0 :             pOut->MoveClipRegion( ReadYXExt() );
     436             :         }
     437           0 :         break;
     438             : 
     439             :         case W_META_TEXTOUT:
     440             :         {
     441           0 :             sal_uInt16 nLength = 0;
     442           0 :             pWMF->ReadUInt16( nLength );
     443           0 :             if ( nLength )
     444             :             {
     445           0 :                 boost::scoped_array<char> pChar(new char[ ( nLength + 1 ) &~ 1 ]);
     446           0 :                 pWMF->Read( pChar.get(), ( nLength + 1 ) &~ 1 );
     447           0 :                 OUString aText( pChar.get(), nLength, pOut->GetCharSet() );
     448           0 :                 pChar.reset();
     449           0 :                 Point aPosition( ReadYX() );
     450           0 :                 pOut->DrawText( aPosition, aText );
     451             :             }
     452             :         }
     453           0 :         break;
     454             : 
     455             :         case W_META_EXTTEXTOUT:
     456             :         {
     457           0 :             sal_uInt16  nLen = 0, nOptions = 0;
     458           0 :             sal_Int32   nRecordPos, nRecordSize = 0, nOriginalTextLen, nNewTextLen;
     459           0 :             Point       aPosition;
     460           0 :             Rectangle   aRect;
     461           0 :             boost::scoped_array<sal_Int32> pDXAry;
     462             : 
     463           0 :             pWMF->SeekRel(-6);
     464           0 :             nRecordPos = pWMF->Tell();
     465           0 :             pWMF->ReadInt32( nRecordSize );
     466           0 :             pWMF->SeekRel(2);
     467           0 :             aPosition = ReadYX();
     468           0 :             pWMF->ReadUInt16( nLen ).ReadUInt16( nOptions );
     469             : 
     470           0 :             sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT;
     471           0 :             if ( nOptions & ETO_RTLREADING )
     472           0 :                 nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
     473           0 :             pOut->SetTextLayoutMode( nTextLayoutMode );
     474             :             DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in WMF" );
     475             : 
     476             :             // output only makes sense if the text contains characters
     477           0 :             if( nLen )
     478             :             {
     479           0 :                 nOriginalTextLen = nLen;
     480           0 :                 if( nOptions & ETO_CLIPPED )
     481             :                 {
     482           0 :                     const Point aPt1( ReadPoint() );
     483           0 :                     const Point aPt2( ReadPoint() );
     484           0 :                     aRect = Rectangle( aPt1, aPt2 );
     485             :                 }
     486           0 :                 boost::scoped_array<char> pChar(new char[ ( nOriginalTextLen + 1 ) &~ 1 ]);
     487           0 :                 pWMF->Read( pChar.get(), ( nOriginalTextLen + 1 ) &~ 1 );
     488           0 :                 OUString aText( pChar.get(), (sal_uInt16)nOriginalTextLen, pOut->GetCharSet() );// after this conversion the text may contain
     489           0 :                 nNewTextLen = aText.getLength();                                          // less character (japanese version), so the
     490           0 :                 pChar.reset();                                                         // dxAry will not fit
     491             : 
     492           0 :                 if ( nNewTextLen )
     493             :                 {
     494           0 :                     sal_uInt32  nMaxStreamPos = nRecordPos + ( nRecordSize << 1 );
     495           0 :                     sal_Int32   nDxArySize =  nMaxStreamPos - pWMF->Tell();
     496           0 :                     sal_Int32   nDxAryEntries = nDxArySize >> 1;
     497           0 :                     bool        bUseDXAry = false;
     498             : 
     499           0 :                     if ( ( ( nDxAryEntries % nOriginalTextLen ) == 0 ) && ( nNewTextLen <= nOriginalTextLen ) )
     500             :                     {
     501           0 :                         sal_Int16 nDx = 0, nDxTmp = 0;
     502             :                         sal_uInt16 i; //needed just outside the for
     503           0 :                         pDXAry.reset(new sal_Int32[ nNewTextLen ]);
     504           0 :                         for (i = 0; i < nNewTextLen; i++ )
     505             :                         {
     506           0 :                             if ( pWMF->Tell() >= nMaxStreamPos )
     507           0 :                                 break;
     508           0 :                             pWMF->ReadInt16( nDx );
     509           0 :                             if ( nNewTextLen != nOriginalTextLen )
     510             :                             {
     511           0 :                                 sal_Unicode nUniChar = aText[i];
     512           0 :                                 OString aTmp(&nUniChar, 1, pOut->GetCharSet());
     513           0 :                                 if ( aTmp.getLength() > 1 )
     514             :                                 {
     515           0 :                                     sal_Int32 nDxCount = aTmp.getLength() - 1;
     516           0 :                                     if ( ( ( nDxCount * 2 ) + pWMF->Tell() ) > nMaxStreamPos )
     517           0 :                                         break;
     518           0 :                                     while ( nDxCount-- )
     519             :                                     {
     520           0 :                                         pWMF->ReadInt16( nDxTmp );
     521           0 :                                         nDx = nDx + nDxTmp;
     522             :                                     }
     523           0 :                                 }
     524             :                             }
     525           0 :                             pDXAry[ i ] = nDx;
     526             :                         }
     527           0 :                         if ( i == nNewTextLen )
     528           0 :                             bUseDXAry = true;
     529             :                     }
     530           0 :                     if ( pDXAry && bUseDXAry )
     531           0 :                         pOut->DrawText( aPosition, aText, pDXAry.get() );
     532             :                     else
     533           0 :                         pOut->DrawText( aPosition, aText );
     534           0 :                 }
     535           0 :             }
     536             :         }
     537           0 :         break;
     538             : 
     539             :         case W_META_SELECTOBJECT:
     540             :         {
     541           0 :             sal_Int16   nObjIndex = 0;
     542           0 :             pWMF->ReadInt16( nObjIndex );
     543           0 :             pOut->SelectObject( nObjIndex );
     544             :         }
     545           0 :         break;
     546             : 
     547             :         case W_META_SETTEXTALIGN:
     548             :         {
     549           0 :             sal_uInt16  nAlign = 0;
     550           0 :             pWMF->ReadUInt16( nAlign );
     551           0 :             pOut->SetTextAlign( nAlign );
     552             :         }
     553           0 :         break;
     554             : 
     555             :         case W_META_BITBLT:
     556             :         {
     557             :             // 0-3   : nWinROP                      #93454#
     558             :             // 4-5   : y offset of source bitmap
     559             :             // 6-7   : x offset of source bitmap
     560             :             // 8-9   : used height of source bitmap
     561             :             // 10-11 : used width  of source bitmap
     562             :             // 12-13 : destination position y (in pixel)
     563             :             // 14-15 : destination position x (in pixel)
     564             :             // 16-17 : dont know
     565             :             // 18-19 : Width Bitmap in Pixel
     566             :             // 20-21 : Height Bitmap in Pixel
     567             :             // 22-23 : bytes per scanline
     568             :             // 24    : planes
     569             :             // 25    : bitcount
     570             : 
     571           0 :             sal_Int32   nWinROP = 0;
     572           0 :             sal_uInt16  nSx = 0, nSy = 0, nSxe = 0, nSye = 0, nDontKnow = 0, nWidth = 0, nHeight = 0, nBytesPerScan = 0;
     573             :             sal_uInt8   nPlanes, nBitCount;
     574             : 
     575           0 :             pWMF->ReadInt32( nWinROP )
     576           0 :                  .ReadUInt16( nSy ).ReadUInt16( nSx ).ReadUInt16( nSye ).ReadUInt16( nSxe );
     577           0 :             Point aPoint( ReadYX() );
     578           0 :             pWMF->ReadUInt16( nDontKnow ).ReadUInt16( nWidth ).ReadUInt16( nHeight ).ReadUInt16( nBytesPerScan ).ReadUChar( nPlanes ).ReadUChar( nBitCount );
     579             : 
     580           0 :             if ( nWidth && nHeight && ( nPlanes == 1 ) && ( nBitCount == 1 ) )
     581             :             {
     582           0 :                 Bitmap aBmp( Size( nWidth, nHeight ), nBitCount );
     583             :                 BitmapWriteAccess* pAcc;
     584           0 :                 pAcc = aBmp.AcquireWriteAccess();
     585           0 :                 if ( pAcc )
     586             :                 {
     587           0 :                     for (sal_uInt16 y = 0; y < nHeight; y++ )
     588             :                     {
     589           0 :                         sal_uInt16 x = 0;
     590           0 :                         for (sal_uInt16 scan = 0; scan < nBytesPerScan; scan++ )
     591             :                         {
     592           0 :                             sal_Int8 nEightPixels = 0;
     593           0 :                             pWMF->ReadSChar( nEightPixels );
     594           0 :                             for (sal_Int8 i = 7; i >= 0; i-- )
     595             :                             {
     596           0 :                                 if ( x < nWidth )
     597             :                                 {
     598           0 :                                     pAcc->SetPixelIndex( y, x, (nEightPixels>>i)&1 );
     599             :                                 }
     600           0 :                                 x++;
     601             :                             }
     602             :                         }
     603             :                     }
     604           0 :                     aBmp.ReleaseAccess( pAcc );
     605           0 :                     if ( nSye && nSxe &&
     606           0 :                         ( ( nSx + nSxe ) <= aBmp.GetSizePixel().Width() ) &&
     607           0 :                             ( ( nSy + nSye <= aBmp.GetSizePixel().Height() ) ) )
     608             :                     {
     609           0 :                         Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
     610           0 :                         aBmp.Crop( aCropRect );
     611             :                     }
     612           0 :                     Rectangle aDestRect( aPoint, Size( nSxe, nSye ) );
     613           0 :                     aBmpSaveList.push_back( new BSaveStruct( aBmp, aDestRect, nWinROP, pOut->GetFillStyle () ) );
     614           0 :                 }
     615             :             }
     616             :         }
     617           0 :         break;
     618             : 
     619             :         case W_META_STRETCHBLT:
     620             :         case W_META_DIBBITBLT:
     621             :         case W_META_DIBSTRETCHBLT:
     622             :         case W_META_STRETCHDIB:
     623             :         {
     624           0 :             sal_Int32   nWinROP = 0;
     625           0 :             sal_uInt16  nSx = 0, nSy = 0, nSxe = 0, nSye = 0, nUsage = 0;
     626           0 :             Bitmap      aBmp;
     627             : 
     628           0 :             pWMF->ReadInt32( nWinROP );
     629             : 
     630           0 :             if( nFunc == W_META_STRETCHDIB )
     631           0 :                 pWMF->ReadUInt16( nUsage );
     632             : 
     633             :             // nSye and nSxe is the number of pixels that has to been used
     634             :             // If they are set to zero, it is as indicator not to scale the bitmap later
     635             : 
     636           0 :             if( nFunc == W_META_STRETCHDIB || nFunc == W_META_STRETCHBLT || nFunc == W_META_DIBSTRETCHBLT )
     637           0 :                 pWMF->ReadUInt16( nSye ).ReadUInt16( nSxe );
     638             : 
     639             :             // nSy and nx is the offset of the first pixel
     640           0 :             pWMF->ReadUInt16( nSy ).ReadUInt16( nSx );
     641             : 
     642           0 :             if( nFunc == W_META_STRETCHDIB || nFunc == W_META_DIBBITBLT || nFunc == W_META_DIBSTRETCHBLT )
     643             :             {
     644           0 :                 if ( nWinROP == PATCOPY )
     645           0 :                     pWMF->ReadUInt16( nUsage );    // i don't know anything of this parameter, so its called nUsage
     646             :                                         // pOut->DrawRect( Rectangle( ReadYX(), aDestSize ), false );
     647             : 
     648           0 :                 Size aDestSize( ReadYXExt() );
     649           0 :                 if ( aDestSize.Width() && aDestSize.Height() )  // #92623# do not try to read buggy bitmaps
     650             :                 {
     651           0 :                     Rectangle aDestRect( ReadYX(), aDestSize );
     652           0 :                     if ( nWinROP != PATCOPY )
     653           0 :                         ReadDIB(aBmp, *pWMF, false);
     654             : 
     655             :                     // test if it is sensible to crop
     656           0 :                     if ( nSye && nSxe &&
     657           0 :                         ( ( nSx + nSxe ) <= aBmp.GetSizePixel().Width() ) &&
     658           0 :                             ( ( nSy + nSye <= aBmp.GetSizePixel().Height() ) ) )
     659             :                     {
     660           0 :                         Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
     661           0 :                         aBmp.Crop( aCropRect );
     662             :                     }
     663           0 :                     aBmpSaveList.push_back( new BSaveStruct( aBmp, aDestRect, nWinROP, pOut->GetFillStyle () ) );
     664             :                 }
     665           0 :             }
     666             :         }
     667           0 :         break;
     668             : 
     669             :         case W_META_DIBCREATEPATTERNBRUSH:
     670             :         {
     671           0 :             Bitmap  aBmp;
     672             :             BitmapReadAccess* pBmp;
     673           0 :             sal_uInt32  nRed = 0, nGreen = 0, nBlue = 0, nCount = 1;
     674           0 :             sal_uInt16  nFunction = 0;
     675             : 
     676           0 :             pWMF->ReadUInt16( nFunction ).ReadUInt16( nFunction );
     677             : 
     678           0 :             ReadDIB(aBmp, *pWMF, false);
     679           0 :             pBmp = aBmp.AcquireReadAccess();
     680           0 :             if ( pBmp )
     681             :             {
     682           0 :                 for ( sal_Int32 y = 0; y < pBmp->Height(); y++ )
     683             :                 {
     684           0 :                     for ( sal_Int32 x = 0; x < pBmp->Width(); x++ )
     685             :                     {
     686           0 :                         const BitmapColor aColor( pBmp->GetColor( y, x ) );
     687             : 
     688           0 :                         nRed += aColor.GetRed();
     689           0 :                         nGreen += aColor.GetGreen();
     690           0 :                         nBlue += aColor.GetBlue();
     691           0 :                     }
     692             :                 }
     693           0 :                 nCount = pBmp->Height() * pBmp->Width();
     694           0 :                 if ( !nCount )
     695           0 :                     nCount++;
     696           0 :                 aBmp.ReleaseAccess( pBmp );
     697             :             }
     698           0 :             Color aColor( (sal_uInt8)( nRed / nCount ), (sal_uInt8)( nGreen / nCount ), (sal_uInt8)( nBlue / nCount ) );
     699           0 :             pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( aColor, false ) );
     700             :         }
     701           0 :         break;
     702             : 
     703             :         case W_META_DELETEOBJECT:
     704             :         {
     705           0 :             sal_Int16 nIndex = 0;
     706           0 :             pWMF->ReadInt16( nIndex );
     707           0 :             pOut->DeleteObject( nIndex );
     708             :         }
     709           0 :         break;
     710             : 
     711             :         case W_META_CREATEPALETTE:
     712             :         {
     713           0 :             pOut->CreateObject( GDI_DUMMY );
     714             :         }
     715           0 :         break;
     716             : 
     717             :         case W_META_CREATEBRUSH:
     718             :         {
     719           0 :             pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), false ) );
     720             :         }
     721           0 :         break;
     722             : 
     723             :         case W_META_CREATEPATTERNBRUSH:
     724             :         {
     725           0 :             pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), false ) );
     726             :         }
     727           0 :         break;
     728             : 
     729             :         case W_META_CREATEPENINDIRECT:
     730             :         {
     731           0 :             LineInfo    aLineInfo;
     732           0 :             sal_uInt16      nStyle = 0, nWidth = 0, nHeight = 0;
     733             : 
     734           0 :             pWMF->ReadUInt16( nStyle ).ReadUInt16( nWidth ).ReadUInt16( nHeight );
     735             : 
     736           0 :             if ( nWidth )
     737           0 :                 aLineInfo.SetWidth( nWidth );
     738             : 
     739           0 :             bool bTransparent = false;
     740           0 :             switch( nStyle & 0xFF )
     741             :             {
     742             :                 case PS_DASHDOTDOT :
     743           0 :                     aLineInfo.SetStyle( LINE_DASH );
     744           0 :                     aLineInfo.SetDashCount( 1 );
     745           0 :                     aLineInfo.SetDotCount( 2 );
     746           0 :                     aLineInfo.SetDashLen( 150 );
     747           0 :                     aLineInfo.SetDotLen( 30 );
     748           0 :                     aLineInfo.SetDistance( 50 );
     749           0 :                 break;
     750             :                 case PS_DASHDOT :
     751           0 :                     aLineInfo.SetStyle( LINE_DASH );
     752           0 :                     aLineInfo.SetDashCount( 1 );
     753           0 :                     aLineInfo.SetDotCount( 1 );
     754           0 :                     aLineInfo.SetDashLen( 150 );
     755           0 :                     aLineInfo.SetDotLen( 30 );
     756           0 :                     aLineInfo.SetDistance( 90 );
     757           0 :                 break;
     758             :                 case PS_DOT :
     759           0 :                     aLineInfo.SetStyle( LINE_DASH );
     760           0 :                     aLineInfo.SetDashCount( 0 );
     761           0 :                     aLineInfo.SetDotCount( 1 );
     762           0 :                     aLineInfo.SetDotLen( 30 );
     763           0 :                     aLineInfo.SetDistance( 50 );
     764           0 :                 break;
     765             :                 case PS_DASH :
     766           0 :                     aLineInfo.SetStyle( LINE_DASH );
     767           0 :                     aLineInfo.SetDashCount( 1 );
     768           0 :                     aLineInfo.SetDotCount( 0 );
     769           0 :                     aLineInfo.SetDashLen( 225 );
     770           0 :                     aLineInfo.SetDistance( 100 );
     771           0 :                 break;
     772             :                 case PS_NULL :
     773           0 :                     bTransparent = true;
     774           0 :                     aLineInfo.SetStyle( LINE_NONE );
     775           0 :                 break;
     776             :                 default :
     777             :                 case PS_INSIDEFRAME :
     778             :                 case PS_SOLID :
     779           0 :                     aLineInfo.SetStyle( LINE_SOLID );
     780             :             }
     781           0 :             switch( nStyle & 0xF00 )
     782             :             {
     783             :                 case PS_ENDCAP_ROUND :
     784           0 :                     aLineInfo.SetLineCap( com::sun::star::drawing::LineCap_ROUND );
     785           0 :                 break;
     786             :                 case PS_ENDCAP_SQUARE :
     787           0 :                     aLineInfo.SetLineCap( com::sun::star::drawing::LineCap_SQUARE );
     788           0 :                 break;
     789             :                 case PS_ENDCAP_FLAT :
     790             :                 default :
     791           0 :                     aLineInfo.SetLineCap( com::sun::star::drawing::LineCap_BUTT );
     792             :             }
     793           0 :             switch( nStyle & 0xF000 )
     794             :             {
     795             :                 case PS_JOIN_ROUND :
     796           0 :                     aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_ROUND );
     797           0 :                 break;
     798             :                 case PS_JOIN_MITER :
     799           0 :                     aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_MITER );
     800           0 :                 break;
     801             :                 case PS_JOIN_BEVEL :
     802           0 :                     aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_BEVEL );
     803           0 :                 break;
     804             :                 default :
     805           0 :                     aLineInfo.SetLineJoin ( basegfx::B2DLINEJOIN_NONE );
     806             :             }
     807           0 :             pOut->CreateObject( GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
     808             :         }
     809           0 :         break;
     810             : 
     811             :         case W_META_CREATEBRUSHINDIRECT:
     812             :         {
     813           0 :             sal_uInt16  nStyle = 0;
     814           0 :             pWMF->ReadUInt16( nStyle );
     815           0 :             pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? true : false ) );
     816             :         }
     817           0 :         break;
     818             : 
     819             :         case W_META_CREATEFONTINDIRECT:
     820             :         {
     821           0 :             Size    aFontSize;
     822             :             char    lfFaceName[ LF_FACESIZE ];
     823           0 :             sal_Int16   lfEscapement = 0, lfOrientation = 0, lfWeight = 0;  // ( formerly sal_uInt16 )
     824             : 
     825           0 :             LOGFONTW aLogFont;
     826           0 :             aFontSize = ReadYXExt();
     827           0 :             pWMF->ReadInt16( lfEscapement ).ReadInt16( lfOrientation ).ReadInt16( lfWeight )
     828           0 :                    .ReadUChar( aLogFont.lfItalic ).ReadUChar( aLogFont.lfUnderline ).ReadUChar( aLogFont.lfStrikeOut ).ReadUChar( aLogFont.lfCharSet ).ReadUChar( aLogFont.lfOutPrecision )
     829           0 :                        .ReadUChar( aLogFont.lfClipPrecision ).ReadUChar( aLogFont.lfQuality ).ReadUChar( aLogFont.lfPitchAndFamily );
     830           0 :             pWMF->Read( lfFaceName, LF_FACESIZE );
     831           0 :             aLogFont.lfWidth = aFontSize.Width();
     832           0 :             aLogFont.lfHeight = aFontSize.Height();
     833           0 :             aLogFont.lfEscapement = lfEscapement;
     834           0 :             aLogFont.lfOrientation = lfOrientation;
     835           0 :             aLogFont.lfWeight = lfWeight;
     836             : 
     837             :             rtl_TextEncoding eCharSet;
     838           0 :             if ( ( aLogFont.lfCharSet == OEM_CHARSET ) || ( aLogFont.lfCharSet == DEFAULT_CHARSET ) )
     839           0 :                 eCharSet = osl_getThreadTextEncoding();
     840             :             else
     841           0 :                 eCharSet = rtl_getTextEncodingFromWindowsCharset( aLogFont.lfCharSet );
     842           0 :             if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
     843           0 :                 eCharSet = osl_getThreadTextEncoding();
     844           0 :             if ( eCharSet == RTL_TEXTENCODING_SYMBOL )
     845           0 :                 eCharSet = RTL_TEXTENCODING_MS_1252;
     846           0 :             aLogFont.alfFaceName = OUString( lfFaceName, strlen(lfFaceName), eCharSet );
     847             : 
     848           0 :             pOut->CreateObject( GDI_FONT, new WinMtfFontStyle( aLogFont ) );
     849             :         }
     850           0 :         break;
     851             : 
     852             :         case W_META_CREATEBITMAPINDIRECT:
     853             :         {
     854           0 :             pOut->CreateObject( GDI_DUMMY );
     855             :         }
     856           0 :         break;
     857             : 
     858             :         case W_META_CREATEBITMAP:
     859             :         {
     860           0 :             pOut->CreateObject( GDI_DUMMY );
     861             :         }
     862           0 :         break;
     863             : 
     864             :         case W_META_CREATEREGION:
     865             :         {
     866           0 :             pOut->CreateObject( GDI_DUMMY );
     867             :         }
     868           0 :         break;
     869             : 
     870             :         case W_META_EXCLUDECLIPRECT :
     871             :         {
     872           0 :             pOut->ExcludeClipRect( ReadRectangle() );
     873             :         }
     874           0 :         break;
     875             : 
     876             :         case W_META_PATBLT:
     877             :         {
     878           0 :             sal_uInt32 nROP = 0, nOldROP = 0;
     879           0 :             pWMF->ReadUInt32( nROP );
     880           0 :             Size aSize = ReadYXExt();
     881           0 :             nOldROP = pOut->SetRasterOp( nROP );
     882           0 :             pOut->DrawRect( Rectangle( ReadYX(), aSize ), false );
     883           0 :             pOut->SetRasterOp( nOldROP );
     884             :         }
     885           0 :         break;
     886             : 
     887             :         case W_META_SELECTCLIPREGION:
     888             :         {
     889           0 :             sal_Int16 nObjIndex = 0;
     890           0 :             pWMF->ReadInt16( nObjIndex );
     891           0 :             if ( !nObjIndex )
     892             :             {
     893           0 :                 PolyPolygon aEmptyPolyPoly;
     894           0 :                 pOut->SetClipPath( aEmptyPolyPoly, RGN_COPY, true );
     895             :             }
     896             :         }
     897           0 :         break;
     898             : 
     899             :         case W_META_ESCAPE :
     900             :         {
     901             :             // nRecSize has been checked previously to be greater than 3
     902           0 :             sal_uInt64 nMetaRecSize = static_cast< sal_uInt64 >( nRecSize - 2 ) * 2;
     903           0 :             sal_uInt64 nMetaRecEndPos = pWMF->Tell() + nMetaRecSize;
     904             : 
     905             :             // taking care that nRecSize does not exceed the maximal stream position
     906           0 :             if ( nMetaRecEndPos > nEndPos )
     907             :             {
     908           0 :                 pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
     909           0 :                 break;
     910             :             }
     911           0 :             if ( nRecSize >= 4 )    // minimal escape length
     912             :             {
     913           0 :                 sal_uInt16  nMode = 0, nLen = 0;
     914           0 :                 pWMF->ReadUInt16( nMode )
     915           0 :                      .ReadUInt16( nLen );
     916           0 :                 if ( ( nMode == W_MFCOMMENT ) && ( nLen >= 4 ) )
     917             :                 {
     918           0 :                     sal_uInt32 nNewMagic = 0; // we have to read int32 for
     919           0 :                     pWMF->ReadUInt32( nNewMagic );   // META_ESCAPE_ENHANCED_METAFILE CommentIdentifier
     920             : 
     921           0 :                     if( nNewMagic == 0x2c2a4f4f &&  nLen >= 14 )
     922             :                     {
     923           0 :                         sal_uInt16 nMagic2 = 0;
     924           0 :                         pWMF->ReadUInt16( nMagic2 );
     925           0 :                         if( nMagic2 == 0x0a ) // 2nd half of magic
     926             :                         {                     // continue with private escape
     927           0 :                             sal_uInt32 nCheck = 0, nEsc = 0;
     928           0 :                             pWMF->ReadUInt32( nCheck )
     929           0 :                                  .ReadUInt32( nEsc );
     930             : 
     931           0 :                             sal_uInt32 nEscLen = nLen - 14;
     932           0 :                             if ( nEscLen <= ( nRecSize * 2 ) )
     933             :                             {
     934             : #ifdef OSL_BIGENDIAN
     935             :                                 sal_uInt32 nTmp = OSL_SWAPDWORD( nEsc );
     936             :                                 sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
     937             : #else
     938           0 :                                 sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
     939             : #endif
     940           0 :                                 boost::scoped_array<sal_Int8> pData;
     941             : 
     942           0 :                                 if ( ( static_cast< sal_uInt64 >( nEscLen ) + pWMF->Tell() ) > nMetaRecEndPos )
     943             :                                 {
     944           0 :                                     pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
     945           0 :                                     break;
     946             :                                 }
     947           0 :                                 if ( nEscLen > 0 )
     948             :                                 {
     949           0 :                                     pData.reset(new sal_Int8[ nEscLen ]);
     950           0 :                                     pWMF->Read( pData.get(), nEscLen );
     951           0 :                                     nCheckSum = rtl_crc32( nCheckSum, pData.get(), nEscLen );
     952             :                                 }
     953           0 :                                 if ( nCheck == nCheckSum )
     954             :                                 {
     955           0 :                                     switch( nEsc )
     956             :                                     {
     957             :                                         case PRIVATE_ESCAPE_UNICODE :
     958             :                                         {
     959             :                                             // we will use text instead of polygons only if we have the correct font
     960           0 :                                             if ( Application::GetDefaultDevice()->IsFontAvailable( pOut->GetFont().GetName() ) )
     961             :                                             {
     962           0 :                                                 Point  aPt;
     963           0 :                                                 OUString aString;
     964             :                                                 sal_uInt32  nStringLen, nDXCount;
     965           0 :                                                 boost::scoped_array<sal_Int32> pDXAry;
     966           0 :                                                 SvMemoryStream aMemoryStream( nEscLen );
     967           0 :                                                 aMemoryStream.Write( pData.get(), nEscLen );
     968           0 :                                                 aMemoryStream.Seek( STREAM_SEEK_TO_BEGIN );
     969             :                                                 //#fdo39428 SvStream no longer supports operator>>(long&)
     970           0 :                                                 sal_Int32 nTmpX(0), nTmpY(0);
     971           0 :                                                 aMemoryStream.ReadInt32( nTmpX )
     972           0 :                                                              .ReadInt32( nTmpY )
     973           0 :                                                              .ReadUInt32( nStringLen );
     974           0 :                                                  aPt.X() = nTmpX;
     975           0 :                                                  aPt.Y() = nTmpY;
     976             : 
     977           0 :                                                 if ( ( static_cast< sal_uInt64 >( nStringLen ) * sizeof( sal_Unicode ) ) < ( nEscLen - aMemoryStream.Tell() ) )
     978             :                                                 {
     979             : 
     980           0 :                                                     aString = read_uInt16s_ToOUString(aMemoryStream, nStringLen);
     981           0 :                                                     aMemoryStream.ReadUInt32( nDXCount );
     982           0 :                                                     if ( ( static_cast< sal_uInt64 >( nDXCount ) * sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.Tell() ) )
     983           0 :                                                         nDXCount = 0;
     984           0 :                                                     if ( nDXCount )
     985           0 :                                                         pDXAry.reset(new sal_Int32[ nDXCount ]);
     986           0 :                                                     for  (sal_uInt32 i = 0; i < nDXCount; i++ )
     987           0 :                                                         aMemoryStream.ReadInt32( pDXAry[ i ] );
     988           0 :                                                     aMemoryStream.ReadUInt32( nSkipActions );
     989           0 :                                                     pOut->DrawText( aPt, aString, pDXAry.get() );
     990           0 :                                                 }
     991             :                                             }
     992             :                                         }
     993           0 :                                         break;
     994             :                                     }
     995           0 :                                 }
     996             :                             }
     997           0 :                         }
     998             :                     }
     999           0 :                     else if ( (nNewMagic == static_cast< sal_uInt32 >(0x43464D57)) && (nLen >= 34) && ( (sal_Int32)(nLen + 10) <= (sal_Int32)(nRecSize * 2) ))
    1000             :                     {
    1001           0 :                         sal_uInt32 nComType = 0, nVersion = 0, nFlags = 0, nComRecCount = 0,
    1002           0 :                                    nCurRecSize = 0, nRemainingSize = 0, nEMFTotalSize = 0;
    1003           0 :                         sal_uInt16 nCheck = 0;
    1004             : 
    1005           0 :                         pWMF->ReadUInt32( nComType ).ReadUInt32( nVersion ).ReadUInt16( nCheck ).ReadUInt32( nFlags )
    1006           0 :                              .ReadUInt32( nComRecCount ).ReadUInt32( nCurRecSize )
    1007           0 :                              .ReadUInt32( nRemainingSize ).ReadUInt32( nEMFTotalSize ); // the nRemainingSize is not mentioned in MSDN documentation
    1008             :                                                                   // but it seems to be required to read in data produced by OLE
    1009             : 
    1010           0 :                         if( nComType == 0x01 && nVersion == 0x10000 && nComRecCount )
    1011             :                         {
    1012           0 :                             if( !nEMFRec )
    1013             :                             {   // first EMF comment
    1014           0 :                                 nEMFRecCount    = nComRecCount;
    1015           0 :                                 nEMFSize        = nEMFTotalSize;
    1016           0 :                                 pEMFStream = new SvMemoryStream( nEMFSize );
    1017             :                             }
    1018           0 :                             else if( ( nEMFRecCount != nComRecCount ) || ( nEMFSize != nEMFTotalSize ) ) // add additional checks here
    1019             :                             {
    1020             :                                 // total records should be the same as in previous comments
    1021           0 :                                 nEMFRecCount = 0xFFFFFFFF;
    1022           0 :                                 delete pEMFStream;
    1023           0 :                                 pEMFStream = NULL;
    1024             :                             }
    1025           0 :                             nEMFRec++;
    1026             : 
    1027           0 :                             if( pEMFStream && nCurRecSize + 34 > nLen )
    1028             :                             {
    1029           0 :                                 nEMFRecCount = 0xFFFFFFFF;
    1030           0 :                                 delete pEMFStream;
    1031           0 :                                 pEMFStream = NULL;
    1032             :                             }
    1033             : 
    1034           0 :                             if( pEMFStream )
    1035             :                             {
    1036           0 :                                 boost::scoped_array<sal_Int8> pBuf(new sal_Int8[ nCurRecSize ]);
    1037           0 :                                 sal_uInt32 nCount = pWMF->Read( pBuf.get(), nCurRecSize );
    1038           0 :                                 if( nCount == nCurRecSize )
    1039           0 :                                     pEMFStream->Write( pBuf.get(), nCount );
    1040             :                             }
    1041             :                         }
    1042             :                     }
    1043             :                 }
    1044             :             }
    1045             :         }
    1046           0 :         break;
    1047             : 
    1048             :         case W_META_SETRELABS:
    1049             :         case W_META_SETPOLYFILLMODE:
    1050             :         case W_META_SETSTRETCHBLTMODE:
    1051             :         case W_META_SETTEXTCHAREXTRA:
    1052             :         case W_META_SETTEXTJUSTIFICATION:
    1053             :         case W_META_FLOODFILL :
    1054             :         case W_META_FILLREGION:
    1055             :         case W_META_FRAMEREGION:
    1056             :         case W_META_INVERTREGION:
    1057             :         case W_META_PAINTREGION:
    1058             :         case W_META_DRAWTEXT:
    1059             :         case W_META_SETMAPPERFLAGS:
    1060             :         case W_META_SETDIBTODEV:
    1061             :         case W_META_SELECTPALETTE:
    1062             :         case W_META_REALIZEPALETTE:
    1063             :         case W_META_ANIMATEPALETTE:
    1064             :         case W_META_SETPALENTRIES:
    1065             :         case W_META_RESIZEPALETTE:
    1066             :         case W_META_EXTFLOODFILL:
    1067             :         case W_META_RESETDC:
    1068             :         case W_META_STARTDOC:
    1069             :         case W_META_STARTPAGE:
    1070             :         case W_META_ENDPAGE:
    1071             :         case W_META_ABORTDOC:
    1072             :         case W_META_ENDDOC:
    1073           0 :         break;
    1074             :     }
    1075           0 : }
    1076             : 
    1077           0 : bool WMFReader::ReadHeader()
    1078             : {
    1079           0 :     sal_Size nStrmPos = pWMF->Tell();
    1080             : 
    1081           0 :     sal_uInt32 nPlaceableMetaKey(0);
    1082             :     // if available read the METAFILEHEADER
    1083           0 :     pWMF->ReadUInt32( nPlaceableMetaKey );
    1084           0 :     if (!pWMF->good())
    1085           0 :         return false;
    1086             : 
    1087           0 :     Rectangle aPlaceableBound;
    1088             : 
    1089           0 :     if (nPlaceableMetaKey == 0x9ac6cdd7L)
    1090             :     { //TODO do some real error handling here
    1091             :         sal_Int16 nVal;
    1092             : 
    1093             :         // Skip reserved bytes
    1094           0 :         pWMF->SeekRel(2);
    1095             : 
    1096             :         // BoundRect
    1097           0 :         pWMF->ReadInt16( nVal );
    1098           0 :         aPlaceableBound.Left() = nVal;
    1099           0 :         pWMF->ReadInt16( nVal );
    1100           0 :         aPlaceableBound.Top() = nVal;
    1101           0 :         pWMF->ReadInt16( nVal );
    1102           0 :         aPlaceableBound.Right() = nVal;
    1103           0 :         pWMF->ReadInt16( nVal );
    1104           0 :         aPlaceableBound.Bottom() = nVal;
    1105             : 
    1106             :         // inch
    1107           0 :         pWMF->ReadUInt16( nUnitsPerInch );
    1108             : 
    1109             :         // reserved
    1110           0 :         pWMF->SeekRel( 4 );
    1111             : 
    1112             :         // Skip and don't check the checksum
    1113           0 :         pWMF->SeekRel( 2 );
    1114             :     }
    1115             :     else
    1116             :     {
    1117           0 :         nUnitsPerInch = 96;
    1118           0 :         pWMF->Seek( nStrmPos + 18 );    // set the streampos to the start of the metaactions
    1119           0 :         GetPlaceableBound( aPlaceableBound, pWMF );
    1120           0 :         pWMF->Seek( nStrmPos );
    1121           0 :         if ( pExternalHeader != NULL && ( pExternalHeader->mapMode == MM_ISOTROPIC
    1122           0 :                                         || pExternalHeader->mapMode == MM_ANISOTROPIC ) )
    1123             :         {
    1124             :             // #n417818#: If we have an external header then overwrite the bounds!
    1125             :             Rectangle aExtRect(0, 0,
    1126           0 :                           pExternalHeader->xExt*567*nUnitsPerInch/1440/1000,
    1127           0 :                           pExternalHeader->yExt*567*nUnitsPerInch/1440/1000);
    1128           0 :             GetWinExtMax( aExtRect, aPlaceableBound, pExternalHeader->mapMode );
    1129           0 :             pOut->SetMapMode( pExternalHeader->mapMode );
    1130             :         }
    1131             :     }
    1132             : 
    1133           0 :     pOut->SetWinOrg( aPlaceableBound.TopLeft() );
    1134           0 :     Size aWMFSize( labs( aPlaceableBound.GetWidth() ), labs( aPlaceableBound.GetHeight() ) );
    1135           0 :     pOut->SetWinExt( aWMFSize );
    1136             : 
    1137           0 :     Size aDevExt( 10000, 10000 );
    1138           0 :     if( ( labs( aWMFSize.Width() ) > 1 ) && ( labs( aWMFSize.Height() ) > 1 ) )
    1139             :     {
    1140           0 :         const Fraction  aFrac( 1, nUnitsPerInch );
    1141           0 :         MapMode         aWMFMap( MAP_INCH, Point(), aFrac, aFrac );
    1142           0 :         Size            aSize100( OutputDevice::LogicToLogic( aWMFSize, aWMFMap, MAP_100TH_MM ) );
    1143           0 :         aDevExt = Size( labs( aSize100.Width() ), labs( aSize100.Height() ) );
    1144             :     }
    1145           0 :     pOut->SetDevExt( aDevExt );
    1146             : 
    1147             :     // read the METAHEADER
    1148           0 :     sal_uInt32 nMetaKey(0);
    1149           0 :     pWMF->ReadUInt32( nMetaKey ); // type and headersize
    1150           0 :     if (!pWMF->good())
    1151           0 :         return false;
    1152           0 :     if (nMetaKey != 0x00090001)
    1153             :     {
    1154           0 :         sal_uInt16 aNextWord(0);
    1155           0 :         pWMF->ReadUInt16( aNextWord );
    1156           0 :         if (nMetaKey != 0x10000 || aNextWord != 0x09)
    1157             :         {
    1158           0 :             pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
    1159           0 :             return false;
    1160             :         }
    1161             :     }
    1162             : 
    1163           0 :     pWMF->SeekRel( 2 ); // Version (of Windows)
    1164           0 :     pWMF->SeekRel( 4 ); // Size (of file in words)
    1165           0 :     pWMF->SeekRel( 2 ); // NoObjects (maximum number of simultaneous objects)
    1166           0 :     pWMF->SeekRel( 4 ); // MaxRecord (size of largets record in words)
    1167           0 :     pWMF->SeekRel( 2 ); // NoParameters (Unused
    1168             : 
    1169           0 :     return pWMF->good();
    1170             : }
    1171             : 
    1172           0 : void WMFReader::ReadWMF()
    1173             : {
    1174             :     sal_uInt16  nFunction;
    1175             :     sal_uLong   nPos, nPercent, nLastPercent;
    1176             : 
    1177           0 :     nSkipActions = 0;
    1178           0 :     nCurrentAction = 0;
    1179           0 :     nUnicodeEscapeAction = 0;
    1180             : 
    1181           0 :     pEMFStream      = NULL;
    1182           0 :     nEMFRecCount    = 0;
    1183           0 :     nEMFRec         = 0;
    1184           0 :     nEMFSize        = 0;
    1185             : 
    1186           0 :     bool bEMFAvailable = false;
    1187             : 
    1188           0 :     pOut->SetMapMode( MM_ANISOTROPIC );
    1189           0 :     pOut->SetWinOrg( Point() );
    1190           0 :     pOut->SetWinExt( Size( 1, 1 ) );
    1191           0 :     pOut->SetDevExt( Size( 10000, 10000 ) );
    1192             : 
    1193           0 :     nEndPos=pWMF->Seek( STREAM_SEEK_TO_END );
    1194           0 :     pWMF->Seek( nStartPos );
    1195           0 :     Callback( (sal_uInt16) ( nLastPercent = 0 ) );
    1196             : 
    1197           0 :     if ( ReadHeader( ) )
    1198             :     {
    1199             : 
    1200           0 :         nPos = pWMF->Tell();
    1201             : 
    1202           0 :         if( nEndPos - nStartPos )
    1203             :         {
    1204             :             while( true )
    1205             :             {
    1206           0 :                 nCurrentAction++;
    1207           0 :                 nPercent = ( nPos - nStartPos ) * 100 / ( nEndPos - nStartPos );
    1208             : 
    1209           0 :                 if( nLastPercent + 4 <= nPercent )
    1210             :                 {
    1211           0 :                     Callback( (sal_uInt16) nPercent );
    1212           0 :                     nLastPercent = nPercent;
    1213             :                 }
    1214           0 :                 pWMF->ReadUInt32( nRecSize ).ReadUInt16( nFunction );
    1215             : 
    1216           0 :                 if(  pWMF->GetError()
    1217           0 :                   || ( nRecSize < 3 )
    1218           0 :                   || (  nRecSize  == 3
    1219           0 :                      && nFunction == 0
    1220             :                      )
    1221           0 :                   || pWMF->IsEof()
    1222             :                   )
    1223             :                 {
    1224           0 :                     if( pWMF->IsEof() )
    1225           0 :                         pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
    1226             : 
    1227           0 :                     break;
    1228             :                 }
    1229           0 :                 if ( !bEMFAvailable )
    1230             :                 {
    1231           0 :                     if(   !aBmpSaveList.empty()
    1232           0 :                       && ( nFunction != W_META_STRETCHDIB    )
    1233           0 :                       && ( nFunction != W_META_DIBBITBLT     )
    1234           0 :                       && ( nFunction != W_META_DIBSTRETCHBLT )
    1235             :                       )
    1236             :                     {
    1237           0 :                         pOut->ResolveBitmapActions( aBmpSaveList );
    1238             :                     }
    1239             : 
    1240           0 :                     if ( !nSkipActions )
    1241           0 :                         ReadRecordParams( nFunction );
    1242             :                     else
    1243           0 :                         nSkipActions--;
    1244             : 
    1245           0 :                     if( pEMFStream && nEMFRecCount == nEMFRec )
    1246             :                     {
    1247           0 :                         GDIMetaFile aMeta;
    1248           0 :                         pEMFStream->Seek( 0 );
    1249           0 :                         EnhWMFReader* pEMFReader = new EnhWMFReader ( *pEMFStream, aMeta );
    1250           0 :                         bEMFAvailable = pEMFReader->ReadEnhWMF();
    1251           0 :                         delete pEMFReader; // destroy first!!!
    1252             : 
    1253           0 :                         if( bEMFAvailable )
    1254             :                         {
    1255           0 :                             pOut->AddFromGDIMetaFile( aMeta );
    1256           0 :                             pOut->SetrclFrame( Rectangle( Point(0, 0), aMeta.GetPrefSize()));
    1257             : 
    1258             :                             // the stream needs to be set to the wmf end position,
    1259             :                             // otherwise the GfxLink that is created will be incorrect
    1260             :                             // (leading to graphic loss after swapout/swapin).
    1261             :                             // so we will proceed normally, but are ignoring further wmf
    1262             :                             // records
    1263             :                         }
    1264             :                         else
    1265             :                         {
    1266             :                             // something went wrong
    1267             :                             // continue with WMF, don't try this again
    1268           0 :                             delete pEMFStream;
    1269           0 :                             pEMFStream = NULL;
    1270           0 :                         }
    1271             :                     }
    1272             :                 }
    1273           0 :                 nPos += nRecSize * 2;
    1274           0 :                 if ( nPos <= nEndPos )
    1275           0 :                     pWMF->Seek( nPos  );
    1276             :                 else
    1277           0 :                     pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
    1278           0 :             }
    1279             :         }
    1280             :         else
    1281           0 :             pWMF->SetError( SVSTREAM_GENERALERROR );
    1282             : 
    1283           0 :         if( !pWMF->GetError() && !aBmpSaveList.empty() )
    1284           0 :             pOut->ResolveBitmapActions( aBmpSaveList );
    1285             :     }
    1286           0 :     if ( pWMF->GetError() )
    1287           0 :         pWMF->Seek( nStartPos );
    1288           0 : }
    1289             : 
    1290           0 : bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pStm )
    1291             : {
    1292           0 :     bool bRet = true;
    1293             : 
    1294           0 :     rPlaceableBound.Left()   = (sal_Int32)0x7fffffff;
    1295           0 :     rPlaceableBound.Top()    = (sal_Int32)0x7fffffff;
    1296           0 :     rPlaceableBound.Right()  = (sal_Int32)0x80000000;
    1297           0 :     rPlaceableBound.Bottom() = (sal_Int32)0x80000000;
    1298             : 
    1299           0 :     sal_uInt32 nPos = pStm->Tell();
    1300           0 :     sal_uInt32 nEnd = pStm->Seek( STREAM_SEEK_TO_END );
    1301             : 
    1302           0 :     pStm->Seek( nPos );
    1303             : 
    1304           0 :     if( nEnd - nPos )
    1305             :     {
    1306           0 :         sal_Int16 nMapMode = MM_ANISOTROPIC;
    1307             :         sal_uInt16 nFunction;
    1308             :         sal_uInt32 nRSize;
    1309             : 
    1310           0 :         while( bRet )
    1311             :         {
    1312           0 :             pStm->ReadUInt32( nRSize ).ReadUInt16( nFunction );
    1313             : 
    1314           0 :             if( pStm->GetError() || ( nRSize < 3 ) || ( nRSize==3 && nFunction==0 ) || pStm->IsEof() )
    1315             :             {
    1316           0 :                 if( pStm->IsEof() )
    1317             :                 {
    1318           0 :                     pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
    1319           0 :                     bRet = false;
    1320             :                 }
    1321           0 :                 break;
    1322             :             }
    1323           0 :             switch( nFunction )
    1324             :             {
    1325             :                 case W_META_SETWINDOWORG:
    1326             :                 {
    1327           0 :                     Point aWinOrg;
    1328           0 :                     aWinOrg = ReadYX();
    1329           0 :                     rPlaceableBound.SetPos( aWinOrg );
    1330             :                 }
    1331           0 :                 break;
    1332             : 
    1333             :                 case W_META_SETWINDOWEXT:
    1334             :                 {
    1335           0 :                     sal_Int16 nWidth(0), nHeight(0);
    1336           0 :                     pStm->ReadInt16( nHeight ).ReadInt16( nWidth );
    1337           0 :                     rPlaceableBound.SetSize( Size( nWidth, nHeight ) );
    1338             :                 }
    1339           0 :                 break;
    1340             : 
    1341             :                 case W_META_SETMAPMODE :
    1342           0 :                     pStm->ReadInt16( nMapMode );
    1343           0 :                 break;
    1344             : 
    1345             :                 case W_META_MOVETO:
    1346             :                 case W_META_LINETO:
    1347           0 :                     GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
    1348           0 :                 break;
    1349             : 
    1350             :                 case W_META_RECTANGLE:
    1351             :                 case W_META_INTERSECTCLIPRECT:
    1352             :                 case W_META_EXCLUDECLIPRECT :
    1353             :                 case W_META_ELLIPSE:
    1354           0 :                     GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
    1355           0 :                 break;
    1356             : 
    1357             :                 case W_META_ROUNDRECT:
    1358           0 :                     ReadYXExt(); // size
    1359           0 :                     GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
    1360           0 :                 break;
    1361             : 
    1362             :                 case W_META_ARC:
    1363             :                 case W_META_PIE:
    1364             :                 case W_META_CHORD:
    1365           0 :                     ReadYX(); // end
    1366           0 :                     ReadYX(); // start
    1367           0 :                     GetWinExtMax( ReadRectangle(), rPlaceableBound, nMapMode );
    1368           0 :                 break;
    1369             : 
    1370             :                 case W_META_POLYGON:
    1371             :                 {
    1372             :                     sal_uInt16 nPoints;
    1373           0 :                     pStm->ReadUInt16( nPoints );
    1374           0 :                     for(sal_uInt16 i = 0; i < nPoints; i++ )
    1375           0 :                         GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
    1376             :                 }
    1377           0 :                 break;
    1378             : 
    1379             :                 case W_META_POLYPOLYGON:
    1380             :                 {
    1381           0 :                     bool bRecordOk = true;
    1382           0 :                     sal_uInt16 nPoly, nPoints = 0;
    1383           0 :                     pStm->ReadUInt16( nPoly );
    1384           0 :                     for(sal_uInt16 i = 0; i < nPoly; i++ )
    1385             :                     {
    1386           0 :                         sal_uInt16 nP = 0;
    1387           0 :                         pStm->ReadUInt16( nP );
    1388           0 :                         if (nP > SAL_MAX_UINT16 - nPoints)
    1389             :                         {
    1390           0 :                             bRecordOk = false;
    1391           0 :                             break;
    1392             :                         }
    1393           0 :                         nPoints += nP;
    1394             :                     }
    1395             : 
    1396             :                     SAL_WARN_IF(!bRecordOk, "vcl.filter", "polypolygon record has more polygons than we can handle");
    1397             : 
    1398           0 :                     bRecordOk &= pStm->good();
    1399             : 
    1400           0 :                     if (!bRecordOk)
    1401             :                     {
    1402           0 :                         pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
    1403           0 :                         bRet = false;
    1404           0 :                         break;
    1405             :                     }
    1406             : 
    1407           0 :                     for (sal_uInt16 i = 0; i < nPoints; i++ )
    1408           0 :                         GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
    1409             : 
    1410           0 :                     bRecordOk &= pStm->good();
    1411             : 
    1412           0 :                     if (!bRecordOk)
    1413             :                     {
    1414           0 :                         pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
    1415           0 :                         bRet = false;
    1416           0 :                         break;
    1417             :                     }
    1418             :                 }
    1419           0 :                 break;
    1420             : 
    1421             :                 case W_META_POLYLINE:
    1422             :                 {
    1423             :                     sal_uInt16 nPoints;
    1424           0 :                     pStm->ReadUInt16( nPoints );
    1425           0 :                     for(sal_uInt16 i = 0; i < nPoints; i++ )
    1426           0 :                         GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode );
    1427             :                 }
    1428           0 :                 break;
    1429             : 
    1430             :                 case W_META_SETPIXEL:
    1431             :                 {
    1432           0 :                     ReadColor();
    1433           0 :                     GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
    1434             :                 }
    1435           0 :                 break;
    1436             : 
    1437             :                 case W_META_TEXTOUT:
    1438             :                 {
    1439             :                     sal_uInt16 nLength;
    1440           0 :                     pStm->ReadUInt16( nLength );
    1441             :                     // todo: we also have to take care of the text width
    1442           0 :                     if ( nLength )
    1443             :                     {
    1444           0 :                         pStm->SeekRel( ( nLength + 1 ) &~ 1 );
    1445           0 :                         GetWinExtMax( ReadYX(), rPlaceableBound, nMapMode );
    1446             :                     }
    1447             :                 }
    1448           0 :                 break;
    1449             : 
    1450             :                 case W_META_EXTTEXTOUT:
    1451             :                 {
    1452             :                     sal_uInt16  nLen, nOptions;
    1453           0 :                     Point       aPosition;
    1454             : 
    1455           0 :                     aPosition = ReadYX();
    1456           0 :                     pStm->ReadUInt16( nLen ).ReadUInt16( nOptions );
    1457             :                     // todo: we also have to take care of the text width
    1458           0 :                     if( nLen )
    1459           0 :                         GetWinExtMax( aPosition, rPlaceableBound, nMapMode );
    1460             :                 }
    1461           0 :                 break;
    1462             :                 case W_META_BITBLT:
    1463             :                 case W_META_STRETCHBLT:
    1464             :                 case W_META_DIBBITBLT:
    1465             :                 case W_META_DIBSTRETCHBLT:
    1466             :                 case W_META_STRETCHDIB:
    1467             :                 {
    1468             :                     sal_Int32   nWinROP;
    1469             :                     sal_uInt16  nSx, nSy, nSxe, nSye, nUsage;
    1470           0 :                     pStm->ReadInt32( nWinROP );
    1471             : 
    1472           0 :                     if( nFunction == W_META_STRETCHDIB )
    1473           0 :                         pStm->ReadUInt16( nUsage );
    1474             : 
    1475             :                     // nSye and nSxe is the number of pixels that has to been used
    1476           0 :                     if( nFunction == W_META_STRETCHDIB || nFunction == W_META_STRETCHBLT || nFunction == W_META_DIBSTRETCHBLT )
    1477           0 :                         pStm->ReadUInt16( nSye ).ReadUInt16( nSxe );
    1478             :                     else
    1479           0 :                         nSye = nSxe = 0;    // set this to zero as indicator not to scale the bitmap later
    1480             : 
    1481             :                     // nSy and nx is the offset of the first pixel
    1482           0 :                     pStm->ReadUInt16( nSy ).ReadUInt16( nSx );
    1483             : 
    1484           0 :                     if( nFunction == W_META_STRETCHDIB || nFunction == W_META_DIBBITBLT || nFunction == W_META_DIBSTRETCHBLT )
    1485             :                     {
    1486           0 :                         if ( nWinROP == PATCOPY )
    1487           0 :                             pStm->ReadUInt16( nUsage );    // i don't know anything of this parameter, so its called nUsage
    1488             :                                                 // pOut->DrawRect( Rectangle( ReadYX(), aDestSize ), false );
    1489             : 
    1490           0 :                         Size aDestSize( ReadYXExt() );
    1491           0 :                         if ( aDestSize.Width() && aDestSize.Height() )  // #92623# do not try to read buggy bitmaps
    1492             :                         {
    1493           0 :                             Rectangle aDestRect( ReadYX(), aDestSize );
    1494           0 :                             GetWinExtMax( aDestRect, rPlaceableBound, nMapMode );
    1495             :                         }
    1496             :                     }
    1497             :                 }
    1498           0 :                 break;
    1499             : 
    1500             :                 case W_META_PATBLT:
    1501             :                 {
    1502             :                     sal_uInt32 nROP;
    1503           0 :                     pStm->ReadUInt32( nROP );
    1504           0 :                     Size aSize = ReadYXExt();
    1505           0 :                     GetWinExtMax( Rectangle( ReadYX(), aSize ), rPlaceableBound, nMapMode );
    1506             :                 }
    1507           0 :                 break;
    1508             :             }
    1509           0 :             nPos += nRSize * 2;
    1510           0 :              if ( nPos <= nEnd )
    1511           0 :                  pStm->Seek( nPos );
    1512             :              else
    1513             :              {
    1514           0 :                  pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
    1515           0 :                  bRet = false;
    1516             :              }
    1517             : 
    1518             :         }
    1519             :     }
    1520             :     else
    1521             :     {
    1522           0 :         pStm->SetError( SVSTREAM_GENERALERROR );
    1523           0 :         bRet = false;
    1524             :     }
    1525           0 :     return bRet;
    1526             : }
    1527             : 
    1528           0 : WMFReader::~WMFReader()
    1529             : {
    1530           0 :     if( pEMFStream )
    1531           0 :         delete pEMFStream;
    1532           0 : }
    1533             : 
    1534             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10