2 * Dump an Enhanced Meta File
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
38 #include "gdiplusenums.h"
46 } EmfPlusRecordHeader
;
48 static const char *debugstr_wn(const WCHAR
*wstr
, unsigned int n
)
54 if (!wstr
) return "(null)";
59 while (i
< n
&& i
< sizeof(buf
) - 2 && wstr
[i
])
61 if (wstr
[i
] < 127) *p
++ = wstr
[i
];
70 static unsigned int read_int(const unsigned char *buffer
)
78 #define EMRCASE(x) case x: printf("%-20s %08x\n", #x, length); break
79 #define EMRPLUSCASE(x) case x: printf(" %-20s %04x %08x %08x\n", #x, header->Flags, header->Size, header->DataSize); break
81 static unsigned offset
= 0;
83 static int dump_emfrecord(void)
85 const unsigned char* ptr
;
86 unsigned int type
, length
, i
;
92 length
= read_int(ptr
+ 4);
97 EMRCASE(EMR_POLYBEZIER
);
99 EMRCASE(EMR_POLYLINE
);
100 EMRCASE(EMR_POLYBEZIERTO
);
101 EMRCASE(EMR_POLYLINETO
);
102 EMRCASE(EMR_POLYPOLYLINE
);
103 EMRCASE(EMR_POLYPOLYGON
);
104 EMRCASE(EMR_SETWINDOWEXTEX
);
105 EMRCASE(EMR_SETWINDOWORGEX
);
106 EMRCASE(EMR_SETVIEWPORTEXTEX
);
107 EMRCASE(EMR_SETVIEWPORTORGEX
);
108 EMRCASE(EMR_SETBRUSHORGEX
);
110 EMRCASE(EMR_SETPIXELV
);
111 EMRCASE(EMR_SETMAPPERFLAGS
);
112 EMRCASE(EMR_SETMAPMODE
);
113 EMRCASE(EMR_SETBKMODE
);
114 EMRCASE(EMR_SETPOLYFILLMODE
);
115 EMRCASE(EMR_SETROP2
);
116 EMRCASE(EMR_SETSTRETCHBLTMODE
);
117 EMRCASE(EMR_SETTEXTALIGN
);
118 EMRCASE(EMR_SETCOLORADJUSTMENT
);
119 EMRCASE(EMR_SETTEXTCOLOR
);
120 EMRCASE(EMR_SETBKCOLOR
);
121 EMRCASE(EMR_OFFSETCLIPRGN
);
122 EMRCASE(EMR_MOVETOEX
);
123 EMRCASE(EMR_SETMETARGN
);
124 EMRCASE(EMR_EXCLUDECLIPRECT
);
126 case EMR_INTERSECTCLIPRECT
:
128 const EMRINTERSECTCLIPRECT
*clip
= PRD(offset
, sizeof(*clip
));
130 printf("%-20s %08x\n", "EMR_INTERSECTCLIPRECT", length
);
131 printf("rect %d,%d - %d, %d\n",
132 clip
->rclClip
.left
, clip
->rclClip
.top
,
133 clip
->rclClip
.right
, clip
->rclClip
.bottom
);
137 EMRCASE(EMR_SCALEVIEWPORTEXTEX
);
138 EMRCASE(EMR_SCALEWINDOWEXTEX
);
140 EMRCASE(EMR_RESTOREDC
);
141 EMRCASE(EMR_SETWORLDTRANSFORM
);
142 EMRCASE(EMR_MODIFYWORLDTRANSFORM
);
143 EMRCASE(EMR_SELECTOBJECT
);
144 EMRCASE(EMR_CREATEPEN
);
145 EMRCASE(EMR_CREATEBRUSHINDIRECT
);
146 EMRCASE(EMR_DELETEOBJECT
);
147 EMRCASE(EMR_ANGLEARC
);
148 EMRCASE(EMR_ELLIPSE
);
149 EMRCASE(EMR_RECTANGLE
);
150 EMRCASE(EMR_ROUNDRECT
);
154 EMRCASE(EMR_SELECTPALETTE
);
155 EMRCASE(EMR_CREATEPALETTE
);
156 EMRCASE(EMR_SETPALETTEENTRIES
);
157 EMRCASE(EMR_RESIZEPALETTE
);
158 EMRCASE(EMR_REALIZEPALETTE
);
159 EMRCASE(EMR_EXTFLOODFILL
);
162 EMRCASE(EMR_POLYDRAW
);
163 EMRCASE(EMR_SETARCDIRECTION
);
164 EMRCASE(EMR_SETMITERLIMIT
);
165 EMRCASE(EMR_BEGINPATH
);
166 EMRCASE(EMR_ENDPATH
);
167 EMRCASE(EMR_CLOSEFIGURE
);
168 EMRCASE(EMR_FILLPATH
);
169 EMRCASE(EMR_STROKEANDFILLPATH
);
170 EMRCASE(EMR_STROKEPATH
);
171 EMRCASE(EMR_FLATTENPATH
);
172 EMRCASE(EMR_WIDENPATH
);
173 EMRCASE(EMR_SELECTCLIPPATH
);
174 EMRCASE(EMR_ABORTPATH
);
178 printf("%-20s %08x\n", "EMR_GDICOMMENT", length
);
180 /* Handle EMF+ records */
181 if (length
>= 16 && !memcmp((char*)PRD(offset
+ 12, sizeof(unsigned int)), "EMF+", 4))
183 const EmfPlusRecordHeader
*header
;
184 const unsigned int *data_size
;
188 data_size
= PRD(offset
, sizeof(*data_size
));
189 printf("data size = %x\n", *data_size
);
193 while (length
>= sizeof(*header
))
195 header
= PRD(offset
, sizeof(*header
));
198 EMRPLUSCASE(EmfPlusRecordTypeInvalid
);
199 EMRPLUSCASE(EmfPlusRecordTypeHeader
);
200 EMRPLUSCASE(EmfPlusRecordTypeEndOfFile
);
201 EMRPLUSCASE(EmfPlusRecordTypeComment
);
202 EMRPLUSCASE(EmfPlusRecordTypeGetDC
);
203 EMRPLUSCASE(EmfPlusRecordTypeMultiFormatStart
);
204 EMRPLUSCASE(EmfPlusRecordTypeMultiFormatSection
);
205 EMRPLUSCASE(EmfPlusRecordTypeMultiFormatEnd
);
206 EMRPLUSCASE(EmfPlusRecordTypeObject
);
207 EMRPLUSCASE(EmfPlusRecordTypeClear
);
208 EMRPLUSCASE(EmfPlusRecordTypeFillRects
);
209 EMRPLUSCASE(EmfPlusRecordTypeDrawRects
);
210 EMRPLUSCASE(EmfPlusRecordTypeFillPolygon
);
211 EMRPLUSCASE(EmfPlusRecordTypeDrawLines
);
212 EMRPLUSCASE(EmfPlusRecordTypeFillEllipse
);
213 EMRPLUSCASE(EmfPlusRecordTypeDrawEllipse
);
214 EMRPLUSCASE(EmfPlusRecordTypeFillPie
);
215 EMRPLUSCASE(EmfPlusRecordTypeDrawPie
);
216 EMRPLUSCASE(EmfPlusRecordTypeDrawArc
);
217 EMRPLUSCASE(EmfPlusRecordTypeFillRegion
);
218 EMRPLUSCASE(EmfPlusRecordTypeFillPath
);
219 EMRPLUSCASE(EmfPlusRecordTypeDrawPath
);
220 EMRPLUSCASE(EmfPlusRecordTypeFillClosedCurve
);
221 EMRPLUSCASE(EmfPlusRecordTypeDrawClosedCurve
);
222 EMRPLUSCASE(EmfPlusRecordTypeDrawCurve
);
223 EMRPLUSCASE(EmfPlusRecordTypeDrawBeziers
);
224 EMRPLUSCASE(EmfPlusRecordTypeDrawImage
);
225 EMRPLUSCASE(EmfPlusRecordTypeDrawImagePoints
);
226 EMRPLUSCASE(EmfPlusRecordTypeDrawString
);
227 EMRPLUSCASE(EmfPlusRecordTypeSetRenderingOrigin
);
228 EMRPLUSCASE(EmfPlusRecordTypeSetAntiAliasMode
);
229 EMRPLUSCASE(EmfPlusRecordTypeSetTextRenderingHint
);
230 EMRPLUSCASE(EmfPlusRecordTypeSetTextContrast
);
231 EMRPLUSCASE(EmfPlusRecordTypeSetInterpolationMode
);
232 EMRPLUSCASE(EmfPlusRecordTypeSetPixelOffsetMode
);
233 EMRPLUSCASE(EmfPlusRecordTypeSetCompositingMode
);
234 EMRPLUSCASE(EmfPlusRecordTypeSetCompositingQuality
);
235 EMRPLUSCASE(EmfPlusRecordTypeSave
);
236 EMRPLUSCASE(EmfPlusRecordTypeRestore
);
237 EMRPLUSCASE(EmfPlusRecordTypeBeginContainer
);
238 EMRPLUSCASE(EmfPlusRecordTypeBeginContainerNoParams
);
239 EMRPLUSCASE(EmfPlusRecordTypeEndContainer
);
240 EMRPLUSCASE(EmfPlusRecordTypeSetWorldTransform
);
241 EMRPLUSCASE(EmfPlusRecordTypeResetWorldTransform
);
242 EMRPLUSCASE(EmfPlusRecordTypeMultiplyWorldTransform
);
243 EMRPLUSCASE(EmfPlusRecordTypeTranslateWorldTransform
);
244 EMRPLUSCASE(EmfPlusRecordTypeScaleWorldTransform
);
245 EMRPLUSCASE(EmfPlusRecordTypeRotateWorldTransform
);
246 EMRPLUSCASE(EmfPlusRecordTypeSetPageTransform
);
247 EMRPLUSCASE(EmfPlusRecordTypeResetClip
);
248 EMRPLUSCASE(EmfPlusRecordTypeSetClipRect
);
249 EMRPLUSCASE(EmfPlusRecordTypeSetClipPath
);
250 EMRPLUSCASE(EmfPlusRecordTypeSetClipRegion
);
251 EMRPLUSCASE(EmfPlusRecordTypeOffsetClip
);
252 EMRPLUSCASE(EmfPlusRecordTypeDrawDriverString
);
253 EMRPLUSCASE(EmfPlusRecordTypeStrokeFillPath
);
254 EMRPLUSCASE(EmfPlusRecordTypeSerializableObject
);
255 EMRPLUSCASE(EmfPlusRecordTypeSetTSGraphics
);
256 EMRPLUSCASE(EmfPlusRecordTypeSetTSClip
);
257 EMRPLUSCASE(EmfPlusRecordTotal
);
260 printf(" unknown EMF+ record %x %04x %08x\n", header
->Type
, header
->Flags
, header
->Size
);
264 if (length
<sizeof(*header
) || header
->Size
%4)
267 length
-= sizeof(*header
);
268 offset
+= sizeof(*header
);
270 for (i
=0; i
<header
->Size
-sizeof(*header
); i
+=4)
274 if (!(ptr
= PRD(offset
, 4))) return -1;
277 printf("%08x ", read_int(ptr
));
278 if ((i
% 16 == 12) || (i
+ 4 == header
->Size
- sizeof(*header
)))
289 EMRCASE(EMR_FILLRGN
);
290 EMRCASE(EMR_FRAMERGN
);
291 EMRCASE(EMR_INVERTRGN
);
292 EMRCASE(EMR_PAINTRGN
);
294 case EMR_EXTSELECTCLIPRGN
:
296 const EMREXTSELECTCLIPRGN
*clip
= PRD(offset
, sizeof(*clip
));
297 const RGNDATA
*data
= (const RGNDATA
*)clip
->RgnData
;
298 DWORD i
, rc_count
= 0;
301 if (length
>= sizeof(*clip
) + sizeof(*data
))
302 rc_count
= data
->rdh
.nCount
;
304 printf("%-20s %08x\n", "EMR_EXTSELECTCLIPRGN", length
);
305 printf("mode %d, rects %d\n", clip
->iMode
, rc_count
);
306 for (i
= 0, rc
= (const RECT
*)data
->Buffer
; i
< rc_count
; i
++, rc
++)
307 printf(" (%d,%d)-(%d,%d)", rc
->left
, rc
->top
, rc
->right
, rc
->bottom
);
308 if (rc_count
!= 0) printf("\n");
313 EMRCASE(EMR_STRETCHBLT
);
314 EMRCASE(EMR_MASKBLT
);
316 EMRCASE(EMR_SETDIBITSTODEVICE
);
317 EMRCASE(EMR_STRETCHDIBITS
);
319 case EMR_EXTCREATEFONTINDIRECTW
:
321 const EMREXTCREATEFONTINDIRECTW
*pf
= PRD(offset
, sizeof(*pf
));
322 const LOGFONTW
*plf
= &pf
->elfw
.elfLogFont
;
324 printf("%-20s %08x\n", "EMR_EXTCREATEFONTINDIRECTW", length
);
325 printf("(%d %d %d %d %x out %d clip %x quality %d charset %d) %s %s %s %s\n",
326 plf
->lfHeight
, plf
->lfWidth
,
327 plf
->lfEscapement
, plf
->lfOrientation
,
328 plf
->lfPitchAndFamily
,
329 plf
->lfOutPrecision
, plf
->lfClipPrecision
,
330 plf
->lfQuality
, plf
->lfCharSet
,
331 debugstr_wn(plf
->lfFaceName
, LF_FACESIZE
),
332 plf
->lfWeight
> 400 ? "Bold" : "",
333 plf
->lfItalic
? "Italic" : "",
334 plf
->lfUnderline
? "Underline" : "");
338 EMRCASE(EMR_EXTTEXTOUTA
);
340 case EMR_EXTTEXTOUTW
:
342 const EMREXTTEXTOUTW
*etoW
= PRD(offset
, sizeof(*etoW
));
344 printf("%-20s %08x\n", "EMR_EXTTEXTOUTW", length
);
345 printf("pt (%d,%d) rect (%d,%d - %d,%d) flags %#x, %s\n",
346 etoW
->emrtext
.ptlReference
.x
, etoW
->emrtext
.ptlReference
.y
,
347 etoW
->emrtext
.rcl
.left
, etoW
->emrtext
.rcl
.top
,
348 etoW
->emrtext
.rcl
.right
, etoW
->emrtext
.rcl
.bottom
,
349 etoW
->emrtext
.fOptions
,
350 debugstr_wn((LPCWSTR
)((const BYTE
*)etoW
+ etoW
->emrtext
.offString
), etoW
->emrtext
.nChars
));
354 EMRCASE(EMR_POLYBEZIER16
);
355 EMRCASE(EMR_POLYGON16
);
356 EMRCASE(EMR_POLYLINE16
);
357 EMRCASE(EMR_POLYBEZIERTO16
);
358 EMRCASE(EMR_POLYLINETO16
);
359 EMRCASE(EMR_POLYPOLYLINE16
);
360 EMRCASE(EMR_POLYPOLYGON16
);
361 EMRCASE(EMR_POLYDRAW16
);
362 EMRCASE(EMR_CREATEMONOBRUSH
);
363 EMRCASE(EMR_CREATEDIBPATTERNBRUSHPT
);
364 EMRCASE(EMR_EXTCREATEPEN
);
365 EMRCASE(EMR_POLYTEXTOUTA
);
366 EMRCASE(EMR_POLYTEXTOUTW
);
367 EMRCASE(EMR_SETICMMODE
);
368 EMRCASE(EMR_CREATECOLORSPACE
);
369 EMRCASE(EMR_SETCOLORSPACE
);
370 EMRCASE(EMR_DELETECOLORSPACE
);
371 EMRCASE(EMR_GLSRECORD
);
372 EMRCASE(EMR_GLSBOUNDEDRECORD
);
373 EMRCASE(EMR_PIXELFORMAT
);
374 EMRCASE(EMR_DRAWESCAPE
);
375 EMRCASE(EMR_EXTESCAPE
);
376 EMRCASE(EMR_STARTDOC
);
377 EMRCASE(EMR_SMALLTEXTOUT
);
378 EMRCASE(EMR_FORCEUFIMAPPING
);
379 EMRCASE(EMR_NAMEDESCAPE
);
380 EMRCASE(EMR_COLORCORRECTPALETTE
);
381 EMRCASE(EMR_SETICMPROFILEA
);
382 EMRCASE(EMR_SETICMPROFILEW
);
383 EMRCASE(EMR_ALPHABLEND
);
384 EMRCASE(EMR_SETLAYOUT
);
385 EMRCASE(EMR_TRANSPARENTBLT
);
386 EMRCASE(EMR_RESERVED_117
);
387 EMRCASE(EMR_GRADIENTFILL
);
388 EMRCASE(EMR_SETLINKEDUFI
);
389 EMRCASE(EMR_SETTEXTJUSTIFICATION
);
390 EMRCASE(EMR_COLORMATCHTOTARGETW
);
391 EMRCASE(EMR_CREATECOLORSPACEW
);
394 printf("%u %08x\n", type
, length
);
398 if ( (length
< 8) || (length
% 4) )
405 for(i
=0; i
<length
; i
+=4)
409 if (!(ptr
= PRD(offset
, 4))) return -1;
411 printf("%08x ", read_int(ptr
));
412 if ( (i
% 16 == 12) || (i
+ 4 == length
))
419 enum FileSig
get_kind_emf(void)
421 const ENHMETAHEADER
* hdr
;
423 hdr
= PRD(0, sizeof(*hdr
));
424 if (hdr
&& hdr
->iType
== EMR_HEADER
&& hdr
->dSignature
== ENHMETA_SIGNATURE
)
432 while (!dump_emfrecord());