blob: 135ce1d8de4308d3ecc7abfcb5ca9a36e7831459 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include "winmtf.hxx"
#include <osl/endian.h>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <vcl/dibtools.hxx>
//=========================== 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
//-----------------------------------------------------------------------------------
#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
struct BLENDFUNCTION{
unsigned char aBlendOperation;
unsigned char aBlendFlags;
unsigned char aSrcConstantAlpha;
unsigned char aAlphaFormat;
friend SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun );
};
SvStream& operator>>( SvStream& rIn, BLENDFUNCTION& rBlendFun )
{
rIn >> rBlendFun.aBlendOperation >> rBlendFun.aBlendFlags >>
rBlendFun.aSrcConstantAlpha >> rBlendFun.aAlphaFormat;
return rIn;
}
SvStream& operator>>( SvStream& rIn, XForm& rXForm )
{
if ( sizeof( float ) != 4 )
{
DBG_ERROR( "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;
}
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();
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;
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_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() ) )
{
sal_uInt16* pnPoints = new sal_uInt16[ nPoly ];
for ( i = 0; i < nPoly && !pWMF->IsEof(); 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_uInt32 nPoly(0);
sal_uInt32 nGesPoints(0);
sal_uInt32 nReadPoints(0);
pWMF->SeekRel( 0x10 );
// Anzahl der Polygone:
*pWMF >> nPoly >> nGesPoints;
if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() )
{
if ( ( nPoly * sizeof(sal_uInt16) ) <= ( nEndPos - pWMF->Tell() ) )
{
sal_uInt32 i(0);
sal_uInt16* pnPoints = new sal_uInt16[ nPoly ];
for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ )
{
*pWMF >> nPoints;
pnPoints[ i ] = (sal_uInt16)nPoints;
}
if ( ( nGesPoints * (sizeof(sal_uInt32)+sizeof(sal_uInt32)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof())
{
PolyPolygon aPolyPoly(nPoly, nPoly);
for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ )
{
const sal_uInt16 nPointCount(pnPoints[i]);
Point* pPtAry = new Point[nPointCount];
for(sal_uInt16 j(0); j < nPointCount && !pWMF->IsEof(); j++)
{
*pWMF >> nX32 >> nY32;
pPtAry[ j ] = Point( nX32, nY32 );
nReadPoints++;
}
aPolyPoly.Insert(Polygon(nPointCount, pPtAry));
delete[] pPtAry;
}
pOut->DrawPolyPolygon( aPolyPoly, bRecordPath );
}
delete[] pnPoints;
}
}
OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)");
}
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_ALPHABLEND:
{
sal_Int32 xDest, yDest, cxDest, cyDest;
BLENDFUNCTION aFunc;
sal_Int32 xSrc, ySrc;
XForm xformSrc;
sal_uInt32 BkColorSrc,iUsageSrc ,offBmiSrc,cbBmiSrc,offBitsSrc,cbBitsSrc ,cxSrc,cySrc ;
sal_uInt32 nStart = pWMF->Tell() - 8;
pWMF->SeekRel( 0x10 );
*pWMF >> xDest >> yDest >> cxDest >> cyDest >> aFunc >> xSrc >> ySrc
>> xformSrc >> BkColorSrc >> iUsageSrc >> offBmiSrc >> cbBmiSrc
>> offBitsSrc >> cbBitsSrc >>cxSrc>>cySrc ;
sal_uInt32 dwRop = SRCAND|SRCINVERT;
Bitmap aBitmap;
Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
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 );
ReadDIB(aBitmap, aTmp, true);
// test if it is sensible to crop
if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
( xSrc >= 0 ) && ( ySrc >= 0 ) &&
( xSrc + static_cast< sal_Int32 >(cxSrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Width()) ) &&
( ySrc + static_cast< sal_Int32 >(cySrc) <= static_cast< sal_Int32 >(aBitmap.GetSizePixel().Height()) ) )
{
Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
aBitmap.Crop( aCropRect );
}
aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
}
}
}
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 );
ReadDIB(aBitmap, aTmp, 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 );
}
aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), 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 );
ReadDIB(aBitmap, aTmp, 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 );
}
aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), 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 );
// #123216# Not used in the test case of #121382# (always identity in XForm), also
// no hints in ms docu if FontSize should be scaled with WT. Using with the example
// from #123216# creates errors, so removing.
//
// // #121382# Need to apply WorldTransform to FontHeight/Width; this should be completely
// // chnaged to basegfx::B2DHomMatrix instead of 'struct XForm', but not now due to time
// // constraints and dangers
// const XForm& rXF = pOut->GetWorldTransform();
// const basegfx::B2DHomMatrix aWT(rXF.eM11, rXF.eM21, rXF.eDx, rXF.eM12, rXF.eM22, rXF.eDy);
// const basegfx::B2DVector aTransVec(aWT * basegfx::B2DVector(aLogFont.lfWidth, aLogFont.lfHeight));
// aLogFont.lfWidth = aTransVec.getX();
// aLogFont.lfHeight = aTransVec.getY();
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_uInt32 nPoly(0);
sal_uInt32 nGesPoints(0);
pWMF->SeekRel( 0x10 );
// Anzahl der Polygone:
*pWMF >> nPoly >> nGesPoints;
sal_uInt32 nReadPoints(0);
if ( ( nGesPoints < SAL_MAX_UINT32 / sizeof(Point) ) && ( nPoly < SAL_MAX_UINT32 / sizeof(sal_uInt16) ) && !pWMF->IsEof() )
{
if ( ( static_cast< sal_uInt32 >( nPoly ) * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() ) )
{
sal_uInt32 i(0);
sal_uInt16* pnPoints = new sal_uInt16[ nPoly ];
for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ )
{
*pWMF >> nPoints;
pnPoints[ i ] = (sal_uInt16)nPoints;
}
if ( ( nGesPoints * (sizeof(sal_uInt16)+sizeof(sal_uInt16)) ) <= ( nEndPos - pWMF->Tell() ) && !pWMF->IsEof() )
{
PolyPolygon aPolyPoly(nPoly, nPoly);
for ( i = 0; i < nPoly && !pWMF->IsEof(); i++ )
{
const sal_uInt16 nPointCount(pnPoints[i]);
Point* pPtAry = new Point[nPointCount];
for(sal_uInt16 b(0); b < nPointCount && !pWMF->IsEof(); b++)
{
*pWMF >> nX16 >> nY16;
pPtAry[b] = Point( nX16, nY16 );
nReadPoints++;
}
aPolyPoly.Insert(Polygon(nPointCount, pPtAry));
delete[] pPtAry;
}
// create PolyPolygon actions
pOut->DrawPolyPolygon( aPolyPoly, bRecordPath );
}
delete[] pnPoints;
}
}
OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON16 is unequal imported number (!)");
}
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 nTmp32;
sal_uInt32 nOffset;
*pWMF >> nIndex;
Bitmap aBmp;
BitmapReadAccess* pBmp;
sal_uInt32 nRed = 0, nGreen = 0, nBlue = 0, nCount = 1;
*pWMF >> nTmp32;
*pWMF >> nOffset;
for ( sal_uInt32 i = 0; i < (nOffset - 20)/4; i ++ )
{
*pWMF >> nTmp32;
}
ReadDIB(aBmp, *pWMF, false);
pBmp = aBmp.AcquireReadAccess();
if ( pBmp )
{
for ( sal_Int32 y = 0; y < pBmp->Height(); y++ )
{
for ( sal_Int32 x = 0; x < pBmp->Width(); x++ )
{
const BitmapColor aColor( pBmp->GetColor( y, x ) );
nRed += aColor.GetRed();
nGreen += aColor.GetGreen();
nBlue += aColor.GetBlue();
}
}
nCount = pBmp->Height() * pBmp->Width();
if ( !nCount )
nCount++;
aBmp.ReleaseAccess( pBmp );
}
Color aColor( (sal_Char)( nRed / nCount ), (sal_Char)( nGreen / nCount ), (sal_Char)( nBlue / nCount ) );
pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aColor, sal_False ) );
}
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_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()
{
};