diff options
Diffstat (limited to 'svtools/source/filter.vcl/wmf/enhwmf.cxx')
-rw-r--r-- | svtools/source/filter.vcl/wmf/enhwmf.cxx | 1533 |
1 files changed, 1533 insertions, 0 deletions
diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter.vcl/wmf/enhwmf.cxx new file mode 100644 index 000000000000..91cabcf430a3 --- /dev/null +++ b/svtools/source/filter.vcl/wmf/enhwmf.cxx @@ -0,0 +1,1533 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "winmtf.hxx" +#include <osl/endian.h> + +//=========================== GDI-Array =================================== + +#define EMR_HEADER 1 +#define EMR_POLYBEZIER 2 +#define EMR_POLYGON 3 +#define EMR_POLYLINE 4 +#define EMR_POLYBEZIERTO 5 +#define EMR_POLYLINETO 6 +#define EMR_POLYPOLYLINE 7 +#define EMR_POLYPOLYGON 8 +#define EMR_SETWINDOWEXTEX 9 +#define EMR_SETWINDOWORGEX 10 +#define EMR_SETVIEWPORTEXTEX 11 +#define EMR_SETVIEWPORTORGEX 12 +#define EMR_SETBRUSHORGEX 13 +#define EMR_EOF 14 +#define EMR_SETPIXELV 15 +#define EMR_SETMAPPERFLAGS 16 +#define EMR_SETMAPMODE 17 +#define EMR_SETBKMODE 18 +#define EMR_SETPOLYFILLMODE 19 +#define EMR_SETROP2 20 +#define EMR_SETSTRETCHBLTMODE 21 +#define EMR_SETTEXTALIGN 22 +#define EMR_SETCOLORADJUSTMENT 23 +#define EMR_SETTEXTCOLOR 24 +#define EMR_SETBKCOLOR 25 +#define EMR_OFFSETCLIPRGN 26 +#define EMR_MOVETOEX 27 +#define EMR_SETMETARGN 28 +#define EMR_EXCLUDECLIPRECT 29 +#define EMR_INTERSECTCLIPRECT 30 +#define EMR_SCALEVIEWPORTEXTEX 31 +#define EMR_SCALEWINDOWEXTEX 32 +#define EMR_SAVEDC 33 +#define EMR_RESTOREDC 34 +#define EMR_SETWORLDTRANSFORM 35 +#define EMR_MODIFYWORLDTRANSFORM 36 +#define EMR_SELECTOBJECT 37 +#define EMR_CREATEPEN 38 +#define EMR_CREATEBRUSHINDIRECT 39 +#define EMR_DELETEOBJECT 40 +#define EMR_ANGLEARC 41 +#define EMR_ELLIPSE 42 +#define EMR_RECTANGLE 43 +#define EMR_ROUNDRECT 44 +#define EMR_ARC 45 +#define EMR_CHORD 46 +#define EMR_PIE 47 +#define EMR_SELECTPALETTE 48 +#define EMR_CREATEPALETTE 49 +#define EMR_SETPALETTEENTRIES 50 +#define EMR_RESIZEPALETTE 51 +#define EMR_REALIZEPALETTE 52 +#define EMR_EXTFLOODFILL 53 +#define EMR_LINETO 54 +#define EMR_ARCTO 55 +#define EMR_POLYDRAW 56 +#define EMR_SETARCDIRECTION 57 +#define EMR_SETMITERLIMIT 58 +#define EMR_BEGINPATH 59 +#define EMR_ENDPATH 60 +#define EMR_CLOSEFIGURE 61 +#define EMR_FILLPATH 62 +#define EMR_STROKEANDFILLPATH 63 +#define EMR_STROKEPATH 64 +#define EMR_FLATTENPATH 65 +#define EMR_WIDENPATH 66 +#define EMR_SELECTCLIPPATH 67 +#define EMR_ABORTPATH 68 + +#define EMR_GDICOMMENT 70 +#define EMR_FILLRGN 71 +#define EMR_FRAMERGN 72 +#define EMR_INVERTRGN 73 +#define EMR_PAINTRGN 74 +#define EMR_EXTSELECTCLIPRGN 75 +#define EMR_BITBLT 76 +#define EMR_STRETCHBLT 77 +#define EMR_MASKBLT 78 +#define EMR_PLGBLT 79 +#define EMR_SETDIBITSTODEVICE 80 +#define EMR_STRETCHDIBITS 81 +#define EMR_EXTCREATEFONTINDIRECTW 82 +#define EMR_EXTTEXTOUTA 83 +#define EMR_EXTTEXTOUTW 84 +#define EMR_POLYBEZIER16 85 +#define EMR_POLYGON16 86 +#define EMR_POLYLINE16 87 +#define EMR_POLYBEZIERTO16 88 +#define EMR_POLYLINETO16 89 +#define EMR_POLYPOLYLINE16 90 +#define EMR_POLYPOLYGON16 91 +#define EMR_POLYDRAW16 92 +#define EMR_CREATEMONOBRUSH 93 +#define EMR_CREATEDIBPATTERNBRUSHPT 94 +#define EMR_EXTCREATEPEN 95 +#define EMR_POLYTEXTOUTA 96 +#define EMR_POLYTEXTOUTW 97 + +// WINDOWS VERSION >= 0x400 +#define EMR_SETICMMODE 98 +#define EMR_CREATECOLORSPACE 99 +#define EMR_SETCOLORSPACE 100 +#define EMR_DELETECOLORSPACE 101 +#define EMR_GLSRECORD 102 +#define EMR_GLSBOUNDEDRECORD 103 +#define EMR_PIXELFORMAT 104 + +// WINDOWS VERSION >= 0x500 +#define EMR_DRAWESCAPE 105 +#define EMR_EXTESCAPE 106 +#define EMR_STARTDOC 107 +#define EMR_SMALLTEXTOUT 108 +#define EMR_FORCEUFIMAPPING 109 +#define EMR_NAMEDESCAPE 110 +#define EMR_COLORCORRECTPALETTE 111 +#define EMR_SETICMPROFILEA 112 +#define EMR_SETICMPROFILEW 113 +#define EMR_ALPHABLEND 114 +#define EMR_ALPHADIBBLEND 115 +#define EMR_TRANSPARENTBLT 116 +#define EMR_TRANSPARENTDIB 117 +#define EMR_GRADIENTFILL 118 +#define EMR_SETLINKEDUFIS 119 +#define EMR_SETTEXTJUSTIFICATION 120 + +#define EMFP_DEBUG(x) +//#define EMFP_DEBUG(x) x + +//----------------------------------------------------------------------------------- + +#ifdef OSL_BIGENDIAN +// currently unused +static float GetSwapFloat( SvStream& rSt ) +{ + float fTmp; + sal_Int8* pPtr = (sal_Int8*)&fTmp; + rSt >> pPtr[3] >> pPtr[2] >> pPtr[1] >> pPtr[0]; // Little Endian <-> Big Endian switch + return fTmp; +} +#endif + +SvStream& operator>>( SvStream& rIn, XForm& rXForm ) +{ + if ( sizeof( float ) != 4 ) + { + OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" ); + rXForm = XForm(); + } + else + { +#ifdef OSL_BIGENDIAN + rXForm.eM11 = GetSwapFloat( rIn ); + rXForm.eM12 = GetSwapFloat( rIn ); + rXForm.eM21 = GetSwapFloat( rIn ); + rXForm.eM22 = GetSwapFloat( rIn ); + rXForm.eDx = GetSwapFloat( rIn ); + rXForm.eDy = GetSwapFloat( rIn ); +#else + rIn >> rXForm.eM11 >> rXForm.eM12 >> rXForm.eM21 >> rXForm.eM22 + >> rXForm.eDx >> rXForm.eDy; +#endif + } + return rIn; +} + +static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt32 nLen ) +{ + sal_Bool bOk = sal_False; + if ( nLen ) + { + sal_uInt32 nHdSize, nType, nCount, nRgnSize, i; + rSt >> nHdSize + >> nType + >> nCount + >> nRgnSize; + + if ( nCount && ( nType == RDH_RECTANGLES ) && + ( nLen >= ( ( nCount << 4 ) + ( nHdSize - 16 ) ) ) ) + { + sal_Int32 nx1, ny1, nx2, ny2; + + for ( i = 0; i < nCount; i++ ) + { + rSt >> nx1 >> ny1 >> nx2 >> ny2; + + Rectangle aRect( Point( nx1, ny1 ), Point( nx2, ny2 ) ); + Polygon aPolygon( aRect ); + PolyPolygon aPolyPolyOr1( aPolygon ); + PolyPolygon aPolyPolyOr2( rPolyPoly ); + rPolyPoly.GetUnion( aPolyPolyOr1, aPolyPolyOr2 ); + rPolyPoly = aPolyPolyOr2; + } + bOk = sal_True; + } + } + return bOk; +} + +EMFP_DEBUG(void dumpWords( SvStream& s, int i ) +{ + sal_uInt32 pos = s.Tell(); + INT16 data; + for( ; i > 0; i -- ) { + s >> data; + EMFP_DEBUG(printf ("\t\t\tdata: %04hx\n", data)); + } + s.Seek (pos); +}); + +void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC) +{ + if (!bEMFPlus) { + pOut->PassEMFPlusHeaderInfo(); + + // debug code - write the stream to debug file /tmp/emf-stream.emf + EMFP_DEBUG(int pos = pWMF->Tell(); + pWMF->Seek(0); + SvFileStream file( UniString::CreateFromAscii( "/tmp/emf-stream.emf" ), STREAM_WRITE | STREAM_TRUNC ); + + *pWMF >> file; + file.Flush(); + file.Close(); + + pWMF->Seek( pos );) + } + bEMFPlus = true; + + void *buffer = malloc( length ); + + int pos = pWMF->Tell(); + pOut->PassEMFPlus( buffer, pWMF->Read( buffer, length ) ); + pWMF->Seek( pos ); + + bHaveDC = false; + + length -= 4; + + while (length > 0) { + sal_uInt16 type, flags; + sal_uInt32 size, dataSize; + sal_uInt32 next; + + *pWMF >> type >> flags >> size >> dataSize; + + EMFP_DEBUG(printf ("\t\tEMF+ record type: %d\n", type)); + + // GetDC + if( type == 16388 ) { + bHaveDC = true; + EMFP_DEBUG(printf ("\t\tEMF+ lock DC (device context)\n", type)); + } + + next = pWMF->Tell() + ( size - 12 ); + + length -= size; + + pWMF->Seek( next ); + } + + free( buffer ); +} + +void EnhWMFReader::ReadGDIComment() +{ + sal_uInt32 type; + + *pWMF >> type; + + switch( type ) { + case 2: { + sal_Int32 x, y, r, b; + + EMFP_DEBUG(printf ("\t\tBEGINGROUP\n")); + + *pWMF >> x >> y >> r >> b; + EMFP_DEBUG(printf ("\t\tbounding rectangle: %d,%d x %d,%d\n", x, y, r, b)); + + sal_uInt32 l; + + *pWMF >> l; + EMFP_DEBUG(printf ("\t\tdescription length: %d\n", l)); + + break; + } + case 3: { + EMFP_DEBUG(printf ("\t\tENDGROUP\n")); + break; + } + case 0x40000004: { + EMFP_DEBUG(printf ("\t\tMULTIFORMATS\n")); + break; + } + default: + EMFP_DEBUG(printf ("\t\tunknown GDIComment\n")); + EMFP_DEBUG(dumpWords (*pWMF, 16)); + } +} + +sal_Bool EnhWMFReader::ReadEnhWMF() +{ + sal_uInt32 nStretchBltMode = 0; + sal_uInt32 nRecType, nRecSize, nNextPos, + nW, nH, nPoints, nColor, nIndex, + nDat32, nNom1, nDen1, nNom2, nDen2; + sal_Int32 nX32, nY32, nx32, ny32; + sal_Int16 nX16, nY16; + + sal_Bool bFlag, bStatus = ReadHeader(); + sal_Bool bHaveDC = false; + +#ifdef UNX + static sal_Bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == NULL ); +#else + // TODO: make it possible to disable emf+ on windows + static sal_Bool bEnableEMFPlus = sal_False; +#endif + + while( bStatus && nRecordCount-- ) + { + *pWMF >> nRecType >> nRecSize; + + if ( ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameter sind immer durch 4 teilbar + { + bStatus = sal_False; + break; + } + + nNextPos = pWMF->Tell() + ( nRecSize - 8 ); + + if ( nNextPos > nEndPos ) + { + bStatus = sal_False; + break; + } + + if( aBmpSaveList.Count() && ( nRecType != EMR_STRETCHBLT ) && ( nRecType != EMR_STRETCHDIBITS ) ) + pOut->ResolveBitmapActions( aBmpSaveList ); + + bFlag = sal_False; + + EMFP_DEBUG(printf ("0x%04x-0x%04x record type: %d size: %d\n", nNextPos - nRecSize, nNextPos, nRecType, nRecSize)); + + if( bEnableEMFPlus && nRecType == EMR_GDICOMMENT ) { + sal_uInt32 length; + + *pWMF >> length; + + EMFP_DEBUG(printf ("\tGDI comment\n\t\tlength: %d\n", length)); + + if( length >= 4 ) { + sal_uInt32 id; + + *pWMF >> id; + + EMFP_DEBUG(printf ("\t\tbegin %c%c%c%c id: 0x%x\n", (char)(id & 0xff), (char)((id & 0xff00) >> 8), (char)((id & 0xff0000) >> 16), (char)((id & 0xff000000) >> 24), id)); + + // EMF+ comment (fixme: BE?) + if( id == 0x2B464D45 && nRecSize >= 12 ) + ReadEMFPlusComment( length, bHaveDC ); + // GDIC comment, doesn't do anything useful yet => enabled only for debug + else if( id == 0x43494447 && nRecSize >= 12 ) { + EMFP_DEBUG(ReadGDIComment()); + } else { + EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n", id)); + } + } + } else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF ) + + switch( nRecType ) + { + case EMR_POLYBEZIERTO : + bFlag = sal_True; + case EMR_POLYBEZIER : + { + pWMF->SeekRel( 16 ); + *pWMF >> nPoints; + sal_uInt16 i = 0; + if ( bFlag ) + { + i++; + nPoints++; + } + Polygon aPoly( (sal_uInt16)nPoints ); + for( ; i < (sal_uInt16)nPoints; i++ ) + { + *pWMF >> nX32 >> nY32; + aPoly[ i ] = Point( nX32, nY32 ); + } + pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); + } + break; + + case EMR_POLYGON : + { + pWMF->SeekRel( 16 ); + *pWMF >> nPoints; + Polygon aPoly( (sal_uInt16)nPoints ); + for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) + { + *pWMF >> nX32 >> nY32; + aPoly[ k ] = Point( nX32, nY32 ); + } + pOut->DrawPolygon( aPoly, bRecordPath ); + } + break; + + case EMR_POLYLINETO : + bFlag = sal_True; + case EMR_POLYLINE : + { + pWMF->SeekRel( 0x10 ); + *pWMF >> nPoints; + sal_uInt16 i = 0; + if ( bFlag ) + { + i++; + nPoints++; + } + Polygon aPolygon( (sal_uInt16)nPoints ); + for ( ; i < (sal_uInt16)nPoints; i++ ) + { + *pWMF >> nX32 >> nY32; + aPolygon[ i ] = Point( nX32, nY32 ); + } + pOut->DrawPolyLine( aPolygon, bFlag, bRecordPath ); + } + break; + + case EMR_POLYPOLYLINE : + { + sal_uInt16* pnPoints; + + sal_Int32 i, nPoly; + pWMF->SeekRel( 0x10 ); + + // Anzahl der Polygone: + *pWMF >> nPoly >> i; + + // taking the amount of points of each polygon, retrieving the total number of points + if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) + { + if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) + { + pnPoints = new sal_uInt16[ nPoly ]; + + for ( i = 0; i < nPoly; i++ ) + { + *pWMF >> nPoints; + pnPoints[ i ] = (sal_uInt16)nPoints; + } + + // Polygonpunkte holen: + + for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) + { + Polygon aPoly( pnPoints[ i ] ); + for( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) + { + *pWMF >> nX32 >> nY32; + aPoly[ k ] = Point( nX32, nY32 ); + } + pOut->DrawPolyLine( aPoly, sal_False, bRecordPath ); + } + delete[] pnPoints; + } + } + } + break; + + case EMR_POLYPOLYGON : + { + sal_uInt16* pnPoints; + Point* pPtAry; + + sal_uInt32 i, nPoly, nGesPoints; + pWMF->SeekRel( 0x10 ); + + // Anzahl der Polygone: + *pWMF >> nPoly >> nGesPoints; + + if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) ) + { + if ( ( nPoly * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) + { + pnPoints = new sal_uInt16[ nPoly ]; + + for ( i = 0; i < nPoly; i++ ) + { + *pWMF >> nPoints; + pnPoints[ i ] = (sal_uInt16)nPoints; + } + + if ( ( nGesPoints * (sizeof(sal_uInt32)+sizeof(sal_uInt32)) ) <= ( nEndPos - pWMF->Tell() ) ) + { + // Polygonpunkte holen: + pPtAry = new Point[ nGesPoints ]; + + for ( i = 0; i < nGesPoints; i++ ) + { + *pWMF >> nX32 >> nY32; + pPtAry[ i ] = Point( nX32, nY32 ); + } + // PolyPolygon Actions erzeugen + PolyPolygon aPolyPoly( (sal_uInt16)nPoly, pnPoints, pPtAry ); + pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); + delete[] pPtAry; + } + delete[] pnPoints; + } + } + } + break; + + case EMR_SETWINDOWEXTEX : + { // #75383# + *pWMF >> nW >> nH; + pOut->SetWinExt( Size( nW, nH ) ); + } + break; + + case EMR_SETWINDOWORGEX : + { + *pWMF >> nX32 >> nY32; + pOut->SetWinOrg( Point( nX32, nY32 ) ); + } + break; + + case EMR_SCALEWINDOWEXTEX : + { + *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; + pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); + } + break; + + case EMR_SETVIEWPORTORGEX : + { + *pWMF >> nX32 >> nY32; + pOut->SetDevOrg( Point( nX32, nY32 ) ); + } + break; + + case EMR_SCALEVIEWPORTEXTEX : + { + *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2; + pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); + } + break; + + case EMR_SETVIEWPORTEXTEX : + { + *pWMF >> nW >> nH; + pOut->SetDevExt( Size( nW, nH ) ); + } + break; + + case EMR_EOF : + nRecordCount = 0; // #76846# + break; + + case EMR_SETPIXELV : + { + *pWMF >> nX32 >> nY32; + pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() ); + } + break; + + case EMR_SETMAPMODE : + { + sal_uInt32 nMapMode; + *pWMF >> nMapMode; + pOut->SetMapMode( nMapMode ); + } + break; + + case EMR_SETBKMODE : + { + *pWMF >> nDat32; + pOut->SetBkMode( nDat32 ); + } + break; + + case EMR_SETPOLYFILLMODE : + break; + + case EMR_SETROP2 : + { + *pWMF >> nDat32; + pOut->SetRasterOp( nDat32 ); + } + break; + + case EMR_SETSTRETCHBLTMODE : + { + *pWMF >> nStretchBltMode; + } + break; + + case EMR_SETTEXTALIGN : + { + *pWMF >> nDat32; + pOut->SetTextAlign( nDat32 ); + } + break; + + case EMR_SETTEXTCOLOR : + { + pOut->SetTextColor( ReadColor() ); + } + break; + + case EMR_SETBKCOLOR : + { + pOut->SetBkColor( ReadColor() ); + } + break; + + case EMR_OFFSETCLIPRGN : + { + *pWMF >> nX32 >> nY32; + pOut->MoveClipRegion( Size( nX32, nY32 ) ); + } + break; + + case EMR_MOVETOEX : + { + *pWMF >> nX32 >> nY32; + pOut->MoveTo( Point( nX32, nY32 ), bRecordPath ); + } + break; + + case EMR_INTERSECTCLIPRECT : + { + *pWMF >> nX32 >> nY32 >> nx32 >> ny32; + pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); + } + break; + + case EMR_SAVEDC : + { + pOut->Push(); + } + break; + + case EMR_RESTOREDC : + { + pOut->Pop(); + } + break; + + case EMR_SETWORLDTRANSFORM : + { + XForm aTempXForm; + *pWMF >> aTempXForm; + pOut->SetWorldTransform( aTempXForm ); + } + break; + + case EMR_MODIFYWORLDTRANSFORM : + { + sal_uInt32 nMode; + XForm aTempXForm; + *pWMF >> aTempXForm >> nMode; + pOut->ModifyWorldTransform( aTempXForm, nMode ); + } + break; + + case EMR_SELECTOBJECT : + { + *pWMF >> nIndex; + pOut->SelectObject( nIndex ); + } + break; + + case EMR_CREATEPEN : + { + *pWMF >> nIndex; + if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + { + + LineInfo aLineInfo; + sal_uInt32 nStyle; + Size aSize; + + *pWMF >> nStyle >> aSize.Width() >> aSize.Height(); + + if ( aSize.Width() ) + aLineInfo.SetWidth( aSize.Width() ); + + sal_Bool bTransparent = sal_False; + sal_uInt16 nDashCount = 0; + sal_uInt16 nDotCount = 0; + switch( nStyle ) + { + case PS_DASHDOTDOT : + nDotCount++; + case PS_DASHDOT : + nDashCount++; + case PS_DOT : + nDotCount++; + break; + case PS_DASH : + nDashCount++; + break; + case PS_NULL : + bTransparent = sal_True; + aLineInfo.SetStyle( LINE_NONE ); + break; + default : + case PS_INSIDEFRAME : + case PS_SOLID : + aLineInfo.SetStyle( LINE_SOLID ); + } + if ( nDashCount | nDotCount ) + { + aLineInfo.SetStyle( LINE_DASH ); + aLineInfo.SetDashCount( nDashCount ); + aLineInfo.SetDotCount( nDotCount ); + } + pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) ); + } + } + break; + + case EMR_EXTCREATEPEN : + { + sal_Int32 elpHatch; + sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; + Color aColorRef; + + *pWMF >> nIndex; + if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + { + *pWMF >> offBmi >> cbBmi >> offBits >> cbBits >> nStyle >> nWidth >> nBrushStyle; + aColorRef = ReadColor(); + *pWMF >> elpHatch >> elpNumEntries; + + LineInfo aLineInfo; + if ( nWidth ) + aLineInfo.SetWidth( nWidth ); + + sal_Bool bTransparent = sal_False; + sal_uInt16 nDashCount = 0; + sal_uInt16 nDotCount = 0; + + switch( nStyle & PS_STYLE_MASK ) + { + case PS_DASHDOTDOT : + nDotCount++; + case PS_DASHDOT : + nDashCount++; + case PS_DOT : + nDotCount++; + break; + case PS_DASH : + nDashCount++; + break; + case PS_NULL : + bTransparent = sal_True; + aLineInfo.SetStyle( LINE_NONE ); + break; + + default : + case PS_INSIDEFRAME : + case PS_SOLID : + aLineInfo.SetStyle( LINE_SOLID ); + } + if ( nDashCount | nDotCount ) + { + aLineInfo.SetStyle( LINE_DASH ); + aLineInfo.SetDashCount( nDashCount ); + aLineInfo.SetDotCount( nDotCount ); + } + pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( aColorRef, aLineInfo, bTransparent ) ); + } + } + break; + + case EMR_CREATEBRUSHINDIRECT : + { + sal_uInt32 nStyle; + *pWMF >> nIndex; + if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + { + *pWMF >> nStyle; + pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? sal_True : sal_False ) ); + } + } + break; + + case EMR_DELETEOBJECT : + { + *pWMF >> nIndex; + if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + pOut->DeleteObject( nIndex ); + } + break; + + case EMR_ELLIPSE : + { + *pWMF >> nX32 >> nY32 >> nx32 >> ny32; + pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) ); + } + break; + + case EMR_RECTANGLE : + { + *pWMF >> nX32 >> nY32 >> nx32 >> ny32; + pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); + } + break; + + case EMR_ROUNDRECT : + { + *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nW >> nH; + Size aSize( Size( nW, nH ) ); + pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize ); + } + break; + + case EMR_ARC : + { + sal_uInt32 nStartX, nStartY, nEndX, nEndY; + *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; + pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); + } + break; + + case EMR_CHORD : + { + sal_uInt32 nStartX, nStartY, nEndX, nEndY; + *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; + pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); + } + break; + + case EMR_PIE : + { + sal_uInt32 nStartX, nStartY, nEndX, nEndY; + *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; + const Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 )); + + // #i73608# OutputDevice deviates from WMF + // semantics. start==end means full ellipse here. + if( nStartX == nEndX && nStartY == nEndY ) + pOut->DrawEllipse( aRect ); + else + pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); + } + break; + + case EMR_LINETO : + { + *pWMF >> nX32 >> nY32; + pOut->LineTo( Point( nX32, nY32 ), bRecordPath ); + } + break; + + case EMR_ARCTO : + { + sal_uInt32 nStartX, nStartY, nEndX, nEndY; + *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY; + pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), sal_True ); + } + break; + + case EMR_BEGINPATH : + { + pOut->ClearPath(); + bRecordPath = sal_True; + } + break; + + case EMR_ABORTPATH : + pOut->ClearPath(); + case EMR_ENDPATH : + bRecordPath = sal_False; + break; + + case EMR_CLOSEFIGURE : + pOut->ClosePath(); + break; + + case EMR_FILLPATH : + pOut->StrokeAndFillPath( sal_False, sal_True ); + break; + + case EMR_STROKEANDFILLPATH : + pOut->StrokeAndFillPath( sal_True, sal_True ); + break; + + case EMR_STROKEPATH : + pOut->StrokeAndFillPath( sal_True, sal_False ); + break; + + case EMR_SELECTCLIPPATH : + { + sal_Int32 nClippingMode; + *pWMF >> nClippingMode; + pOut->SetClipPath( pOut->GetPathObj(), nClippingMode, sal_True ); + } + break; + + case EMR_EXTSELECTCLIPRGN : + { + sal_Int32 iMode, cbRgnData; + *pWMF >> cbRgnData + >> iMode; + + PolyPolygon aPolyPoly; + if ( cbRgnData ) + ImplReadRegion( aPolyPoly, *pWMF, nRecSize ); + pOut->SetClipPath( aPolyPoly, iMode, sal_False ); + } + break; + + case EMR_BITBLT : // PASSTHROUGH INTENDED + case EMR_STRETCHBLT : + { + sal_Int32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc; + sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc; + XForm xformSrc; + + sal_uInt32 nStart = pWMF->Tell() - 8; + + pWMF->SeekRel( 0x10 ); + *pWMF >> xDest >> yDest >> cxDest >> cyDest >> dwRop >> xSrc >> ySrc + >> xformSrc >> nColor >> iUsageSrc >> offBmiSrc >> cbBmiSrc + >> offBitsSrc >> cbBitsSrc; + + if ( nRecType == EMR_STRETCHBLT ) + *pWMF >> cxSrc >> cySrc; + else + cxSrc = cySrc = 0; + + Bitmap aBitmap; + Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); + + cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative + cyDest = abs( (int)cyDest ); // and also 122889 + + if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) + bStatus = sal_False; + else + { + sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; + if ( nSize <= ( nEndPos - nStartPos ) ) + { + char* pBuf = new char[ nSize ]; + SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); + aTmp.ObjectOwnsMemory( sal_True ); + aTmp << (sal_uInt8)'B' + << (sal_uInt8)'M' + << (sal_uInt32)cbBitsSrc + << (sal_uInt16)0 + << (sal_uInt16)0 + << (sal_uInt32)cbBmiSrc + 14; + pWMF->Seek( nStart + offBmiSrc ); + pWMF->Read( pBuf + 14, cbBmiSrc ); + pWMF->Seek( nStart + offBitsSrc ); + pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); + aTmp.Seek( 0 ); + aBitmap.Read( aTmp, sal_True ); + + // test if it is sensible to crop + if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && + ( xSrc >= 0 ) && ( ySrc >= 0 ) && + ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && + ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) + { + Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); + aBitmap.Crop( aCropRect ); + } + /* Pseudocomment to add more context so that make patch.unapply + * works better. Ha! + */ + aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND ); + } + } + } + break; + + case EMR_STRETCHDIBITS : + { + sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest; + sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop; + sal_uInt32 nStart = pWMF->Tell() - 8; + + pWMF->SeekRel( 0x10 ); + *pWMF >> xDest >> yDest >> xSrc >> ySrc >> cxSrc >> cySrc >> offBmiSrc >> cbBmiSrc >> offBitsSrc + >> cbBitsSrc >> iUsageSrc >> dwRop >> cxDest >> cyDest; + + Bitmap aBitmap; + Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); + + cxDest = abs( (int)cxDest ); // sj: i37894, size can be negative + cyDest = abs( (int)cyDest ); // and also 122889 + + if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) + bStatus = sal_False; + else + { + sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; + if ( nSize <= ( nEndPos - nStartPos ) ) + { + char* pBuf = new char[ nSize ]; + SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); + aTmp.ObjectOwnsMemory( sal_True ); + aTmp << (sal_uInt8)'B' + << (sal_uInt8)'M' + << (sal_uInt32)cbBitsSrc + << (sal_uInt16)0 + << (sal_uInt16)0 + << (sal_uInt32)cbBmiSrc + 14; + pWMF->Seek( nStart + offBmiSrc ); + pWMF->Read( pBuf + 14, cbBmiSrc ); + pWMF->Seek( nStart + offBitsSrc ); + pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc ); + aTmp.Seek( 0 ); + aBitmap.Read( aTmp, sal_True ); + + // test if it is sensible to crop + if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && + ( xSrc >= 0 ) && ( ySrc >= 0 ) && + ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && + ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) + { + Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); + aBitmap.Crop( aCropRect ); + } + /* Another pseudocomment to make make patch.unapply work better */ + aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND ); + } + } + } + break; + + case EMR_EXTCREATEFONTINDIRECTW : + { + *pWMF >> nIndex; + if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + { + LOGFONTW aLogFont; + *pWMF >> aLogFont.lfHeight >> aLogFont.lfWidth >> aLogFont.lfEscapement >> aLogFont.lfOrientation >> aLogFont.lfWeight >> aLogFont.lfItalic + >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision >> aLogFont.lfClipPrecision + >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily; + + sal_Unicode lfFaceName[ LF_FACESIZE ]; + + for ( int i = 0; i < LF_FACESIZE; i++ ) + { + sal_uInt16 nChar; + *pWMF >> nChar; + lfFaceName[ i ] = nChar; + } + aLogFont.alfFaceName = UniString( lfFaceName ); + pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) ); + } + } + break; + + case EMR_EXTTEXTOUTA : + bFlag = sal_True; + case EMR_EXTTEXTOUTW : + { + sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale; + sal_uInt32 nCurPos, nLen, nOffString, nOptions, offDx; + sal_Int32* pDX = NULL; + + nCurPos = pWMF->Tell() - 8; + + *pWMF >> nLeft >> nTop >> nRight >> nBottom >> nGfxMode >> nXScale >> nYScale + >> ptlReferenceX >> ptlReferenceY >> nLen >> nOffString >> nOptions; + + pWMF->SeekRel( 0x10 ); + *pWMF >> offDx; + + sal_Int32 nTextLayoutMode = TEXT_LAYOUT_DEFAULT; + if ( nOptions & ETO_RTLREADING ) + nTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT; + pOut->SetTextLayoutMode( nTextLayoutMode ); + DBG_ASSERT( ( nOptions & ( ETO_PDY | ETO_GLYPH_INDEX ) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" ); + + Point aPos( ptlReferenceX, ptlReferenceY ); + if ( nLen && ( nLen < SAL_MAX_UINT32 / sizeof(sal_Int32) ) ) + { + if ( offDx && (( nCurPos + offDx + nLen * 4 ) <= nNextPos ) ) + { + pWMF->Seek( nCurPos + offDx ); + if ( ( nLen * sizeof(sal_uInt32) ) <= ( nEndPos - pWMF->Tell() ) ) + { + pDX = new sal_Int32[ nLen ]; + sal_uInt32 i; + for ( i = 0; i < nLen; i++ ) + *pWMF >> pDX[ i ]; + } + } + pWMF->Seek( nCurPos + nOffString ); + String aText; + if ( bFlag ) + { + if ( nLen <= ( nEndPos - pWMF->Tell() ) ) + { + sal_Char* pBuf = new sal_Char[ nLen ]; + pWMF->Read( pBuf, nLen ); + aText = String( pBuf, (sal_uInt16)nLen, pOut->GetCharSet() ); + delete[] pBuf; + + if ( aText.Len() != nLen ) + { + sal_uInt16 i, j, k; + sal_Int32* pOldDx = pDX; + pDX = new sal_Int32[ aText.Len() ]; + for ( i = 0, j = 0; i < aText.Len(); i++ ) + { + ByteString aCharacter( aText.GetChar( i ), pOut->GetCharSet() ); + pDX[ i ] = 0; + for ( k = 0; ( k < aCharacter.Len() ) && ( j < nLen ) && ( i < aText.Len() ); k++ ) + pDX[ i ] += pOldDx[ j++ ]; + } + delete[] pOldDx; + } + } + } + else + { + if ( ( nLen * sizeof(sal_Unicode) ) <= ( nEndPos - pWMF->Tell() ) ) + { + sal_Unicode* pBuf = new sal_Unicode[ nLen ]; + pWMF->Read( pBuf, nLen << 1 ); +#ifdef OSL_BIGENDIAN + sal_Char nTmp, *pTmp = (sal_Char*)( pBuf + nLen ); + while ( pTmp-- != (sal_Char*)pBuf ) + { + nTmp = *pTmp--; + pTmp[ 1 ] = *pTmp; + *pTmp = nTmp; + } +#endif + aText = String( pBuf, (xub_StrLen)nLen ); + delete[] pBuf; + } + } + pOut->DrawText( aPos, aText, pDX, bRecordPath, nGfxMode ); + } + delete[] pDX; + } + break; + + case EMR_POLYBEZIERTO16 : + bFlag = sal_True; + case EMR_POLYBEZIER16 : + { + pWMF->SeekRel( 16 ); + *pWMF >> nPoints; + sal_uInt16 i = 0; + if ( bFlag ) + { + i++; + nPoints++; + } + Polygon aPoly( (sal_uInt16)nPoints ); + for( ; i < (sal_uInt16)nPoints; i++ ) + { + *pWMF >> nX16 >> nY16; + aPoly[ i ] = Point( nX16, nY16 ); + } + pOut->DrawPolyBezier( aPoly, bFlag, bRecordPath ); // Line( aPoly, bFlag ); + } + break; + + case EMR_POLYGON16 : + { + pWMF->SeekRel( 16 ); + *pWMF >> nPoints; + Polygon aPoly( (sal_uInt16)nPoints ); + for( sal_uInt16 k = 0; k < (sal_uInt16)nPoints; k++ ) + { + *pWMF >> nX16 >> nY16; + aPoly[ k ] = Point( nX16, nY16 ); + } + pOut->DrawPolygon( aPoly, bRecordPath ); + } + break; + + case EMR_POLYLINETO16 : + bFlag = sal_True; + case EMR_POLYLINE16 : + { + pWMF->SeekRel( 16 ); + *pWMF >> nPoints; + sal_uInt16 i = 0; + if ( bFlag ) + { + i++; + nPoints++; + } + + Polygon aPoly( (sal_uInt16)nPoints ); + for( ; i < (sal_uInt16)nPoints; i++ ) + { + *pWMF >> nX16 >> nY16; + aPoly[ i ] = Point( nX16, nY16 ); + } + pOut->DrawPolyLine( aPoly, bFlag, bRecordPath ); + } + break; + + case EMR_POLYPOLYLINE16 : + { + sal_uInt16* pnPoints; + + sal_Int32 i, nPoly, nGesPoints; + pWMF->SeekRel( 0x10 ); + // Anzahl der Polygone: + *pWMF >> nPoly >> nGesPoints; + + // taking the amount of points of each polygon, retrieving the total number of points + if ( static_cast< sal_uInt32 >(nPoly) < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) + { + if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) ) + { + pnPoints = new sal_uInt16[ nPoly ]; + for ( i = 0; i < nPoly; i++ ) + { + *pWMF >> nPoints; + pnPoints[ i ] = (sal_uInt16)nPoints; + } + // Polygonpunkte holen: + for ( i = 0; ( i < nPoly ) && !pWMF->IsEof(); i++ ) + { + Polygon aPolygon( pnPoints[ i ] ); + for ( sal_uInt16 k = 0; k < pnPoints[ i ]; k++ ) + { + *pWMF >> nX16 >> nY16; + aPolygon[ k ] = Point( nX16, nY16 ); + } + pOut->DrawPolyLine( aPolygon, sal_False, bRecordPath ); + } + delete[] pnPoints; + } + } + } + break; + + case EMR_POLYPOLYGON16 : + { + sal_uInt16* pnPoints; + Point* pPtAry; + + sal_uInt32 i, nPoly, nGesPoints; + pWMF->SeekRel( 0x10 ); + // Anzahl der Polygone: + *pWMF >> nPoly >> nGesPoints; + if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) ) + { + if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() ) ) + { + pnPoints = new sal_uInt16[ nPoly ]; + for ( i = 0; i < nPoly; i++ ) + { + *pWMF >> nPoints; + pnPoints[ i ] = (sal_uInt16)nPoints; + } + if ( ( nGesPoints * (sizeof(sal_uInt16)+sizeof(sal_uInt16)) ) <= ( nEndPos - pWMF->Tell() ) ) + { + // Polygonpunkte holen: + pPtAry = new Point[ nGesPoints ]; + for ( i = 0; i < nGesPoints; i++ ) + { + *pWMF >> nX16 >> nY16; + pPtAry[ i ] = Point( nX16, nY16 ); + } + + // PolyPolygon Actions erzeugen + PolyPolygon aPolyPoly( (sal_uInt16)nPoly, pnPoints, pPtAry ); + pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); + delete[] pPtAry; + } + delete[] pnPoints; + } + } + } + break; + + case EMR_FILLRGN : + { + sal_uInt32 nLen; + PolyPolygon aPolyPoly; + pWMF->SeekRel( 0x10 ); + *pWMF >> nLen >> nIndex; + + if ( ImplReadRegion( aPolyPoly, *pWMF, nRecSize ) ) + { + pOut->Push(); + pOut->SelectObject( nIndex ); + pOut->DrawPolyPolygon( aPolyPoly, sal_False ); + pOut->Pop(); + } + } + break; + + case EMR_CREATEDIBPATTERNBRUSHPT : + { + sal_uInt32 nStart = pWMF->Tell() - 8; + Bitmap aBitmap; + + *pWMF >> nIndex; + + if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + { + sal_uInt32 usage, offBmi, cbBmi, offBits, cbBits; + + *pWMF >> usage; + *pWMF >> offBmi; + *pWMF >> cbBmi; + *pWMF >> offBits; + *pWMF >> cbBits; + + if ( (cbBits > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBits < cbBmi) ) + bStatus = sal_False; + else if ( offBmi ) + { + sal_uInt32 nSize = cbBmi + cbBits + 14; + if ( nSize <= ( nEndPos - nStartPos ) ) + { + char* pBuf = new char[ nSize ]; + + SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE ); + aTmp.ObjectOwnsMemory( sal_True ); + aTmp << (sal_uInt8)'B' + << (sal_uInt8)'M' + << (sal_uInt32)cbBits + << (sal_uInt16)0 + << (sal_uInt16)0 + << (sal_uInt32)cbBmi + 14; + pWMF->Seek( nStart + offBmi ); + pWMF->Read( pBuf + 14, cbBmi ); + pWMF->Seek( nStart + offBits ); + pWMF->Read( pBuf + 14 + cbBmi, cbBits ); + aTmp.Seek( 0 ); + aBitmap.Read( aTmp, sal_True ); + } + } + } + + pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aBitmap ) ); + } + break; + +#ifdef WIN_MTF_ASSERT + default : WinMtfAssertHandler( "Unknown Meta Action" ); break; + case EMR_MASKBLT : WinMtfAssertHandler( "MaskBlt" ); break; + case EMR_PLGBLT : WinMtfAssertHandler( "PlgBlt" ); break; + case EMR_SETDIBITSTODEVICE : WinMtfAssertHandler( "SetDIBitsToDevice" ); break; + case EMR_FRAMERGN : WinMtfAssertHandler( "FrameRgn" ); break; + case EMR_INVERTRGN : WinMtfAssertHandler( "InvertRgn" ); break; + case EMR_PAINTRGN : WinMtfAssertHandler( "PaintRgn" ); break; + case EMR_FLATTENPATH : WinMtfAssertHandler( "FlattenPath" ); break; + case EMR_WIDENPATH : WinMtfAssertHandler( "WidenPath" ); break; + case EMR_POLYDRAW : WinMtfAssertHandler( "Polydraw" ); break; + case EMR_SETARCDIRECTION : WinMtfAssertHandler( "SetArcDirection" ); break; + case EMR_SETPALETTEENTRIES : WinMtfAssertHandler( "SetPaletteEntries" ); break; + case EMR_RESIZEPALETTE : WinMtfAssertHandler( "ResizePalette" ); break; + case EMR_EXTFLOODFILL : WinMtfAssertHandler( "ExtFloodFill" ); break; + case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break; + case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break; + case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break; + case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break; + case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break; + case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break; + case EMR_SETCOLORSPACE : WinMtfAssertHandler( "SetColorSpace" ); break; + case EMR_DELETECOLORSPACE : WinMtfAssertHandler( "DeleteColorSpace" ); break; + case EMR_GLSRECORD : WinMtfAssertHandler( "GlsRecord" ); break; + case EMR_GLSBOUNDEDRECORD : WinMtfAssertHandler( "GlsBoundRecord" ); break; + case EMR_PIXELFORMAT : WinMtfAssertHandler( "PixelFormat" ); break; + case EMR_DRAWESCAPE : WinMtfAssertHandler( "DrawEscape" ); break; + case EMR_EXTESCAPE : WinMtfAssertHandler( "ExtEscape" ); break; + case EMR_STARTDOC : WinMtfAssertHandler( "StartDoc" ); break; + case EMR_SMALLTEXTOUT : WinMtfAssertHandler( "SmallTextOut" ); break; + case EMR_FORCEUFIMAPPING : WinMtfAssertHandler( "ForceUFIMapping" ); break; + case EMR_NAMEDESCAPE : WinMtfAssertHandler( "NamedEscape" ); break; + case EMR_COLORCORRECTPALETTE : WinMtfAssertHandler( "ColorCorrectPalette" ); break; + case EMR_SETICMPROFILEA : WinMtfAssertHandler( "SetICMProfileA" ); break; + case EMR_SETICMPROFILEW : WinMtfAssertHandler( "SetICMProfileW" ); break; + case EMR_ALPHABLEND : WinMtfAssertHandler( "Alphablend" ); break; + case EMR_TRANSPARENTBLT : WinMtfAssertHandler( "TransparenBlt" ); break; + case EMR_TRANSPARENTDIB : WinMtfAssertHandler( "TransparenDib" ); break; + case EMR_GRADIENTFILL : WinMtfAssertHandler( "GradientFill" ); break; + case EMR_SETLINKEDUFIS : WinMtfAssertHandler( "SetLinkedUFIS" ); break; + + case EMR_SETMAPPERFLAGS : WinMtfAssertHandler( "SetMapperFlags", 0 ); break; + case EMR_SETICMMODE : WinMtfAssertHandler( "SetICMMode", 0 ); break; + case EMR_CREATEMONOBRUSH : WinMtfAssertHandler( "CreateMonoBrush", 0 ); break; + case EMR_SETBRUSHORGEX : WinMtfAssertHandler( "SetBrushOrgEx", 0 ); break; + case EMR_SETMETARGN : WinMtfAssertHandler( "SetMetArgn", 0 ); break; + case EMR_SETMITERLIMIT : WinMtfAssertHandler( "SetMiterLimit", 0 ); break; + case EMR_EXCLUDECLIPRECT : WinMtfAssertHandler( "ExcludeClipRect", 0 ); break; + case EMR_REALIZEPALETTE : WinMtfAssertHandler( "RealizePalette", 0 ); break; + case EMR_SELECTPALETTE : WinMtfAssertHandler( "SelectPalette", 0 ); break; + case EMR_CREATEPALETTE : WinMtfAssertHandler( "CreatePalette", 0 ); break; + case EMR_ALPHADIBBLEND : WinMtfAssertHandler( "AlphaDibBlend", 0 ); break; + case EMR_SETTEXTJUSTIFICATION : WinMtfAssertHandler( "SetTextJustification", 0 ); break; + + case EMR_GDICOMMENT : + case EMR_HEADER : // has already been read at ReadHeader() + break; +#endif + } + pWMF->Seek( nNextPos ); + } + if( aBmpSaveList.Count() ) + pOut->ResolveBitmapActions( aBmpSaveList ); + + if ( bStatus ) + pWMF->Seek(nEndPos); + + return bStatus; +}; + +//----------------------------------------------------------------------------------- + +sal_Bool EnhWMFReader::ReadHeader() +{ + sal_uInt32 nsal_uInt32, nHeaderSize, nPalEntries; + sal_Int32 nLeft, nTop, nRight, nBottom; + + // METAFILEHEADER SPARE ICH MIR HIER + // Einlesen des METAHEADER + *pWMF >> nsal_uInt32 >> nHeaderSize; + if ( nsal_uInt32 != 1 ) // Typ + return sal_False; + + // bound size + Rectangle rclBounds; // rectangle in logical units 1/100th mm + *pWMF >> nLeft >> nTop >> nRight >> nBottom; + rclBounds.Left() = nLeft; + rclBounds.Top() = nTop; + rclBounds.Right() = nRight; + rclBounds.Bottom() = nBottom; + + // picture frame size + Rectangle rclFrame; // rectangle in device units + *pWMF >> nLeft >> nTop >> nRight >> nBottom; + rclFrame.Left() = nLeft; + rclFrame.Top() = nTop; + rclFrame.Right() = nRight; + rclFrame.Bottom() = nBottom; + + *pWMF >> nsal_uInt32; // signature + + if ( nsal_uInt32 != 0x464d4520 ) + return sal_False; + + *pWMF >> nsal_uInt32; // nVersion + *pWMF >> nEndPos; // size of metafile + nEndPos += nStartPos; + + sal_uInt32 nStrmPos = pWMF->Tell(); // checking if nEndPos is valid + pWMF->Seek( STREAM_SEEK_TO_END ); + if ( pWMF->Tell() < nEndPos ) + nEndPos = pWMF->Tell(); + pWMF->Seek( nStrmPos ); + + *pWMF >> nRecordCount; + + if ( !nRecordCount ) + return sal_False; + + pWMF->SeekRel( 0xc ); + + sal_Int32 nPixX, nPixY, nMillX, nMillY; + *pWMF >> nPalEntries >> nPixX >> nPixY >> nMillX >> nMillY; + + pOut->SetrclFrame( rclFrame ); + pOut->SetrclBounds( rclBounds ); + pOut->SetRefPix( Size( nPixX, nPixY ) ); + pOut->SetRefMill( Size( nMillX, nMillY ) ); + + pWMF->Seek( nStartPos + nHeaderSize ); + return sal_True; +} + +//----------------------------------------------------------------------------------- + +Rectangle EnhWMFReader::ReadRectangle( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) +{ + Point aTL ( Point( x1, y1 ) ); + Point aBR( Point( --x2, --y2 ) ); + return Rectangle( aTL, aBR ); +} + +EnhWMFReader::~EnhWMFReader() +{ + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |