Release 1.4-rc1.
[wine/multimedia.git] / tools / winedump / emf.c
blob68f5b41e810b2653f4d0b460d37d89e546b06572
1 /*
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
21 #include "config.h"
22 #include "wine/port.h"
23 #include "winedump.h"
25 #include <stdio.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
31 #endif
32 #include <fcntl.h>
33 #include <stdarg.h>
35 #include "windef.h"
36 #include "winbase.h"
37 #include "wingdi.h"
39 static const char *debugstr_wn(const WCHAR *wstr, unsigned int n)
41 static char buf[80];
42 char *p;
43 unsigned int i;
45 if (!wstr) return "(null)";
47 i = 0;
48 p = buf;
49 *p++ = '\"';
50 while (i < n && i < sizeof(buf) - 2 && wstr[i])
52 if (wstr[i] < 127) *p++ = wstr[i];
53 else *p++ = '.';
54 i++;
56 *p++ = '\"';
57 *p = 0;
58 return buf;
61 static unsigned int read_int(const unsigned char *buffer)
63 return buffer[0]
64 + (buffer[1]<<8)
65 + (buffer[2]<<16)
66 + (buffer[3]<<24);
69 #define EMRCASE(x) case x: printf("%-20s %08x\n", #x, length); break
71 static unsigned offset = 0;
73 static int dump_emfrecord(void)
75 const unsigned char* ptr;
76 unsigned int type, length, i;
78 ptr = PRD(offset, 8);
79 if (!ptr) return -1;
81 type = read_int(ptr);
82 length = read_int(ptr + 4);
84 switch(type)
86 EMRCASE(EMR_HEADER);
87 EMRCASE(EMR_POLYBEZIER);
88 EMRCASE(EMR_POLYGON);
89 EMRCASE(EMR_POLYLINE);
90 EMRCASE(EMR_POLYBEZIERTO);
91 EMRCASE(EMR_POLYLINETO);
92 EMRCASE(EMR_POLYPOLYLINE);
93 EMRCASE(EMR_POLYPOLYGON);
94 EMRCASE(EMR_SETWINDOWEXTEX);
95 EMRCASE(EMR_SETWINDOWORGEX);
96 EMRCASE(EMR_SETVIEWPORTEXTEX);
97 EMRCASE(EMR_SETVIEWPORTORGEX);
98 EMRCASE(EMR_SETBRUSHORGEX);
99 EMRCASE(EMR_EOF);
100 EMRCASE(EMR_SETPIXELV);
101 EMRCASE(EMR_SETMAPPERFLAGS);
102 EMRCASE(EMR_SETMAPMODE);
103 EMRCASE(EMR_SETBKMODE);
104 EMRCASE(EMR_SETPOLYFILLMODE);
105 EMRCASE(EMR_SETROP2);
106 EMRCASE(EMR_SETSTRETCHBLTMODE);
107 EMRCASE(EMR_SETTEXTALIGN);
108 EMRCASE(EMR_SETCOLORADJUSTMENT);
109 EMRCASE(EMR_SETTEXTCOLOR);
110 EMRCASE(EMR_SETBKCOLOR);
111 EMRCASE(EMR_OFFSETCLIPRGN);
112 EMRCASE(EMR_MOVETOEX);
113 EMRCASE(EMR_SETMETARGN);
114 EMRCASE(EMR_EXCLUDECLIPRECT);
116 case EMR_INTERSECTCLIPRECT:
118 const EMRINTERSECTCLIPRECT *clip = PRD(offset, sizeof(*clip));
120 printf("%-20s %08x\n", "EMR_INTERSECTCLIPRECT", length);
121 printf("rect %d,%d - %d, %d\n",
122 clip->rclClip.left, clip->rclClip.top,
123 clip->rclClip.right, clip->rclClip.bottom);
124 break;
127 EMRCASE(EMR_SCALEVIEWPORTEXTEX);
128 EMRCASE(EMR_SCALEWINDOWEXTEX);
129 EMRCASE(EMR_SAVEDC);
130 EMRCASE(EMR_RESTOREDC);
131 EMRCASE(EMR_SETWORLDTRANSFORM);
132 EMRCASE(EMR_MODIFYWORLDTRANSFORM);
133 EMRCASE(EMR_SELECTOBJECT);
134 EMRCASE(EMR_CREATEPEN);
135 EMRCASE(EMR_CREATEBRUSHINDIRECT);
136 EMRCASE(EMR_DELETEOBJECT);
137 EMRCASE(EMR_ANGLEARC);
138 EMRCASE(EMR_ELLIPSE);
139 EMRCASE(EMR_RECTANGLE);
140 EMRCASE(EMR_ROUNDRECT);
141 EMRCASE(EMR_ARC);
142 EMRCASE(EMR_CHORD);
143 EMRCASE(EMR_PIE);
144 EMRCASE(EMR_SELECTPALETTE);
145 EMRCASE(EMR_CREATEPALETTE);
146 EMRCASE(EMR_SETPALETTEENTRIES);
147 EMRCASE(EMR_RESIZEPALETTE);
148 EMRCASE(EMR_REALIZEPALETTE);
149 EMRCASE(EMR_EXTFLOODFILL);
150 EMRCASE(EMR_LINETO);
151 EMRCASE(EMR_ARCTO);
152 EMRCASE(EMR_POLYDRAW);
153 EMRCASE(EMR_SETARCDIRECTION);
154 EMRCASE(EMR_SETMITERLIMIT);
155 EMRCASE(EMR_BEGINPATH);
156 EMRCASE(EMR_ENDPATH);
157 EMRCASE(EMR_CLOSEFIGURE);
158 EMRCASE(EMR_FILLPATH);
159 EMRCASE(EMR_STROKEANDFILLPATH);
160 EMRCASE(EMR_STROKEPATH);
161 EMRCASE(EMR_FLATTENPATH);
162 EMRCASE(EMR_WIDENPATH);
163 EMRCASE(EMR_SELECTCLIPPATH);
164 EMRCASE(EMR_ABORTPATH);
165 EMRCASE(EMR_GDICOMMENT);
166 EMRCASE(EMR_FILLRGN);
167 EMRCASE(EMR_FRAMERGN);
168 EMRCASE(EMR_INVERTRGN);
169 EMRCASE(EMR_PAINTRGN);
171 case EMR_EXTSELECTCLIPRGN:
173 const EMREXTSELECTCLIPRGN *clip = PRD(offset, sizeof(*clip));
174 const RGNDATA *data = (const RGNDATA *)clip->RgnData;
175 DWORD i, rc_count = 0;
176 const RECT *rc;
178 if (length >= sizeof(*clip) + sizeof(*data))
179 rc_count = data->rdh.nCount;
181 printf("%-20s %08x\n", "EMREXTSELECTCLIPRGN", length);
182 printf("mode %d, rects %d\n", clip->iMode, rc_count);
183 for (i = 0, rc = (const RECT *)data->Buffer; i < rc_count; i++, rc++)
184 printf(" (%d,%d)-(%d,%d)", rc->left, rc->top, rc->right, rc->bottom);
185 if (rc_count != 0) printf("\n");
186 break;
189 EMRCASE(EMR_BITBLT);
190 EMRCASE(EMR_STRETCHBLT);
191 EMRCASE(EMR_MASKBLT);
192 EMRCASE(EMR_PLGBLT);
193 EMRCASE(EMR_SETDIBITSTODEVICE);
194 EMRCASE(EMR_STRETCHDIBITS);
196 case EMR_EXTCREATEFONTINDIRECTW:
198 const EMREXTCREATEFONTINDIRECTW *pf = PRD(offset, sizeof(*pf));
199 const LOGFONTW *plf = &pf->elfw.elfLogFont;
201 printf("%-20s %08x\n", "EMR_EXTCREATEFONTINDIRECTW", length);
202 printf("(%d %d %d %d %x out %d clip %x quality %d charset %d) %s %s %s %s\n",
203 plf->lfHeight, plf->lfWidth,
204 plf->lfEscapement, plf->lfOrientation,
205 plf->lfPitchAndFamily,
206 plf->lfOutPrecision, plf->lfClipPrecision,
207 plf->lfQuality, plf->lfCharSet,
208 debugstr_wn(plf->lfFaceName, LF_FACESIZE),
209 plf->lfWeight > 400 ? "Bold" : "",
210 plf->lfItalic ? "Italic" : "",
211 plf->lfUnderline ? "Underline" : "");
212 break;
215 EMRCASE(EMR_EXTTEXTOUTA);
217 case EMR_EXTTEXTOUTW:
219 const EMREXTTEXTOUTW *etoW = PRD(offset, sizeof(*etoW));
221 printf("%-20s %08x\n", "EMR_EXTTEXTOUTW", length);
222 printf("pt (%d,%d) rect (%d,%d - %d,%d) flags %#x, %s\n",
223 etoW->emrtext.ptlReference.x, etoW->emrtext.ptlReference.y,
224 etoW->emrtext.rcl.left, etoW->emrtext.rcl.top,
225 etoW->emrtext.rcl.right, etoW->emrtext.rcl.bottom,
226 etoW->emrtext.fOptions,
227 debugstr_wn((LPCWSTR)((const BYTE *)etoW + etoW->emrtext.offString), etoW->emrtext.nChars));
228 break;
231 EMRCASE(EMR_POLYBEZIER16);
232 EMRCASE(EMR_POLYGON16);
233 EMRCASE(EMR_POLYLINE16);
234 EMRCASE(EMR_POLYBEZIERTO16);
235 EMRCASE(EMR_POLYLINETO16);
236 EMRCASE(EMR_POLYPOLYLINE16);
237 EMRCASE(EMR_POLYPOLYGON16);
238 EMRCASE(EMR_POLYDRAW16);
239 EMRCASE(EMR_CREATEMONOBRUSH);
240 EMRCASE(EMR_CREATEDIBPATTERNBRUSHPT);
241 EMRCASE(EMR_EXTCREATEPEN);
242 EMRCASE(EMR_POLYTEXTOUTA);
243 EMRCASE(EMR_POLYTEXTOUTW);
244 EMRCASE(EMR_SETICMMODE);
245 EMRCASE(EMR_CREATECOLORSPACE);
246 EMRCASE(EMR_SETCOLORSPACE);
247 EMRCASE(EMR_DELETECOLORSPACE);
248 EMRCASE(EMR_GLSRECORD);
249 EMRCASE(EMR_GLSBOUNDEDRECORD);
250 EMRCASE(EMR_PIXELFORMAT);
251 EMRCASE(EMR_DRAWESCAPE);
252 EMRCASE(EMR_EXTESCAPE);
253 EMRCASE(EMR_STARTDOC);
254 EMRCASE(EMR_SMALLTEXTOUT);
255 EMRCASE(EMR_FORCEUFIMAPPING);
256 EMRCASE(EMR_NAMEDESCAPE);
257 EMRCASE(EMR_COLORCORRECTPALETTE);
258 EMRCASE(EMR_SETICMPROFILEA);
259 EMRCASE(EMR_SETICMPROFILEW);
260 EMRCASE(EMR_ALPHABLEND);
261 EMRCASE(EMR_SETLAYOUT);
262 EMRCASE(EMR_TRANSPARENTBLT);
263 EMRCASE(EMR_RESERVED_117);
264 EMRCASE(EMR_GRADIENTFILL);
265 EMRCASE(EMR_SETLINKEDUFI);
266 EMRCASE(EMR_SETTEXTJUSTIFICATION);
267 EMRCASE(EMR_COLORMATCHTOTARGETW);
268 EMRCASE(EMR_CREATECOLORSPACEW);
270 default:
271 printf("%u %08x\n", type, length);
272 break;
275 if ( (length < 8) || (length % 4) )
276 return -1;
278 length -= 8;
280 offset += 8;
282 for(i=0; i<length; i+=4)
284 if (i%16 == 0)
285 printf(" ");
286 if (!(ptr = PRD(offset, 4))) return -1;
287 offset += 4;
288 printf("%08x ", read_int(ptr));
289 if ( (i % 16 == 12) || (i + 4 == length))
290 printf("\n");
293 return 0;
296 enum FileSig get_kind_emf(void)
298 const ENHMETAHEADER* hdr;
300 hdr = PRD(0, sizeof(*hdr));
301 if (hdr && hdr->iType == EMR_HEADER && hdr->dSignature == ENHMETA_SIGNATURE)
302 return SIG_EMF;
303 return SIG_UNKNOWN;
306 void emf_dump(void)
308 offset = 0;
309 while (!dump_emfrecord());