2 * Dump a Windows Metafile
4 * Copyright 2021 Zhiyi Zhang for CodeWeavers
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
29 #define METAFILE_MEMORY 1
30 #define METAFILE_DISK 2
32 static unsigned offset
= 0;
34 static unsigned short read_word(const unsigned char *buffer
)
36 return buffer
[0] + (buffer
[1] << 8);
39 static unsigned int read_int(const unsigned char *buffer
)
41 return buffer
[0] + (buffer
[1] << 8) + (buffer
[2] << 16) + (buffer
[3] << 24);
44 static int dump_mfrecord(void)
46 unsigned int type
, size
, i
;
47 const unsigned char *ptr
;
56 type
= read_word(ptr
);
57 /* mtHeaderSize is in words */
58 size
= read_word(ptr
+ 2) * 2;
63 /* rdSize is in words */
64 size
= read_int(ptr
) * 2;
65 type
= read_word(ptr
+ 4);
70 printf("%-20s %08x\n", #x, size); \
78 const METAHEADER
*header
= PRD(offset
, sizeof(*header
));
80 printf("%-20s %08x\n", "METAHEADER", size
);
81 printf("type %d header_size %#x version %#x size %#x object_count %d max_record_size %#x "
82 "parameter_count %d\n",
83 header
->mtType
, header
->mtHeaderSize
* 2, header
->mtVersion
, (UINT
)header
->mtSize
* 2,
84 header
->mtNoObjects
, (UINT
)header
->mtMaxRecord
* 2, header
->mtNoParameters
);
87 MRCASE(META_SETBKCOLOR
);
88 MRCASE(META_SETBKMODE
);
89 MRCASE(META_SETMAPMODE
);
91 MRCASE(META_SETRELABS
);
92 MRCASE(META_SETPOLYFILLMODE
);
93 MRCASE(META_SETSTRETCHBLTMODE
);
94 MRCASE(META_SETTEXTCHAREXTRA
);
95 MRCASE(META_SETTEXTCOLOR
);
96 MRCASE(META_SETTEXTJUSTIFICATION
);
97 MRCASE(META_SETWINDOWORG
);
98 MRCASE(META_SETWINDOWEXT
);
99 MRCASE(META_SETVIEWPORTORG
);
100 MRCASE(META_SETVIEWPORTEXT
);
101 MRCASE(META_OFFSETWINDOWORG
);
102 MRCASE(META_SCALEWINDOWEXT
);
103 MRCASE(META_OFFSETVIEWPORTORG
);
104 MRCASE(META_SCALEVIEWPORTEXT
);
107 MRCASE(META_EXCLUDECLIPRECT
);
108 MRCASE(META_INTERSECTCLIPRECT
);
110 MRCASE(META_ELLIPSE
);
111 MRCASE(META_FLOODFILL
);
113 MRCASE(META_RECTANGLE
);
114 MRCASE(META_ROUNDRECT
);
117 MRCASE(META_SETPIXEL
);
118 MRCASE(META_OFFSETCLIPRGN
);
119 MRCASE(META_TEXTOUT
);
121 MRCASE(META_STRETCHBLT
);
122 MRCASE(META_POLYGON
);
123 MRCASE(META_POLYLINE
);
125 MRCASE(META_RESTOREDC
);
126 MRCASE(META_FILLREGION
);
127 MRCASE(META_FRAMEREGION
);
128 MRCASE(META_INVERTREGION
);
129 MRCASE(META_PAINTREGION
);
130 MRCASE(META_SELECTCLIPREGION
);
131 MRCASE(META_SELECTOBJECT
);
132 MRCASE(META_SETTEXTALIGN
);
133 MRCASE(META_DRAWTEXT
);
135 MRCASE(META_SETMAPPERFLAGS
);
136 MRCASE(META_EXTTEXTOUT
);
137 MRCASE(META_SETDIBTODEV
);
138 MRCASE(META_SELECTPALETTE
);
139 MRCASE(META_REALIZEPALETTE
);
140 MRCASE(META_ANIMATEPALETTE
);
141 MRCASE(META_SETPALENTRIES
);
142 MRCASE(META_POLYPOLYGON
);
143 MRCASE(META_RESIZEPALETTE
);
144 MRCASE(META_DIBBITBLT
);
145 MRCASE(META_DIBSTRETCHBLT
);
146 MRCASE(META_DIBCREATEPATTERNBRUSH
);
147 MRCASE(META_STRETCHDIB
);
148 MRCASE(META_EXTFLOODFILL
);
149 MRCASE(META_RESETDC
);
150 MRCASE(META_STARTDOC
);
151 MRCASE(META_STARTPAGE
);
152 MRCASE(META_ENDPAGE
);
153 MRCASE(META_ABORTDOC
);
155 MRCASE(META_SETLAYOUT
);
156 MRCASE(META_DELETEOBJECT
);
157 MRCASE(META_CREATEPALETTE
);
158 MRCASE(META_CREATEBRUSH
);
159 MRCASE(META_CREATEPATTERNBRUSH
);
160 MRCASE(META_CREATEPENINDIRECT
);
161 MRCASE(META_CREATEFONTINDIRECT
);
162 MRCASE(META_CREATEBRUSHINDIRECT
);
163 MRCASE(META_CREATEBITMAPINDIRECT
);
164 MRCASE(META_CREATEBITMAP
);
165 MRCASE(META_CREATEREGION
);
166 MRCASE(META_UNKNOWN
);
170 printf("%u %08x\n", type
, size
);
176 if ((size
< 6) || (size
% 2))
186 for (i
= 0; i
< size
; i
+= 2)
190 if (!(ptr
= PRD(offset
, 2)))
193 printf("%04x ", read_word(ptr
));
194 if ((i
% 16 == 14) || (i
+ 2 == size
))
201 enum FileSig
get_kind_mf(void)
203 const METAHEADER
*hdr
;
205 hdr
= PRD(0, sizeof(*hdr
));
206 if (hdr
&& (hdr
->mtType
== METAFILE_MEMORY
|| hdr
->mtType
== METAFILE_DISK
)
207 && hdr
->mtHeaderSize
== sizeof(METAHEADER
) / sizeof(WORD
)
208 && (hdr
->mtVersion
== 0x0100 || hdr
->mtVersion
== 0x0300))
216 while (!dump_mfrecord())