mfplat: Implement MFCreatePathFromURL().
[wine.git] / tools / winedump / mf.c
blobdac8be200af51a4f4c178cfc6286cc973c0f6977
1 /*
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
21 #include "config.h"
23 #include "winedump.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
28 #define META_EOF 0
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;
49 ptr = PRD(offset, 6);
50 if (!ptr)
51 return -1;
53 /* METAHEADER */
54 if (offset == 0)
56 type = read_word(ptr);
57 /* mtHeaderSize is in words */
58 size = read_word(ptr + 2) * 2;
60 /* METARECORD */
61 else
63 /* rdSize is in words */
64 size = read_int(ptr) * 2;
65 type = read_word(ptr + 4);
68 #define MRCASE(x) \
69 case x: \
70 printf("%-20s %08x\n", #x, size); \
71 break
73 switch (type)
75 case METAFILE_MEMORY:
76 case METAFILE_DISK:
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);
85 break;
87 MRCASE(META_SETBKCOLOR);
88 MRCASE(META_SETBKMODE);
89 MRCASE(META_SETMAPMODE);
90 MRCASE(META_SETROP2);
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);
105 MRCASE(META_LINETO);
106 MRCASE(META_MOVETO);
107 MRCASE(META_EXCLUDECLIPRECT);
108 MRCASE(META_INTERSECTCLIPRECT);
109 MRCASE(META_ARC);
110 MRCASE(META_ELLIPSE);
111 MRCASE(META_FLOODFILL);
112 MRCASE(META_PIE);
113 MRCASE(META_RECTANGLE);
114 MRCASE(META_ROUNDRECT);
115 MRCASE(META_PATBLT);
116 MRCASE(META_SAVEDC);
117 MRCASE(META_SETPIXEL);
118 MRCASE(META_OFFSETCLIPRGN);
119 MRCASE(META_TEXTOUT);
120 MRCASE(META_BITBLT);
121 MRCASE(META_STRETCHBLT);
122 MRCASE(META_POLYGON);
123 MRCASE(META_POLYLINE);
124 MRCASE(META_ESCAPE);
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);
134 MRCASE(META_CHORD);
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);
154 MRCASE(META_ENDDOC);
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);
167 MRCASE(META_EOF);
169 default:
170 printf("%u %08x\n", type, size);
171 break;
174 #undef MRCASE
176 if ((size < 6) || (size % 2))
177 return -1;
179 /* METARECORD */
180 if (offset)
182 size -= 6;
183 offset += 6;
186 for (i = 0; i < size; i += 2)
188 if (i % 16 == 0)
189 printf(" ");
190 if (!(ptr = PRD(offset, 2)))
191 return -1;
192 offset += 2;
193 printf("%04x ", read_word(ptr));
194 if ((i % 16 == 14) || (i + 2 == size))
195 printf("\n");
198 return 0;
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))
209 return SIG_MF;
210 return SIG_UNKNOWN;
213 void mf_dump(void)
215 offset = 0;
216 while (!dump_mfrecord())