1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: enhwmf.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
35 #include <osl/endian.h>
37 //=========================== GDI-Array ===================================
40 #define EMR_POLYBEZIER 2
42 #define EMR_POLYLINE 4
43 #define EMR_POLYBEZIERTO 5
44 #define EMR_POLYLINETO 6
45 #define EMR_POLYPOLYLINE 7
46 #define EMR_POLYPOLYGON 8
47 #define EMR_SETWINDOWEXTEX 9
48 #define EMR_SETWINDOWORGEX 10
49 #define EMR_SETVIEWPORTEXTEX 11
50 #define EMR_SETVIEWPORTORGEX 12
51 #define EMR_SETBRUSHORGEX 13
53 #define EMR_SETPIXELV 15
54 #define EMR_SETMAPPERFLAGS 16
55 #define EMR_SETMAPMODE 17
56 #define EMR_SETBKMODE 18
57 #define EMR_SETPOLYFILLMODE 19
58 #define EMR_SETROP2 20
59 #define EMR_SETSTRETCHBLTMODE 21
60 #define EMR_SETTEXTALIGN 22
61 #define EMR_SETCOLORADJUSTMENT 23
62 #define EMR_SETTEXTCOLOR 24
63 #define EMR_SETBKCOLOR 25
64 #define EMR_OFFSETCLIPRGN 26
65 #define EMR_MOVETOEX 27
66 #define EMR_SETMETARGN 28
67 #define EMR_EXCLUDECLIPRECT 29
68 #define EMR_INTERSECTCLIPRECT 30
69 #define EMR_SCALEVIEWPORTEXTEX 31
70 #define EMR_SCALEWINDOWEXTEX 32
72 #define EMR_RESTOREDC 34
73 #define EMR_SETWORLDTRANSFORM 35
74 #define EMR_MODIFYWORLDTRANSFORM 36
75 #define EMR_SELECTOBJECT 37
76 #define EMR_CREATEPEN 38
77 #define EMR_CREATEBRUSHINDIRECT 39
78 #define EMR_DELETEOBJECT 40
79 #define EMR_ANGLEARC 41
80 #define EMR_ELLIPSE 42
81 #define EMR_RECTANGLE 43
82 #define EMR_ROUNDRECT 44
86 #define EMR_SELECTPALETTE 48
87 #define EMR_CREATEPALETTE 49
88 #define EMR_SETPALETTEENTRIES 50
89 #define EMR_RESIZEPALETTE 51
90 #define EMR_REALIZEPALETTE 52
91 #define EMR_EXTFLOODFILL 53
94 #define EMR_POLYDRAW 56
95 #define EMR_SETARCDIRECTION 57
96 #define EMR_SETMITERLIMIT 58
97 #define EMR_BEGINPATH 59
98 #define EMR_ENDPATH 60
99 #define EMR_CLOSEFIGURE 61
100 #define EMR_FILLPATH 62
101 #define EMR_STROKEANDFILLPATH 63
102 #define EMR_STROKEPATH 64
103 #define EMR_FLATTENPATH 65
104 #define EMR_WIDENPATH 66
105 #define EMR_SELECTCLIPPATH 67
106 #define EMR_ABORTPATH 68
108 #define EMR_GDICOMMENT 70
109 #define EMR_FILLRGN 71
110 #define EMR_FRAMERGN 72
111 #define EMR_INVERTRGN 73
112 #define EMR_PAINTRGN 74
113 #define EMR_EXTSELECTCLIPRGN 75
114 #define EMR_BITBLT 76
115 #define EMR_STRETCHBLT 77
116 #define EMR_MASKBLT 78
117 #define EMR_PLGBLT 79
118 #define EMR_SETDIBITSTODEVICE 80
119 #define EMR_STRETCHDIBITS 81
120 #define EMR_EXTCREATEFONTINDIRECTW 82
121 #define EMR_EXTTEXTOUTA 83
122 #define EMR_EXTTEXTOUTW 84
123 #define EMR_POLYBEZIER16 85
124 #define EMR_POLYGON16 86
125 #define EMR_POLYLINE16 87
126 #define EMR_POLYBEZIERTO16 88
127 #define EMR_POLYLINETO16 89
128 #define EMR_POLYPOLYLINE16 90
129 #define EMR_POLYPOLYGON16 91
130 #define EMR_POLYDRAW16 92
131 #define EMR_CREATEMONOBRUSH 93
132 #define EMR_CREATEDIBPATTERNBRUSHPT 94
133 #define EMR_EXTCREATEPEN 95
134 #define EMR_POLYTEXTOUTA 96
135 #define EMR_POLYTEXTOUTW 97
137 // WINDOWS VERSION >= 0x400
138 #define EMR_SETICMMODE 98
139 #define EMR_CREATECOLORSPACE 99
140 #define EMR_SETCOLORSPACE 100
141 #define EMR_DELETECOLORSPACE 101
142 #define EMR_GLSRECORD 102
143 #define EMR_GLSBOUNDEDRECORD 103
144 #define EMR_PIXELFORMAT 104
146 // WINDOWS VERSION >= 0x500
147 #define EMR_DRAWESCAPE 105
148 #define EMR_EXTESCAPE 106
149 #define EMR_STARTDOC 107
150 #define EMR_SMALLTEXTOUT 108
151 #define EMR_FORCEUFIMAPPING 109
152 #define EMR_NAMEDESCAPE 110
153 #define EMR_COLORCORRECTPALETTE 111
154 #define EMR_SETICMPROFILEA 112
155 #define EMR_SETICMPROFILEW 113
156 #define EMR_ALPHABLEND 114
157 #define EMR_ALPHADIBBLEND 115
158 #define EMR_TRANSPARENTBLT 116
159 #define EMR_TRANSPARENTDIB 117
160 #define EMR_GRADIENTFILL 118
161 #define EMR_SETLINKEDUFIS 119
162 #define EMR_SETTEXTJUSTIFICATION 120
164 #define EMFP_DEBUG(x)
165 //#define EMFP_DEBUG(x) x
167 //-----------------------------------------------------------------------------------
171 static float GetSwapFloat( SvStream
& rSt
)
174 sal_Int8
* pPtr
= (sal_Int8
*)&fTmp
;
175 rSt
>> pPtr
[3] >> pPtr
[2] >> pPtr
[1] >> pPtr
[0]; // Little Endian <-> Big Endian switch
180 SvStream
& operator>>( SvStream
& rIn
, XForm
& rXForm
)
182 if ( sizeof( float ) != 4 )
184 DBG_ERROR( "EnhWMFReader::sizeof( float ) != 4" );
190 rXForm
.eM11
= GetSwapFloat( rIn
);
191 rXForm
.eM12
= GetSwapFloat( rIn
);
192 rXForm
.eM21
= GetSwapFloat( rIn
);
193 rXForm
.eM22
= GetSwapFloat( rIn
);
194 rXForm
.eDx
= GetSwapFloat( rIn
);
195 rXForm
.eDy
= GetSwapFloat( rIn
);
197 rIn
>> rXForm
.eM11
>> rXForm
.eM12
>> rXForm
.eM21
>> rXForm
.eM22
198 >> rXForm
.eDx
>> rXForm
.eDy
;
204 static sal_Bool
ImplReadRegion( PolyPolygon
& rPolyPoly
, SvStream
& rSt
, sal_uInt32 nLen
)
206 sal_Bool bOk
= sal_False
;
209 sal_uInt32 nHdSize
, nType
, nCount
, nRgnSize
, i
;
215 if ( nCount
&& ( nType
== RDH_RECTANGLES
) &&
216 ( nLen
>= ( ( nCount
<< 4 ) + ( nHdSize
- 16 ) ) ) )
218 sal_Int32 nx1
, ny1
, nx2
, ny2
;
220 for ( i
= 0; i
< nCount
; i
++ )
222 rSt
>> nx1
>> ny1
>> nx2
>> ny2
;
224 Rectangle
aRect( Point( nx1
, ny1
), Point( nx2
, ny2
) );
225 Polygon
aPolygon( aRect
);
226 PolyPolygon
aPolyPolyOr1( aPolygon
);
227 PolyPolygon
aPolyPolyOr2( rPolyPoly
);
228 rPolyPoly
.GetUnion( aPolyPolyOr1
, aPolyPolyOr2
);
229 rPolyPoly
= aPolyPolyOr2
;
237 EMFP_DEBUG(void dumpWords( SvStream
& s
, int i
)
239 sal_uInt32 pos
= s
.Tell();
241 for( ; i
> 0; i
-- ) {
243 EMFP_DEBUG(printf ("\t\t\tdata: %04hx\n", data
));
248 void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length
, sal_Bool
& bHaveDC
)
251 pOut
->PassEMFPlusHeaderInfo();
253 // debug code - write the stream to debug file /tmp/emf-stream.emf
254 EMFP_DEBUG(int pos
= pWMF
->Tell();
256 SvFileStream
file( UniString::CreateFromAscii( "/tmp/emf-stream.emf" ), STREAM_WRITE
| STREAM_TRUNC
);
266 void *buffer
= malloc( length
);
268 int count
= 0, next
, pos
= pWMF
->Tell();
269 pOut
->PassEMFPlus( buffer
, pWMF
->Read( buffer
, length
) );
278 UINT32 size
, dataSize
;
281 *pWMF
>> type
>> flags
>> size
>> dataSize
;
283 EMFP_DEBUG(printf ("\t\tEMF+ record type: %d\n", type
));
286 if( type
== 16388 ) {
288 EMFP_DEBUG(printf ("\t\tEMF+ lock DC (device context)\n", type
));
291 next
= pWMF
->Tell() + ( size
- 12 );
301 void EnhWMFReader::ReadGDIComment()
309 sal_Int32 x
, y
, r
, b
;
311 EMFP_DEBUG(printf ("\t\tBEGINGROUP\n"));
313 *pWMF
>> x
>> y
>> r
>> b
;
314 EMFP_DEBUG(printf ("\t\tbounding rectangle: %d,%d x %d,%d\n", x
, y
, r
, b
));
319 EMFP_DEBUG(printf ("\t\tdescription length: %d\n", l
));
324 sal_uInt32 x
, y
, w
, h
;
326 EMFP_DEBUG(printf ("\t\tENDGROUP\n"));
330 sal_uInt32 x
, y
, w
, h
;
332 EMFP_DEBUG(printf ("\t\tMULTIFORMATS\n"));
336 EMFP_DEBUG(printf ("\t\tunknown GDIComment\n"));
337 EMFP_DEBUG(dumpWords (*pWMF
, 16));
341 BOOL
EnhWMFReader::ReadEnhWMF()
343 sal_uInt32 nStretchBltMode
= 0;
344 sal_uInt32 nRecType
, nRecSize
, nNextPos
,
345 nW
, nH
, nPoints
, nColor
, nIndex
,
346 nDat32
, nNom1
, nDen1
, nNom2
, nDen2
;
347 sal_Int32 nX32
, nY32
, nx32
, ny32
;
348 sal_Int16 nX16
, nY16
;
350 sal_Bool bFlag
, bStatus
= ReadHeader();
351 sal_Bool bHaveDC
= false;
354 static sal_Bool bEnableEMFPlus
= ( getenv( "EMF_PLUS_DISABLE" ) == NULL
);
356 // TODO: make it possible to disable emf+ on windows
357 static sal_Bool bEnableEMFPlus
= sal_True
;
360 while( bStatus
&& nRecordCount
-- )
362 *pWMF
>> nRecType
>> nRecSize
;
364 if ( ( nRecSize
< 8 ) || ( nRecSize
& 3 ) ) // Parameter sind immer durch 4 teilbar
370 nNextPos
= pWMF
->Tell() + ( nRecSize
- 8 );
372 if ( nNextPos
> nEndPos
)
378 if( aBmpSaveList
.Count() && ( nRecType
!= EMR_STRETCHBLT
) && ( nRecType
!= EMR_STRETCHDIBITS
) )
379 pOut
->ResolveBitmapActions( aBmpSaveList
);
383 EMFP_DEBUG(printf ("0x%04x-0x%04x record type: %d size: %d\n", nNextPos
- nRecSize
, nNextPos
, nRecType
, nRecSize
));
385 if( bEnableEMFPlus
&& nRecType
== EMR_GDICOMMENT
) {
390 EMFP_DEBUG(printf ("\tGDI comment\n\t\tlength: %d\n", length
));
397 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
));
399 // EMF+ comment (fixme: BE?)
400 if( id
== 0x2B464D45 && nRecSize
>= 12 )
401 ReadEMFPlusComment( length
, bHaveDC
);
402 // GDIC comment, doesn't do anything useful yet => enabled only for debug
403 else if( id
== 0x43494447 && nRecSize
>= 12 )
404 EMFP_DEBUG(ReadGDIComment());
406 EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n", id
));
408 } else if( !bEMFPlus
|| bHaveDC
|| nRecType
== EMR_EOF
)
412 case EMR_POLYBEZIERTO
:
414 case EMR_POLYBEZIER
:
424 Polygon
aPoly( (sal_uInt16
)nPoints
);
425 for( ; i
< (sal_uInt16
)nPoints
; i
++ )
427 *pWMF
>> nX32
>> nY32
;
428 aPoly
[ i
] = Point( nX32
, nY32
);
430 pOut
->DrawPolyBezier( aPoly
, bFlag
, bRecordPath
);
438 Polygon
aPoly( (UINT16
)nPoints
);
439 for( UINT16 k
= 0; k
< (UINT16
)nPoints
; k
++ )
441 *pWMF
>> nX32
>> nY32
;
442 aPoly
[ k
] = Point( nX32
, nY32
);
444 pOut
->DrawPolygon( aPoly
, bRecordPath
);
448 case EMR_POLYLINETO
:
452 pWMF
->SeekRel( 0x10 );
460 Polygon
aPolygon( (UINT16
)nPoints
);
461 for ( ; i
< (UINT16
)nPoints
; i
++ )
463 *pWMF
>> nX32
>> nY32
;
464 aPolygon
[ i
] = Point( nX32
, nY32
);
466 pOut
->DrawPolyLine( aPolygon
, bFlag
, bRecordPath
);
470 case EMR_POLYPOLYLINE
:
475 pWMF
->SeekRel( 0x10 );
477 // Anzahl der Polygone:
480 // taking the amount of points of each polygon, retrieving the total number of points
481 if ( static_cast< sal_uInt32
>(nPoly
) < SAL_MAX_UINT32
/ sizeof(UINT16
) )
483 if ( ( static_cast< sal_uInt32
>( nPoly
) * sizeof(UINT16
) ) <= ( nEndPos
- pWMF
->Tell() ) )
485 pnPoints
= new UINT16
[ nPoly
];
487 for ( i
= 0; i
< nPoly
; i
++ )
490 pnPoints
[ i
] = (UINT16
)nPoints
;
493 // Polygonpunkte holen:
495 for ( i
= 0; ( i
< nPoly
) && !pWMF
->IsEof(); i
++ )
497 Polygon
aPoly( pnPoints
[ i
] );
498 for( UINT16 k
= 0; k
< pnPoints
[ i
]; k
++ )
500 *pWMF
>> nX32
>> nY32
;
501 aPoly
[ k
] = Point( nX32
, nY32
);
503 pOut
->DrawPolyLine( aPoly
, sal_False
, bRecordPath
);
511 case EMR_POLYPOLYGON
:
516 UINT32 i
, nPoly
, nGesPoints
;
517 pWMF
->SeekRel( 0x10 );
519 // Anzahl der Polygone:
520 *pWMF
>> nPoly
>> nGesPoints
;
522 if ( ( nGesPoints
< SAL_MAX_UINT32
/ sizeof(Point
) ) && ( nPoly
< SAL_MAX_UINT32
/ sizeof(UINT16
) ) )
524 if ( ( nPoly
* sizeof(UINT16
) ) <= ( nEndPos
- pWMF
->Tell() ) )
526 pnPoints
= new UINT16
[ nPoly
];
528 for ( i
= 0; i
< nPoly
; i
++ )
531 pnPoints
[ i
] = (UINT16
)nPoints
;
534 if ( ( nGesPoints
* (sizeof(sal_uInt32
)+sizeof(sal_uInt32
)) ) <= ( nEndPos
- pWMF
->Tell() ) )
536 // Polygonpunkte holen:
537 pPtAry
= new Point
[ nGesPoints
];
539 for ( i
= 0; i
< nGesPoints
; i
++ )
541 *pWMF
>> nX32
>> nY32
;
542 pPtAry
[ i
] = Point( nX32
, nY32
);
544 // PolyPolygon Actions erzeugen
545 PolyPolygon
aPolyPoly( (UINT16
)nPoly
, pnPoints
, pPtAry
);
546 pOut
->DrawPolyPolygon( aPolyPoly
, bRecordPath
);
555 case EMR_SETWINDOWEXTEX
:
558 pOut
->SetWinExt( Size( nW
, nH
) );
562 case EMR_SETWINDOWORGEX
:
564 *pWMF
>> nX32
>> nY32
;
565 pOut
->SetWinOrg( Point( nX32
, nY32
) );
569 case EMR_SCALEWINDOWEXTEX
:
571 *pWMF
>> nNom1
>> nDen1
>> nNom2
>> nDen2
;
572 pOut
->ScaleWinExt( (double)nNom1
/ nDen1
, (double)nNom2
/ nDen2
);
576 case EMR_SETVIEWPORTORGEX
:
578 *pWMF
>> nX32
>> nY32
;
579 pOut
->SetDevOrg( Point( nX32
, nY32
) );
583 case EMR_SCALEVIEWPORTEXTEX
:
585 *pWMF
>> nNom1
>> nDen1
>> nNom2
>> nDen2
;
586 pOut
->ScaleDevExt( (double)nNom1
/ nDen1
, (double)nNom2
/ nDen2
);
590 case EMR_SETVIEWPORTEXTEX
:
593 pOut
->SetDevExt( Size( nW
, nH
) );
598 nRecordCount
= 0; // #76846#
603 *pWMF
>> nX32
>> nY32
;
604 pOut
->DrawPixel( Point( nX32
, nY32
), ReadColor() );
608 case EMR_SETMAPMODE
:
612 pOut
->SetMapMode( nMapMode
);
619 pOut
->SetBkMode( nDat32
);
623 case EMR_SETPOLYFILLMODE
:
629 pOut
->SetRasterOp( nDat32
);
633 case EMR_SETSTRETCHBLTMODE
:
635 *pWMF
>> nStretchBltMode
;
639 case EMR_SETTEXTALIGN
:
642 pOut
->SetTextAlign( nDat32
);
646 case EMR_SETTEXTCOLOR
:
648 pOut
->SetTextColor( ReadColor() );
652 case EMR_SETBKCOLOR
:
654 pOut
->SetBkColor( ReadColor() );
658 case EMR_OFFSETCLIPRGN
:
660 *pWMF
>> nX32
>> nY32
;
661 pOut
->MoveClipRegion( Size( nX32
, nY32
) );
667 *pWMF
>> nX32
>> nY32
;
668 pOut
->MoveTo( Point( nX32
, nY32
), bRecordPath
);
672 case EMR_INTERSECTCLIPRECT
:
674 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
;
675 pOut
->IntersectClipRect( ReadRectangle( nX32
, nY32
, nx32
, ny32
) );
691 case EMR_SETWORLDTRANSFORM
:
695 pOut
->SetWorldTransform( aTempXForm
);
699 case EMR_MODIFYWORLDTRANSFORM
:
703 *pWMF
>> aTempXForm
>> nMode
;
704 pOut
->ModifyWorldTransform( aTempXForm
, nMode
);
708 case EMR_SELECTOBJECT
:
711 pOut
->SelectObject( nIndex
);
718 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
725 *pWMF
>> nStyle
>> aSize
.Width() >> aSize
.Height();
728 aLineInfo
.SetWidth( aSize
.Width() );
730 BOOL bTransparent
= FALSE
;
731 UINT16 nDashCount
= 0;
732 UINT16 nDotCount
= 0;
747 aLineInfo
.SetStyle( LINE_NONE
);
750 case PS_INSIDEFRAME
:
752 aLineInfo
.SetStyle( LINE_SOLID
);
754 if ( nDashCount
| nDotCount
)
756 aLineInfo
.SetStyle( LINE_DASH
);
757 aLineInfo
.SetDashCount( nDashCount
);
758 aLineInfo
.SetDotCount( nDotCount
);
760 pOut
->CreateObject( nIndex
, GDI_PEN
, new WinMtfLineStyle( ReadColor(), aLineInfo
, bTransparent
) );
765 case EMR_EXTCREATEPEN
:
768 sal_uInt32 offBmi
, cbBmi
, offBits
, cbBits
, nStyle
, nWidth
, nBrushStyle
, elpNumEntries
;
772 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
774 *pWMF
>> offBmi
>> cbBmi
>> offBits
>> cbBits
>> nStyle
>> nWidth
>> nBrushStyle
;
775 aColorRef
= ReadColor();
776 *pWMF
>> elpHatch
>> elpNumEntries
;
780 aLineInfo
.SetWidth( nWidth
);
782 sal_Bool bTransparent
= sal_False
;
783 sal_uInt16 nDashCount
= 0;
784 sal_uInt16 nDotCount
= 0;
786 switch( nStyle
& PS_STYLE_MASK
)
799 bTransparent
= sal_True
;
800 aLineInfo
.SetStyle( LINE_NONE
);
804 case PS_INSIDEFRAME
:
806 aLineInfo
.SetStyle( LINE_SOLID
);
808 if ( nDashCount
| nDotCount
)
810 aLineInfo
.SetStyle( LINE_DASH
);
811 aLineInfo
.SetDashCount( nDashCount
);
812 aLineInfo
.SetDotCount( nDotCount
);
814 pOut
->CreateObject( nIndex
, GDI_PEN
, new WinMtfLineStyle( aColorRef
, aLineInfo
, bTransparent
) );
819 case EMR_CREATEBRUSHINDIRECT
:
823 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
826 pOut
->CreateObject( nIndex
, GDI_BRUSH
, new WinMtfFillStyle( ReadColor(), ( nStyle
== BS_HOLLOW
) ? TRUE
: FALSE
) );
831 case EMR_DELETEOBJECT
:
834 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
835 pOut
->DeleteObject( nIndex
);
841 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
;
842 pOut
->DrawEllipse( ReadRectangle( nX32
, nY32
, nx32
, ny32
) );
848 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
;
849 pOut
->DrawRect( ReadRectangle( nX32
, nY32
, nx32
, ny32
) );
855 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
>> nW
>> nH
;
856 Size
aSize( Size( nW
, nH
) );
857 pOut
->DrawRoundRect( ReadRectangle( nX32
, nY32
, nx32
, ny32
), aSize
);
863 UINT32 nStartX
, nStartY
, nEndX
, nEndY
;
864 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
>> nStartX
>> nStartY
>> nEndX
>> nEndY
;
865 pOut
->DrawArc( ReadRectangle( nX32
, nY32
, nx32
, ny32
), Point( nStartX
, nStartY
), Point( nEndX
, nEndY
) );
871 UINT32 nStartX
, nStartY
, nEndX
, nEndY
;
872 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
>> nStartX
>> nStartY
>> nEndX
>> nEndY
;
873 pOut
->DrawChord( ReadRectangle( nX32
, nY32
, nx32
, ny32
), Point( nStartX
, nStartY
), Point( nEndX
, nEndY
) );
879 UINT32 nStartX
, nStartY
, nEndX
, nEndY
;
880 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
>> nStartX
>> nStartY
>> nEndX
>> nEndY
;
881 const Rectangle
aRect( ReadRectangle( nX32
, nY32
, nx32
, ny32
));
883 // #i73608# OutputDevice deviates from WMF
884 // semantics. start==end means full ellipse here.
885 if( nStartX
== nEndX
&& nStartY
== nEndY
)
886 pOut
->DrawEllipse( aRect
);
888 pOut
->DrawPie( aRect
, Point( nStartX
, nStartY
), Point( nEndX
, nEndY
) );
894 *pWMF
>> nX32
>> nY32
;
895 pOut
->LineTo( Point( nX32
, nY32
), bRecordPath
);
901 UINT32 nStartX
, nStartY
, nEndX
, nEndY
;
902 *pWMF
>> nX32
>> nY32
>> nx32
>> ny32
>> nStartX
>> nStartY
>> nEndX
>> nEndY
;
903 pOut
->DrawArc( ReadRectangle( nX32
, nY32
, nx32
, ny32
), Point( nStartX
, nStartY
), Point( nEndX
, nEndY
), TRUE
);
910 bRecordPath
= sal_True
;
917 bRecordPath
= sal_False
;
920 case EMR_CLOSEFIGURE
:
925 pOut
->StrokeAndFillPath( sal_False
, sal_True
);
928 case EMR_STROKEANDFILLPATH
:
929 pOut
->StrokeAndFillPath( sal_True
, sal_True
);
932 case EMR_STROKEPATH
:
933 pOut
->StrokeAndFillPath( sal_True
, sal_False
);
936 case EMR_SELECTCLIPPATH
:
938 sal_Int32 nClippingMode
;
939 *pWMF
>> nClippingMode
;
940 pOut
->SetClipPath( pOut
->GetPathObj(), nClippingMode
, sal_True
);
944 case EMR_EXTSELECTCLIPRGN
:
946 sal_Int32 iMode
, cbRgnData
;
950 PolyPolygon aPolyPoly
;
952 ImplReadRegion( aPolyPoly
, *pWMF
, nRecSize
);
953 pOut
->SetClipPath( aPolyPoly
, iMode
, sal_False
);
957 case EMR_BITBLT
: // PASSTHROUGH INTENDED
958 case EMR_STRETCHBLT
:
960 INT32 xDest
, yDest
, cxDest
, cyDest
, xSrc
, ySrc
, cxSrc
, cySrc
;
961 UINT32 dwRop
, iUsageSrc
, offBmiSrc
, cbBmiSrc
, offBitsSrc
, cbBitsSrc
;
964 UINT32 nStart
= pWMF
->Tell() - 8;
966 pWMF
->SeekRel( 0x10 );
967 *pWMF
>> xDest
>> yDest
>> cxDest
>> cyDest
>> dwRop
>> xSrc
>> ySrc
968 >> xformSrc
>> nColor
>> iUsageSrc
>> offBmiSrc
>> cbBmiSrc
969 >> offBitsSrc
>> cbBitsSrc
;
971 if ( nRecType
== EMR_STRETCHBLT
)
972 *pWMF
>> cxSrc
>> cySrc
;
977 Rectangle
aRect( Point( xDest
, yDest
), Size( cxDest
+1, cyDest
+1 ) );
979 cxDest
= abs( (int)cxDest
); // sj: i37894, size can be negative
980 cyDest
= abs( (int)cyDest
); // and also 122889
982 if ( (cbBitsSrc
> (SAL_MAX_UINT32
- 14)) || ((SAL_MAX_UINT32
- 14) - cbBitsSrc
< cbBmiSrc
) )
986 UINT32 nSize
= cbBmiSrc
+ cbBitsSrc
+ 14;
987 if ( nSize
<= ( nEndPos
- nStartPos
) )
989 char* pBuf
= new char[ nSize
];
990 SvMemoryStream
aTmp( pBuf
, nSize
, STREAM_READ
| STREAM_WRITE
);
991 aTmp
.ObjectOwnsMemory( TRUE
);
997 << (UINT32
)cbBmiSrc
+ 14;
998 pWMF
->Seek( nStart
+ offBmiSrc
);
999 pWMF
->Read( pBuf
+ 14, cbBmiSrc
);
1000 pWMF
->Seek( nStart
+ offBitsSrc
);
1001 pWMF
->Read( pBuf
+ 14 + cbBmiSrc
, cbBitsSrc
);
1003 aBitmap
.Read( aTmp
, TRUE
);
1005 // test if it is sensible to crop
1006 if ( ( cxSrc
> 0 ) && ( cySrc
> 0 ) &&
1007 ( xSrc
>= 0 ) && ( ySrc
>= 0 ) &&
1008 ( xSrc
+ cxSrc
<= aBitmap
.GetSizePixel().Width() ) &&
1009 ( ySrc
+ cySrc
<= aBitmap
.GetSizePixel().Height() ) )
1011 Rectangle
aCropRect( Point( xSrc
, ySrc
), Size( cxSrc
, cySrc
) );
1012 aBitmap
.Crop( aCropRect
);
1014 /* Pseudocomment to add more context so that make patch.unapply
1017 aBmpSaveList
.Insert( new BSaveStruct( aBitmap
, aRect
, dwRop
, pOut
->GetFillStyle () ), LIST_APPEND
);
1023 case EMR_STRETCHDIBITS
:
1025 INT32 xDest
, yDest
, xSrc
, ySrc
, cxSrc
, cySrc
, cxDest
, cyDest
;
1026 UINT32 offBmiSrc
, cbBmiSrc
, offBitsSrc
, cbBitsSrc
, iUsageSrc
, dwRop
;
1027 UINT32 nStart
= pWMF
->Tell() - 8;
1029 pWMF
->SeekRel( 0x10 );
1030 *pWMF
>> xDest
>> yDest
>> xSrc
>> ySrc
>> cxSrc
>> cySrc
>> offBmiSrc
>> cbBmiSrc
>> offBitsSrc
1031 >> cbBitsSrc
>> iUsageSrc
>> dwRop
>> cxDest
>> cyDest
;
1034 Rectangle
aRect( Point( xDest
, yDest
), Size( cxDest
+1, cyDest
+1 ) );
1036 cxDest
= abs( (int)cxDest
); // sj: i37894, size can be negative
1037 cyDest
= abs( (int)cyDest
); // and also 122889
1039 if ( (cbBitsSrc
> (SAL_MAX_UINT32
- 14)) || ((SAL_MAX_UINT32
- 14) - cbBitsSrc
< cbBmiSrc
) )
1043 UINT32 nSize
= cbBmiSrc
+ cbBitsSrc
+ 14;
1044 if ( nSize
<= ( nEndPos
- nStartPos
) )
1046 char* pBuf
= new char[ nSize
];
1047 SvMemoryStream
aTmp( pBuf
, nSize
, STREAM_READ
| STREAM_WRITE
);
1048 aTmp
.ObjectOwnsMemory( TRUE
);
1051 << (UINT32
)cbBitsSrc
1054 << (UINT32
)cbBmiSrc
+ 14;
1055 pWMF
->Seek( nStart
+ offBmiSrc
);
1056 pWMF
->Read( pBuf
+ 14, cbBmiSrc
);
1057 pWMF
->Seek( nStart
+ offBitsSrc
);
1058 pWMF
->Read( pBuf
+ 14 + cbBmiSrc
, cbBitsSrc
);
1060 aBitmap
.Read( aTmp
, TRUE
);
1062 // test if it is sensible to crop
1063 if ( ( cxSrc
> 0 ) && ( cySrc
> 0 ) &&
1064 ( xSrc
>= 0 ) && ( ySrc
>= 0 ) &&
1065 ( xSrc
+ cxSrc
<= aBitmap
.GetSizePixel().Width() ) &&
1066 ( ySrc
+ cySrc
<= aBitmap
.GetSizePixel().Height() ) )
1068 Rectangle
aCropRect( Point( xSrc
, ySrc
), Size( cxSrc
, cySrc
) );
1069 aBitmap
.Crop( aCropRect
);
1071 /* Another pseudocomment to make make patch.unapply work better */
1072 aBmpSaveList
.Insert( new BSaveStruct( aBitmap
, aRect
, dwRop
, pOut
->GetFillStyle () ), LIST_APPEND
);
1078 case EMR_EXTCREATEFONTINDIRECTW
:
1081 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
1084 *pWMF
>> aLogFont
.lfHeight
>> aLogFont
.lfWidth
>> aLogFont
.lfEscapement
>> aLogFont
.lfOrientation
>> aLogFont
.lfWeight
>> aLogFont
.lfItalic
1085 >> aLogFont
.lfUnderline
>> aLogFont
.lfStrikeOut
>> aLogFont
.lfCharSet
>> aLogFont
.lfOutPrecision
>> aLogFont
.lfClipPrecision
1086 >> aLogFont
.lfQuality
>> aLogFont
.lfPitchAndFamily
;
1088 sal_Unicode lfFaceName
[ LF_FACESIZE
];
1090 for ( int i
= 0; i
< LF_FACESIZE
; i
++ )
1094 lfFaceName
[ i
] = nChar
;
1096 aLogFont
.alfFaceName
= UniString( lfFaceName
);
1097 pOut
->CreateObject( nIndex
, GDI_FONT
, new WinMtfFontStyle( aLogFont
) );
1102 case EMR_EXTTEXTOUTA
:
1104 case EMR_EXTTEXTOUTW
:
1106 sal_Int32 nLeft
, nTop
, nRight
, nBottom
, ptlReferenceX
, ptlReferenceY
, nGfxMode
, nXScale
, nYScale
;
1107 sal_uInt32 nCurPos
, nLen
, nOffString
, nOptions
, offDx
;
1108 sal_Int32
* pDX
= NULL
;
1110 nCurPos
= pWMF
->Tell() - 8;
1112 *pWMF
>> nLeft
>> nTop
>> nRight
>> nBottom
>> nGfxMode
>> nXScale
>> nYScale
1113 >> ptlReferenceX
>> ptlReferenceY
>> nLen
>> nOffString
>> nOptions
;
1115 pWMF
->SeekRel( 0x10 );
1118 sal_Int32 nTextLayoutMode
= TEXT_LAYOUT_DEFAULT
;
1119 if ( nOptions
& ETO_RTLREADING
)
1120 nTextLayoutMode
= TEXT_LAYOUT_BIDI_RTL
| TEXT_LAYOUT_TEXTORIGIN_LEFT
;
1121 pOut
->SetTextLayoutMode( nTextLayoutMode
);
1122 DBG_ASSERT( ( nOptions
& ( ETO_PDY
| ETO_GLYPH_INDEX
) ) == 0, "SJ: ETO_PDY || ETO_GLYPH_INDEX in EMF" );
1124 Point
aPos( ptlReferenceX
, ptlReferenceY
);
1125 if ( nLen
&& ( nLen
< SAL_MAX_UINT32
/ sizeof(sal_Int32
) ) )
1127 if ( offDx
&& (( nCurPos
+ offDx
+ nLen
* 4 ) <= nNextPos
) )
1129 pWMF
->Seek( nCurPos
+ offDx
);
1130 if ( ( nLen
* sizeof(sal_uInt32
) ) <= ( nEndPos
- pWMF
->Tell() ) )
1132 pDX
= new sal_Int32
[ nLen
];
1134 for ( i
= 0; i
< nLen
; i
++ )
1138 pWMF
->Seek( nCurPos
+ nOffString
);
1142 if ( nLen
<= ( nEndPos
- pWMF
->Tell() ) )
1144 sal_Char
* pBuf
= new sal_Char
[ nLen
];
1145 pWMF
->Read( pBuf
, nLen
);
1146 aText
= String( pBuf
, (sal_uInt16
)nLen
, pOut
->GetCharSet() );
1149 if ( aText
.Len() != nLen
)
1152 sal_Int32
* pOldDx
= pDX
;
1153 pDX
= new sal_Int32
[ aText
.Len() ];
1154 for ( i
= 0, j
= 0; i
< aText
.Len(); i
++ )
1156 ByteString
aCharacter( aText
.GetChar( i
), pOut
->GetCharSet() );
1158 for ( k
= 0; ( k
< aCharacter
.Len() ) && ( j
< nLen
) && ( i
< aText
.Len() ); k
++ )
1159 pDX
[ i
] += pOldDx
[ j
++ ];
1167 if ( ( nLen
* sizeof(sal_Unicode
) ) <= ( nEndPos
- pWMF
->Tell() ) )
1169 sal_Unicode
* pBuf
= new sal_Unicode
[ nLen
];
1170 pWMF
->Read( pBuf
, nLen
<< 1 );
1171 #ifdef OSL_BIGENDIAN
1172 sal_Char nTmp
, *pTmp
= (sal_Char
*)( pBuf
+ nLen
);
1173 while ( pTmp
-- != (sal_Char
*)pBuf
)
1180 aText
= String( pBuf
, (xub_StrLen
)nLen
);
1184 pOut
->DrawText( aPos
, aText
, pDX
, bRecordPath
, nGfxMode
);
1190 case EMR_POLYBEZIERTO16
:
1192 case EMR_POLYBEZIER16
:
1194 pWMF
->SeekRel( 16 );
1202 Polygon
aPoly( (UINT16
)nPoints
);
1203 for( ; i
< (UINT16
)nPoints
; i
++ )
1205 *pWMF
>> nX16
>> nY16
;
1206 aPoly
[ i
] = Point( nX16
, nY16
);
1208 pOut
->DrawPolyBezier( aPoly
, bFlag
, bRecordPath
); // Line( aPoly, bFlag );
1212 case EMR_POLYGON16
:
1214 pWMF
->SeekRel( 16 );
1216 Polygon
aPoly( (UINT16
)nPoints
);
1217 for( UINT16 k
= 0; k
< (UINT16
)nPoints
; k
++ )
1219 *pWMF
>> nX16
>> nY16
;
1220 aPoly
[ k
] = Point( nX16
, nY16
);
1222 pOut
->DrawPolygon( aPoly
, bRecordPath
);
1226 case EMR_POLYLINETO16
:
1228 case EMR_POLYLINE16
:
1230 pWMF
->SeekRel( 16 );
1239 Polygon
aPoly( (UINT16
)nPoints
);
1240 for( ; i
< (UINT16
)nPoints
; i
++ )
1242 *pWMF
>> nX16
>> nY16
;
1243 aPoly
[ i
] = Point( nX16
, nY16
);
1245 pOut
->DrawPolyLine( aPoly
, bFlag
, bRecordPath
);
1249 case EMR_POLYPOLYLINE16
:
1253 INT32 i
, nPoly
, nGesPoints
;
1254 pWMF
->SeekRel( 0x10 );
1255 // Anzahl der Polygone:
1256 *pWMF
>> nPoly
>> nGesPoints
;
1258 // taking the amount of points of each polygon, retrieving the total number of points
1259 if ( static_cast< sal_uInt32
>(nPoly
) < SAL_MAX_UINT32
/ sizeof(UINT16
) )
1261 if ( ( static_cast< sal_uInt32
>( nPoly
) * sizeof(UINT16
) ) <= ( nEndPos
- pWMF
->Tell() ) )
1263 pnPoints
= new UINT16
[ nPoly
];
1264 for ( i
= 0; i
< nPoly
; i
++ )
1267 pnPoints
[ i
] = (UINT16
)nPoints
;
1269 // Polygonpunkte holen:
1270 for ( i
= 0; ( i
< nPoly
) && !pWMF
->IsEof(); i
++ )
1272 Polygon
aPolygon( pnPoints
[ i
] );
1273 for ( UINT16 k
= 0; k
< pnPoints
[ i
]; k
++ )
1275 *pWMF
>> nX16
>> nY16
;
1276 aPolygon
[ k
] = Point( nX16
, nY16
);
1278 pOut
->DrawPolyLine( aPolygon
, sal_False
, bRecordPath
);
1286 case EMR_POLYPOLYGON16
:
1291 UINT32 i
, nPoly
, nGesPoints
;
1292 pWMF
->SeekRel( 0x10 );
1293 // Anzahl der Polygone:
1294 *pWMF
>> nPoly
>> nGesPoints
;
1295 if ( ( nGesPoints
< SAL_MAX_UINT32
/ sizeof(Point
) ) && ( nPoly
< SAL_MAX_UINT32
/ sizeof(UINT16
) ) )
1297 if ( ( static_cast< sal_uInt32
>( nPoly
) * sizeof( UINT16
) ) <= ( nEndPos
- pWMF
->Tell() ) )
1299 pnPoints
= new UINT16
[ nPoly
];
1300 for ( i
= 0; i
< nPoly
; i
++ )
1303 pnPoints
[ i
] = (UINT16
)nPoints
;
1305 if ( ( nGesPoints
* (sizeof(sal_uInt16
)+sizeof(sal_uInt16
)) ) <= ( nEndPos
- pWMF
->Tell() ) )
1307 // Polygonpunkte holen:
1308 pPtAry
= new Point
[ nGesPoints
];
1309 for ( i
= 0; i
< nGesPoints
; i
++ )
1311 *pWMF
>> nX16
>> nY16
;
1312 pPtAry
[ i
] = Point( nX16
, nY16
);
1315 // PolyPolygon Actions erzeugen
1316 PolyPolygon
aPolyPoly( (UINT16
)nPoly
, pnPoints
, pPtAry
);
1317 pOut
->DrawPolyPolygon( aPolyPoly
, bRecordPath
);
1329 PolyPolygon aPolyPoly
;
1330 pWMF
->SeekRel( 0x10 );
1331 *pWMF
>> nLen
>> nIndex
;
1333 if ( ImplReadRegion( aPolyPoly
, *pWMF
, nRecSize
) )
1336 pOut
->SelectObject( nIndex
);
1337 pOut
->DrawPolyPolygon( aPolyPoly
, sal_False
);
1343 case EMR_CREATEDIBPATTERNBRUSHPT
:
1345 static int count
= 0;
1346 UINT32 nStart
= pWMF
->Tell() - 8;
1351 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
1353 UINT32 usage
, offBmi
, cbBmi
, offBits
, cbBits
;
1361 if ( (cbBits
> (SAL_MAX_UINT32
- 14)) || ((SAL_MAX_UINT32
- 14) - cbBits
< cbBmi
) )
1365 UINT32 nSize
= cbBmi
+ cbBits
+ 14;
1366 if ( nSize
<= ( nEndPos
- nStartPos
) )
1368 char* pBuf
= new char[ nSize
];
1370 SvMemoryStream
aTmp( pBuf
, nSize
, STREAM_READ
| STREAM_WRITE
);
1371 aTmp
.ObjectOwnsMemory( TRUE
);
1377 << (UINT32
)cbBmi
+ 14;
1378 pWMF
->Seek( nStart
+ offBmi
);
1379 pWMF
->Read( pBuf
+ 14, cbBmi
);
1380 pWMF
->Seek( nStart
+ offBits
);
1381 pWMF
->Read( pBuf
+ 14 + cbBmi
, cbBits
);
1383 aBitmap
.Read( aTmp
, TRUE
);
1388 pOut
->CreateObject( nIndex
, GDI_BRUSH
, new WinMtfFillStyle( aBitmap
) );
1392 #ifdef WIN_MTF_ASSERT
1393 default : WinMtfAssertHandler( "Unknown Meta Action" ); break;
1394 case EMR_MASKBLT
: WinMtfAssertHandler( "MaskBlt" ); break;
1395 case EMR_PLGBLT
: WinMtfAssertHandler( "PlgBlt" ); break;
1396 case EMR_SETDIBITSTODEVICE
: WinMtfAssertHandler( "SetDIBitsToDevice" ); break;
1397 case EMR_FRAMERGN
: WinMtfAssertHandler( "FrameRgn" ); break;
1398 case EMR_INVERTRGN
: WinMtfAssertHandler( "InvertRgn" ); break;
1399 case EMR_PAINTRGN
: WinMtfAssertHandler( "PaintRgn" ); break;
1400 case EMR_FLATTENPATH
: WinMtfAssertHandler( "FlattenPath" ); break;
1401 case EMR_WIDENPATH
: WinMtfAssertHandler( "WidenPath" ); break;
1402 case EMR_POLYDRAW
: WinMtfAssertHandler( "Polydraw" ); break;
1403 case EMR_SETARCDIRECTION
: WinMtfAssertHandler( "SetArcDirection" ); break;
1404 case EMR_SETPALETTEENTRIES
: WinMtfAssertHandler( "SetPaletteEntries" ); break;
1405 case EMR_RESIZEPALETTE
: WinMtfAssertHandler( "ResizePalette" ); break;
1406 case EMR_EXTFLOODFILL
: WinMtfAssertHandler( "ExtFloodFill" ); break;
1407 case EMR_ANGLEARC
: WinMtfAssertHandler( "AngleArc" ); break;
1408 case EMR_SETCOLORADJUSTMENT
: WinMtfAssertHandler( "SetColorAdjustment" ); break;
1409 case EMR_POLYDRAW16
: WinMtfAssertHandler( "PolyDraw16" ); break;
1410 case EMR_POLYTEXTOUTA
: WinMtfAssertHandler( "PolyTextOutA" ); break;
1411 case EMR_POLYTEXTOUTW
: WinMtfAssertHandler( "PolyTextOutW" ); break;
1412 case EMR_CREATECOLORSPACE
: WinMtfAssertHandler( "CreateColorSpace" ); break;
1413 case EMR_SETCOLORSPACE
: WinMtfAssertHandler( "SetColorSpace" ); break;
1414 case EMR_DELETECOLORSPACE
: WinMtfAssertHandler( "DeleteColorSpace" ); break;
1415 case EMR_GLSRECORD
: WinMtfAssertHandler( "GlsRecord" ); break;
1416 case EMR_GLSBOUNDEDRECORD
: WinMtfAssertHandler( "GlsBoundRecord" ); break;
1417 case EMR_PIXELFORMAT
: WinMtfAssertHandler( "PixelFormat" ); break;
1418 case EMR_DRAWESCAPE
: WinMtfAssertHandler( "DrawEscape" ); break;
1419 case EMR_EXTESCAPE
: WinMtfAssertHandler( "ExtEscape" ); break;
1420 case EMR_STARTDOC
: WinMtfAssertHandler( "StartDoc" ); break;
1421 case EMR_SMALLTEXTOUT
: WinMtfAssertHandler( "SmallTextOut" ); break;
1422 case EMR_FORCEUFIMAPPING
: WinMtfAssertHandler( "ForceUFIMapping" ); break;
1423 case EMR_NAMEDESCAPE
: WinMtfAssertHandler( "NamedEscape" ); break;
1424 case EMR_COLORCORRECTPALETTE
: WinMtfAssertHandler( "ColorCorrectPalette" ); break;
1425 case EMR_SETICMPROFILEA
: WinMtfAssertHandler( "SetICMProfileA" ); break;
1426 case EMR_SETICMPROFILEW
: WinMtfAssertHandler( "SetICMProfileW" ); break;
1427 case EMR_ALPHABLEND
: WinMtfAssertHandler( "Alphablend" ); break;
1428 case EMR_TRANSPARENTBLT
: WinMtfAssertHandler( "TransparenBlt" ); break;
1429 case EMR_TRANSPARENTDIB
: WinMtfAssertHandler( "TransparenDib" ); break;
1430 case EMR_GRADIENTFILL
: WinMtfAssertHandler( "GradientFill" ); break;
1431 case EMR_SETLINKEDUFIS
: WinMtfAssertHandler( "SetLinkedUFIS" ); break;
1433 case EMR_SETMAPPERFLAGS
: WinMtfAssertHandler( "SetMapperFlags", 0 ); break;
1434 case EMR_SETICMMODE
: WinMtfAssertHandler( "SetICMMode", 0 ); break;
1435 case EMR_CREATEMONOBRUSH
: WinMtfAssertHandler( "CreateMonoBrush", 0 ); break;
1436 case EMR_SETBRUSHORGEX
: WinMtfAssertHandler( "SetBrushOrgEx", 0 ); break;
1437 case EMR_SETMETARGN
: WinMtfAssertHandler( "SetMetArgn", 0 ); break;
1438 case EMR_SETMITERLIMIT
: WinMtfAssertHandler( "SetMiterLimit", 0 ); break;
1439 case EMR_EXCLUDECLIPRECT
: WinMtfAssertHandler( "ExcludeClipRect", 0 ); break;
1440 case EMR_REALIZEPALETTE
: WinMtfAssertHandler( "RealizePalette", 0 ); break;
1441 case EMR_SELECTPALETTE
: WinMtfAssertHandler( "SelectPalette", 0 ); break;
1442 case EMR_CREATEPALETTE
: WinMtfAssertHandler( "CreatePalette", 0 ); break;
1443 case EMR_ALPHADIBBLEND
: WinMtfAssertHandler( "AlphaDibBlend", 0 ); break;
1444 case EMR_SETTEXTJUSTIFICATION
: WinMtfAssertHandler( "SetTextJustification", 0 ); break;
1446 case EMR_GDICOMMENT
:
1447 case EMR_HEADER
: // has already been read at ReadHeader()
1451 pWMF
->Seek( nNextPos
);
1453 if( aBmpSaveList
.Count() )
1454 pOut
->ResolveBitmapActions( aBmpSaveList
);
1457 pWMF
->Seek(nEndPos
);
1462 //-----------------------------------------------------------------------------------
1464 BOOL
EnhWMFReader::ReadHeader()
1466 UINT32 nUINT32
, nHeaderSize
, nPalEntries
;
1467 INT32 nLeft
, nTop
, nRight
, nBottom
;
1469 // METAFILEHEADER SPARE ICH MIR HIER
1470 // Einlesen des METAHEADER
1471 *pWMF
>> nUINT32
>> nHeaderSize
;
1472 if ( nUINT32
!= 1 ) // Typ
1476 Rectangle rclBounds
; // rectangle in logical units 1/100th mm
1477 *pWMF
>> nLeft
>> nTop
>> nRight
>> nBottom
;
1478 rclBounds
.Left() = nLeft
;
1479 rclBounds
.Top() = nTop
;
1480 rclBounds
.Right() = nRight
;
1481 rclBounds
.Bottom() = nBottom
;
1483 // picture frame size
1484 Rectangle rclFrame
; // rectangle in device units
1485 *pWMF
>> nLeft
>> nTop
>> nRight
>> nBottom
;
1486 rclFrame
.Left() = nLeft
;
1487 rclFrame
.Top() = nTop
;
1488 rclFrame
.Right() = nRight
;
1489 rclFrame
.Bottom() = nBottom
;
1491 *pWMF
>> nUINT32
; // signature
1493 if ( nUINT32
!= 0x464d4520 )
1496 *pWMF
>> nUINT32
; // nVersion
1497 *pWMF
>> nEndPos
; // size of metafile
1498 nEndPos
+= nStartPos
;
1500 sal_uInt32 nStrmPos
= pWMF
->Tell(); // checking if nEndPos is valid
1501 pWMF
->Seek( STREAM_SEEK_TO_END
);
1502 if ( pWMF
->Tell() < nEndPos
)
1503 nEndPos
= pWMF
->Tell();
1504 pWMF
->Seek( nStrmPos
);
1506 *pWMF
>> nRecordCount
;
1508 if ( !nRecordCount
)
1511 pWMF
->SeekRel( 0xc );
1513 sal_Int32 nPixX
, nPixY
, nMillX
, nMillY
;
1514 *pWMF
>> nPalEntries
>> nPixX
>> nPixY
>> nMillX
>> nMillY
;
1516 pOut
->SetrclFrame( rclFrame
);
1517 pOut
->SetrclBounds( rclBounds
);
1518 pOut
->SetRefPix( Size( nPixX
, nPixY
) );
1519 pOut
->SetRefMill( Size( nMillX
, nMillY
) );
1521 pWMF
->Seek( nStartPos
+ nHeaderSize
);
1525 //-----------------------------------------------------------------------------------
1527 Rectangle
EnhWMFReader::ReadRectangle( INT32 x1
, INT32 y1
, INT32 x2
, INT32 y2
)
1529 Point
aTL ( Point( x1
, y1
) );
1530 Point
aBR( Point( --x2
, --y2
) );
1531 return Rectangle( aTL
, aBR
);
1534 EnhWMFReader::~EnhWMFReader()