Remove unnecessary executable bits
[reactos.git] / modules / rostests / winetests / gdi32 / metafile.c
1 /*
2 * Unit tests for metafile functions
3 *
4 * Copyright (c) 2002 Dmitry Timoshkov
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <assert.h>
22 #include <stdio.h>
23 #include <math.h>
24
25 #include "wine/test.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winerror.h"
30
31 #ifndef M_PI
32 #define M_PI 3.14159265358979323846
33 #endif
34
35 static LOGFONTA orig_lf;
36 static BOOL emr_processed = FALSE;
37
38 /* Arbitrarily chosen values for the second co-ordinate of a metafile line */
39 #define LINE_X 55.0f
40 #define LINE_Y 15.0f
41
42 static INT (WINAPI * pGetRelAbs)(HDC, DWORD);
43 static INT (WINAPI * pSetRelAbs)(HDC, INT);
44 static COLORREF (WINAPI *pSetDCBrushColor)(HDC,COLORREF);
45 static COLORREF (WINAPI *pSetDCPenColor)(HDC,COLORREF);
46
47 #define GDI_GET_PROC(func) \
48 p ## func = (void *)GetProcAddress(hGDI, #func); \
49 if(!p ## func) \
50 trace("GetProcAddress(hGDI, \"%s\") failed\n", #func); \
51
52 static void init_function_pointers(void)
53 {
54 HMODULE hGDI;
55
56 pGetRelAbs = NULL;
57 pSetRelAbs = NULL;
58
59 hGDI = GetModuleHandleA("gdi32.dll");
60 assert(hGDI);
61 GDI_GET_PROC(GetRelAbs);
62 GDI_GET_PROC(SetRelAbs);
63 GDI_GET_PROC(SetDCBrushColor);
64 GDI_GET_PROC(SetDCPenColor);
65 }
66
67 static DWORD rgn_rect_count(HRGN hrgn)
68 {
69 DWORD size;
70 RGNDATA *data;
71
72 if (!hrgn) return 0;
73 if (!(size = GetRegionData(hrgn, 0, NULL))) return 0;
74 if (!(data = HeapAlloc(GetProcessHeap(), 0, size))) return 0;
75 GetRegionData(hrgn, size, data);
76 size = data->rdh.nCount;
77 HeapFree(GetProcessHeap(), 0, data);
78 return size;
79 }
80
81 static int CALLBACK eto_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
82 const ENHMETARECORD *emr, int n_objs, LPARAM param)
83 {
84 static int n_record;
85 DWORD i;
86 const INT *dx;
87 INT *orig_dx = (INT *)param;
88 LOGFONTA device_lf;
89 INT ret;
90
91 if(!hdc) return 1;
92
93 PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
94
95 switch (emr->iType)
96 {
97 case EMR_HEADER:
98 ok(GetTextAlign(hdc) == 0, "text align %08x\n", GetTextAlign(hdc));
99 ok(GetBkColor(hdc) == RGB(0xff, 0xff, 0xff), "bk color %08x\n", GetBkColor(hdc));
100 ok(GetTextColor(hdc) == RGB(0x0, 0x0, 0x0), "text color %08x\n", GetTextColor(hdc));
101 ok(GetROP2(hdc) == R2_COPYPEN, "rop %d\n", GetROP2(hdc));
102 ok(GetArcDirection(hdc) == AD_COUNTERCLOCKWISE, "arc dir %d\n", GetArcDirection(hdc));
103 ok(GetPolyFillMode(hdc) == ALTERNATE, "poly fill %d\n", GetPolyFillMode(hdc));
104 ok(GetStretchBltMode(hdc) == BLACKONWHITE, "stretchblt mode %d\n", GetStretchBltMode(hdc));
105
106 /* GetBkMode, GetRelAbs do not get reset to the default value */
107 ok(GetBkMode(hdc) == OPAQUE, "bk mode %d\n", GetBkMode(hdc));
108 if(pSetRelAbs && pGetRelAbs)
109 ok(pGetRelAbs(hdc, 0) == RELATIVE, "relabs %d\n", pGetRelAbs(hdc, 0));
110
111 n_record = 0;
112 break;
113
114 case EMR_EXTTEXTOUTA:
115 {
116 const EMREXTTEXTOUTA *emr_ExtTextOutA = (const EMREXTTEXTOUTA *)emr;
117 dx = (const INT *)((const char *)emr + emr_ExtTextOutA->emrtext.offDx);
118
119 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
120 ok( ret == sizeof(device_lf), "GetObjectA error %d\n", GetLastError());
121
122 /* compare up to lfOutPrecision, other values are not interesting,
123 * and in fact sometimes arbitrary adapted by Win9x.
124 */
125 ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
126 ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
127
128 for(i = 0; i < emr_ExtTextOutA->emrtext.nChars; i++)
129 {
130 ok(orig_dx[i] == dx[i], "pass %d: dx[%d] (%d) didn't match %d\n",
131 n_record, i, dx[i], orig_dx[i]);
132 }
133 n_record++;
134 emr_processed = TRUE;
135 break;
136 }
137
138 case EMR_EXTTEXTOUTW:
139 {
140 const EMREXTTEXTOUTW *emr_ExtTextOutW = (const EMREXTTEXTOUTW *)emr;
141 dx = (const INT *)((const char *)emr + emr_ExtTextOutW->emrtext.offDx);
142
143 SetLastError(0xdeadbeef);
144 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
145 ok( ret == sizeof(device_lf) ||
146 broken(ret == (sizeof(device_lf) - LF_FACESIZE + strlen(device_lf.lfFaceName) + 1)), /* NT4 */
147 "GetObjectA error %d\n", GetLastError());
148
149 /* compare up to lfOutPrecision, other values are not interesting,
150 * and in fact sometimes arbitrary adapted by Win9x.
151 */
152 ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
153 ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
154
155 ok(!emr_ExtTextOutW->rclBounds.left, "emr_ExtTextOutW->rclBounds.left = %d\n",
156 emr_ExtTextOutW->rclBounds.left);
157 ok(emr_ExtTextOutW->rclBounds.right != -1, "emr_ExtTextOutW->rclBounds.right = %d\n",
158 emr_ExtTextOutW->rclBounds.right);
159 ok(emr_ExtTextOutW->rclBounds.bottom != -1, "emr_ExtTextOutW->rclBounds.bottom = %d\n",
160 emr_ExtTextOutW->rclBounds.bottom);
161
162 for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++)
163 {
164 ok(orig_dx[i] == dx[i], "pass %d: dx[%d] (%d) didn't match %d\n",
165 n_record, i, dx[i], orig_dx[i]);
166 }
167 n_record++;
168 emr_processed = TRUE;
169 break;
170 }
171
172 default:
173 break;
174 }
175
176 return 1;
177 }
178
179 static void test_ExtTextOut(void)
180 {
181 HWND hwnd;
182 HDC hdcDisplay, hdcMetafile;
183 HENHMETAFILE hMetafile;
184 HFONT hFont;
185 static const char text[] = "Simple text to test ExtTextOut on metafiles";
186 INT i, len, dx[256];
187 static const RECT rc = { 0, 0, 100, 100 };
188 BOOL ret;
189
190 assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
191
192 /* Win9x doesn't play EMFs on invisible windows */
193 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
194 0, 0, 200, 200, 0, 0, 0, NULL);
195 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
196
197 hdcDisplay = GetDC(hwnd);
198 ok(hdcDisplay != 0, "GetDC error %d\n", GetLastError());
199
200 trace("hdcDisplay %p\n", hdcDisplay);
201
202 SetMapMode(hdcDisplay, MM_TEXT);
203
204 memset(&orig_lf, 0, sizeof(orig_lf));
205
206 orig_lf.lfCharSet = ANSI_CHARSET;
207 orig_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
208 orig_lf.lfWeight = FW_DONTCARE;
209 orig_lf.lfHeight = 7;
210 orig_lf.lfQuality = DEFAULT_QUALITY;
211 lstrcpyA(orig_lf.lfFaceName, "Arial");
212 hFont = CreateFontIndirectA(&orig_lf);
213 ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
214
215 hFont = SelectObject(hdcDisplay, hFont);
216
217 len = lstrlenA(text);
218 for (i = 0; i < len; i++)
219 {
220 ret = GetCharWidthA(hdcDisplay, text[i], text[i], &dx[i]);
221 ok( ret, "GetCharWidthA error %d\n", GetLastError());
222 }
223 hFont = SelectObject(hdcDisplay, hFont);
224
225 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
226 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
227
228 trace("hdcMetafile %p\n", hdcMetafile);
229
230 ok(GetDeviceCaps(hdcMetafile, TECHNOLOGY) == DT_RASDISPLAY,
231 "GetDeviceCaps(TECHNOLOGY) has to return DT_RASDISPLAY for a display based EMF\n");
232
233 hFont = SelectObject(hdcMetafile, hFont);
234
235 /* 1. pass NULL lpDx */
236 ret = ExtTextOutA(hdcMetafile, 0, 0, 0, &rc, text, lstrlenA(text), NULL);
237 ok( ret, "ExtTextOutA error %d\n", GetLastError());
238
239 /* 2. pass custom lpDx */
240 ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
241 ok( ret, "ExtTextOutA error %d\n", GetLastError());
242
243 /* 3. pass NULL lprc */
244 ret = ExtTextOutA(hdcMetafile, 0, 40, 0, NULL, text, lstrlenA(text), NULL);
245 ok( ret, "ExtTextOutA error %d\n", GetLastError());
246
247 /* 4. test with unmatched BeginPath/EndPath calls */
248 ret = BeginPath(hdcMetafile);
249 ok( ret, "BeginPath error %d\n", GetLastError());
250 ret = BeginPath(hdcMetafile);
251 ok( ret, "BeginPath error %d\n", GetLastError());
252 ret = EndPath(hdcMetafile);
253 ok( ret, "BeginPath error %d\n", GetLastError());
254 ret = ExtTextOutA(hdcMetafile, 0, 60, 0, NULL, text, lstrlenA(text), NULL);
255 ok( ret, "ExtTextOutA error %d\n", GetLastError());
256
257 hFont = SelectObject(hdcMetafile, hFont);
258 ret = DeleteObject(hFont);
259 ok( ret, "DeleteObject error %d\n", GetLastError());
260
261 hMetafile = CloseEnhMetaFile(hdcMetafile);
262 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
263
264 ok(!GetObjectType(hdcMetafile), "CloseEnhMetaFile has to destroy metafile hdc\n");
265
266 ret = PlayEnhMetaFile(hdcDisplay, hMetafile, &rc);
267 ok( ret, "PlayEnhMetaFile error %d\n", GetLastError());
268
269 SetTextAlign(hdcDisplay, TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING );
270 SetBkColor(hdcDisplay, RGB(0xff, 0, 0));
271 SetTextColor(hdcDisplay, RGB(0, 0xff, 0));
272 SetROP2(hdcDisplay, R2_NOT);
273 SetArcDirection(hdcDisplay, AD_CLOCKWISE);
274 SetPolyFillMode(hdcDisplay, WINDING);
275 SetStretchBltMode(hdcDisplay, HALFTONE);
276
277 if(pSetRelAbs) pSetRelAbs(hdcDisplay, RELATIVE);
278 SetBkMode(hdcDisplay, OPAQUE);
279
280 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, &rc);
281 ok( ret, "EnumEnhMetaFile error %d\n", GetLastError());
282
283 ok( GetTextAlign(hdcDisplay) == (TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING),
284 "text align %08x\n", GetTextAlign(hdcDisplay));
285 ok( GetBkColor(hdcDisplay) == RGB(0xff, 0, 0), "bk color %08x\n", GetBkColor(hdcDisplay));
286 ok( GetTextColor(hdcDisplay) == RGB(0, 0xff, 0), "text color %08x\n", GetTextColor(hdcDisplay));
287 ok( GetROP2(hdcDisplay) == R2_NOT, "rop2 %d\n", GetROP2(hdcDisplay));
288 ok( GetArcDirection(hdcDisplay) == AD_CLOCKWISE, "arc dir %d\n", GetArcDirection(hdcDisplay));
289 ok( GetPolyFillMode(hdcDisplay) == WINDING, "poly fill %d\n", GetPolyFillMode(hdcDisplay));
290 ok( GetStretchBltMode(hdcDisplay) == HALFTONE, "stretchblt mode %d\n", GetStretchBltMode(hdcDisplay));
291
292 ok(emr_processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record\n");
293
294 ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, NULL),
295 "A valid hdc has to require a valid rc\n");
296
297 ok(EnumEnhMetaFile(NULL, hMetafile, eto_emf_enum_proc, dx, NULL),
298 "A null hdc does not require a valid rc\n");
299
300 ret = DeleteEnhMetaFile(hMetafile);
301 ok( ret, "DeleteEnhMetaFile error %d\n", GetLastError());
302 ret = ReleaseDC(hwnd, hdcDisplay);
303 ok( ret, "ReleaseDC error %d\n", GetLastError());
304 DestroyWindow(hwnd);
305 }
306
307 struct eto_scale_test_record
308 {
309 INT graphics_mode;
310 INT map_mode;
311 double ex_scale;
312 double ey_scale;
313 BOOL processed;
314 };
315
316 static int CALLBACK eto_scale_enum_proc(HDC hdc, HANDLETABLE *handle_table,
317 const ENHMETARECORD *emr, int n_objs, LPARAM param)
318 {
319 struct eto_scale_test_record *test = (struct eto_scale_test_record*)param;
320
321 if (emr->iType == EMR_EXTTEXTOUTW)
322 {
323 const EMREXTTEXTOUTW *pExtTextOutW = (const EMREXTTEXTOUTW *)emr;
324 ok(fabs(test->ex_scale - pExtTextOutW->exScale) < 0.001,
325 "Got exScale %f, expected %f\n", pExtTextOutW->exScale, test->ex_scale);
326 ok(fabs(test->ey_scale - pExtTextOutW->eyScale) < 0.001,
327 "Got eyScale %f, expected %f\n", pExtTextOutW->eyScale, test->ey_scale);
328 test->processed = TRUE;
329 }
330
331 return 1;
332 }
333
334 static void test_ExtTextOutScale(void)
335 {
336 const RECT rc = { 0, 0, 100, 100 };
337 const WCHAR str[] = {'a',0 };
338 struct eto_scale_test_record test;
339 HDC hdcDisplay, hdcMetafile;
340 HENHMETAFILE hMetafile;
341 HWND hwnd;
342 SIZE wndext, vportext;
343 int horzSize, vertSize, horzRes, vertRes;
344 int ret;
345 int i;
346
347 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
348 0, 0, 200, 200, 0, 0, 0, NULL);
349 ok(hwnd != 0, "CreateWindowExA failed\n");
350
351 hdcDisplay = GetDC(hwnd);
352 ok(hdcDisplay != 0, "GetDC failed\n");
353
354 horzSize = GetDeviceCaps(hdcDisplay, HORZSIZE);
355 horzRes = GetDeviceCaps(hdcDisplay, HORZRES);
356 vertSize = GetDeviceCaps(hdcDisplay, VERTSIZE);
357 vertRes = GetDeviceCaps(hdcDisplay, VERTRES);
358 ok(horzSize && horzRes && vertSize && vertRes, "GetDeviceCaps failed\n");
359
360 for (i = 0; i < 16; i++)
361 {
362 test.graphics_mode = i / 8 + 1;
363 test.map_mode = i % 8 + 1;
364
365 ret = SetGraphicsMode(hdcDisplay, test.graphics_mode);
366 ok(ret, "SetGraphicsMode failed\n");
367 ret = SetMapMode(hdcDisplay, test.map_mode);
368 ok(ret, "SetMapMode failed\n");
369
370 if ((test.map_mode == MM_ISOTROPIC) || (test.map_mode == MM_ANISOTROPIC))
371 {
372 ret = SetWindowExtEx(hdcDisplay, 1, 1, NULL);
373 ok(ret, "SetWindowExtEx failed\n");
374 ret = SetViewportExtEx(hdcDisplay, -20, -10, NULL);
375 ok(ret, "SetViewportExtEx failed\n");
376 }
377
378 ret = GetViewportExtEx(hdcDisplay, &vportext);
379 ok(ret, "GetViewportExtEx failed\n");
380 ret = GetWindowExtEx(hdcDisplay, &wndext);
381 ok(ret, "GetWindowExtEx failed\n");
382
383 trace("gm %d, mm %d, wnd %d,%d, vp %d,%d horz %d,%d vert %d,%d\n",
384 test.graphics_mode, test.map_mode,
385 wndext.cx, wndext.cy, vportext.cx, vportext.cy,
386 horzSize, horzRes, vertSize, vertRes);
387
388 if (test.graphics_mode == GM_COMPATIBLE)
389 {
390 test.ex_scale = 100.0 * ((FLOAT)horzSize / (FLOAT)horzRes) /
391 ((FLOAT)wndext.cx / (FLOAT)vportext.cx);
392 test.ey_scale = 100.0 * ((FLOAT)vertSize / (FLOAT)vertRes) /
393 ((FLOAT)wndext.cy / (FLOAT)vportext.cy);
394 }
395 else
396 {
397 test.ex_scale = 0.0;
398 test.ey_scale = 0.0;
399 }
400
401 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
402 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
403
404 ret = SetGraphicsMode(hdcMetafile, test.graphics_mode);
405 ok(ret, "SetGraphicsMode failed\n");
406 ret = SetMapMode(hdcMetafile, test.map_mode);
407 ok(ret, "SetMapMode failed\n");
408
409 if ((test.map_mode == MM_ISOTROPIC) || (test.map_mode == MM_ANISOTROPIC))
410 {
411 ret = SetWindowExtEx(hdcMetafile, 1, 1, NULL);
412 ok(ret, "SetWindowExtEx failed\n");
413 ret = SetViewportExtEx(hdcMetafile, -20, -10, NULL);
414 ok(ret, "SetViewportExtEx failed\n");
415 }
416
417 ret = ExtTextOutW(hdcMetafile, 0, 0, 0, 0, str, 1, NULL);
418 ok(ret, "ExtTextOutW failed\n");
419
420 hMetafile = CloseEnhMetaFile(hdcMetafile);
421 ok(hMetafile != 0, "CloseEnhMetaFile failed\n");
422
423 test.processed = 0;
424 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, eto_scale_enum_proc, &test, &rc);
425 ok(ret, "EnumEnhMetaFile failed\n");
426 ok(test.processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTW record\n");
427
428 ret = DeleteEnhMetaFile(hMetafile);
429 ok(ret, "DeleteEnhMetaFile failed\n");
430 }
431
432 ret = ReleaseDC(hwnd, hdcDisplay);
433 ok(ret, "ReleaseDC failed\n");
434 DestroyWindow(hwnd);
435 }
436
437
438 static void check_dc_state(HDC hdc, int restore_no,
439 int wnd_org_x, int wnd_org_y, int wnd_ext_x, int wnd_ext_y,
440 int vp_org_x, int vp_org_y, int vp_ext_x, int vp_ext_y)
441 {
442 BOOL ret;
443 XFORM xform;
444 POINT vp_org, win_org;
445 SIZE vp_size, win_size;
446 FLOAT xscale, yscale, edx, edy;
447
448 SetLastError(0xdeadbeef);
449 ret = GetWorldTransform(hdc, &xform);
450 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) goto win9x_here;
451 ok(ret, "GetWorldTransform error %u\n", GetLastError());
452
453 trace("%d: eM11 %f, eM22 %f, eDx %f, eDy %f\n", restore_no, xform.eM11, xform.eM22, xform.eDx, xform.eDy);
454
455 ok(xform.eM12 == 0.0, "%d: expected eM12 0.0, got %f\n", restore_no, xform.eM12);
456 ok(xform.eM21 == 0.0, "%d: expected eM21 0.0, got %f\n", restore_no, xform.eM21);
457
458 xscale = (FLOAT)vp_ext_x / (FLOAT)wnd_ext_x;
459 trace("x scale %f\n", xscale);
460 ok(fabs(xscale - xform.eM11) < 0.01, "%d: vp_ext_x %d, wnd_ext_cx %d, eM11 %f\n",
461 restore_no, vp_ext_x, wnd_ext_x, xform.eM11);
462
463 yscale = (FLOAT)vp_ext_y / (FLOAT)wnd_ext_y;
464 trace("y scale %f\n", yscale);
465 ok(fabs(yscale - xform.eM22) < 0.01, "%d: vp_ext_y %d, wnd_ext_y %d, eM22 %f\n",
466 restore_no, vp_ext_y, wnd_ext_y, xform.eM22);
467
468 edx = (FLOAT)vp_org_x - xform.eM11 * (FLOAT)wnd_org_x;
469 ok(fabs(edx - xform.eDx) < 0.01, "%d: edx %f != eDx %f\n", restore_no, edx, xform.eDx);
470 edy = (FLOAT)vp_org_y - xform.eM22 * (FLOAT)wnd_org_y;
471 ok(fabs(edy - xform.eDy) < 0.01, "%d: edy %f != eDy %f\n", restore_no, edy, xform.eDy);
472
473 return;
474
475 win9x_here:
476
477 GetWindowOrgEx(hdc, &win_org);
478 GetViewportOrgEx(hdc, &vp_org);
479 GetWindowExtEx(hdc, &win_size);
480 GetViewportExtEx(hdc, &vp_size);
481
482 ok(wnd_org_x == win_org.x, "%d: wnd_org_x: %d != %d\n", restore_no, wnd_org_x, win_org.x);
483 ok(wnd_org_y == win_org.y, "%d: wnd_org_y: %d != %d\n", restore_no, wnd_org_y, win_org.y);
484
485 ok(vp_org_x == vp_org.x, "%d: vport_org_x: %d != %d\n", restore_no, vp_org_x, vp_org.x);
486 ok(vp_org_y == vp_org.y, "%d: vport_org_y: %d != %d\n", restore_no, vp_org_y, vp_org.y);
487
488 ok(wnd_ext_x == win_size.cx, "%d: wnd_ext_x: %d != %d\n", restore_no, wnd_ext_x, win_size.cx);
489 ok(wnd_ext_y == win_size.cy, "%d: wnd_ext_y: %d != %d\n", restore_no, wnd_ext_y, win_size.cy);
490
491 ok(vp_ext_x == vp_size.cx, "%d: vport_ext_x: %d != %d\n", restore_no, vp_ext_x, vp_size.cx);
492 ok(vp_ext_y == vp_size.cy, "%d: vport_ext_y: %d != %d\n", restore_no, vp_ext_y, vp_size.cy);
493 }
494
495 static int CALLBACK savedc_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
496 const ENHMETARECORD *emr, int n_objs, LPARAM param)
497 {
498 BOOL ret;
499 XFORM xform;
500 POINT pt;
501 SIZE size;
502 static int save_state;
503 static int restore_no;
504 static int select_no;
505
506 trace("hdc %p, emr->iType %d, emr->nSize %d, param %p\n",
507 hdc, emr->iType, emr->nSize, (void *)param);
508
509 SetLastError(0xdeadbeef);
510 ret = GetWorldTransform(hdc, &xform);
511 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
512 {
513 ret = GetWindowOrgEx(hdc, &pt);
514 ok(ret, "GetWindowOrgEx error %u\n", GetLastError());
515 trace("window org (%d,%d)\n", pt.x, pt.y);
516 ret = GetViewportOrgEx(hdc, &pt);
517 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
518 trace("vport org (%d,%d)\n", pt.x, pt.y);
519 ret = GetWindowExtEx(hdc, &size);
520 ok(ret, "GetWindowExtEx error %u\n", GetLastError());
521 trace("window ext (%d,%d)\n", size.cx, size.cy);
522 ret = GetViewportExtEx(hdc, &size);
523 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
524 trace("vport ext (%d,%d)\n", size.cx, size.cy);
525 }
526 else
527 {
528 ok(ret, "GetWorldTransform error %u\n", GetLastError());
529 trace("eM11 %f, eM22 %f, eDx %f, eDy %f\n", xform.eM11, xform.eM22, xform.eDx, xform.eDy);
530 }
531
532 PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
533
534 switch (emr->iType)
535 {
536 case EMR_HEADER:
537 {
538 static RECT exp_bounds = { 0, 0, 150, 150 };
539 RECT bounds;
540 const ENHMETAHEADER *emf = (const ENHMETAHEADER *)emr;
541
542 trace("bounds %d,%d-%d,%d, frame %d,%d-%d,%d\n",
543 emf->rclBounds.left, emf->rclBounds.top, emf->rclBounds.right, emf->rclBounds.bottom,
544 emf->rclFrame.left, emf->rclFrame.top, emf->rclFrame.right, emf->rclFrame.bottom);
545 trace("mm %d x %d, device %d x %d\n", emf->szlMillimeters.cx, emf->szlMillimeters.cy,
546 emf->szlDevice.cx, emf->szlDevice.cy);
547
548 SetRect(&bounds, emf->rclBounds.left, emf->rclBounds.top, emf->rclBounds.right, emf->rclBounds.bottom);
549 ok(EqualRect(&bounds, &exp_bounds), "wrong bounds\n");
550
551 save_state = 0;
552 restore_no = 0;
553 select_no = 0;
554 check_dc_state(hdc, restore_no, 0, 0, 1, 1, 0, 0, 1, 1);
555 break;
556 }
557
558 case EMR_LINETO:
559 {
560 const EMRLINETO *line = (const EMRLINETO *)emr;
561 trace("EMR_LINETO %d,%d\n", line->ptl.x, line->ptl.x);
562 break;
563 }
564 case EMR_SETWINDOWORGEX:
565 {
566 const EMRSETWINDOWORGEX *org = (const EMRSETWINDOWORGEX *)emr;
567 trace("EMR_SETWINDOWORGEX: %d,%d\n", org->ptlOrigin.x, org->ptlOrigin.y);
568 break;
569 }
570 case EMR_SETWINDOWEXTEX:
571 {
572 const EMRSETWINDOWEXTEX *ext = (const EMRSETWINDOWEXTEX *)emr;
573 trace("EMR_SETWINDOWEXTEX: %d,%d\n", ext->szlExtent.cx, ext->szlExtent.cy);
574 break;
575 }
576 case EMR_SETVIEWPORTORGEX:
577 {
578 const EMRSETVIEWPORTORGEX *org = (const EMRSETVIEWPORTORGEX *)emr;
579 trace("EMR_SETVIEWPORTORGEX: %d,%d\n", org->ptlOrigin.x, org->ptlOrigin.y);
580 break;
581 }
582 case EMR_SETVIEWPORTEXTEX:
583 {
584 const EMRSETVIEWPORTEXTEX *ext = (const EMRSETVIEWPORTEXTEX *)emr;
585 trace("EMR_SETVIEWPORTEXTEX: %d,%d\n", ext->szlExtent.cx, ext->szlExtent.cy);
586 break;
587 }
588 case EMR_SAVEDC:
589 save_state++;
590 trace("EMR_SAVEDC\n");
591 break;
592
593 case EMR_RESTOREDC:
594 {
595 const EMRRESTOREDC *restoredc = (const EMRRESTOREDC *)emr;
596 trace("EMR_RESTOREDC: %d\n", restoredc->iRelative);
597
598 switch(++restore_no)
599 {
600 case 1:
601 ok(restoredc->iRelative == -1, "first restore %d\n", restoredc->iRelative);
602 check_dc_state(hdc, restore_no, -2, -2, 8192, 8192, 20, 20, 20479, 20478);
603 break;
604 case 2:
605 ok(restoredc->iRelative == -3, "second restore %d\n", restoredc->iRelative);
606 check_dc_state(hdc, restore_no, 0, 0, 16384, 16384, 0, 0, 17873, 17872);
607 break;
608 case 3:
609 ok(restoredc->iRelative == -2, "third restore %d\n", restoredc->iRelative);
610 check_dc_state(hdc, restore_no, -4, -4, 32767, 32767, 40, 40, 3276, 3276);
611 break;
612 }
613 ok(restore_no <= 3, "restore_no %d\n", restore_no);
614 save_state += restoredc->iRelative;
615 break;
616 }
617 case EMR_SELECTOBJECT:
618 {
619 const EMRSELECTOBJECT *selectobj = (const EMRSELECTOBJECT*)emr;
620 trace("EMR_SELECTOBJECT: %x\n",selectobj->ihObject);
621 select_no ++;
622 break;
623 }
624 case EMR_EOF:
625 ok(save_state == 0, "EOF save_state %d\n", save_state);
626 ok(select_no == 3, "Too many/few selects %i\n",select_no);
627 break;
628 }
629
630 SetLastError(0xdeadbeef);
631 ret = GetWorldTransform(hdc, &xform);
632 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
633 {
634 ret = GetWindowOrgEx(hdc, &pt);
635 ok(ret, "GetWindowOrgEx error %u\n", GetLastError());
636 trace("window org (%d,%d)\n", pt.x, pt.y);
637 ret = GetViewportOrgEx(hdc, &pt);
638 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
639 trace("vport org (%d,%d)\n", pt.x, pt.y);
640 ret = GetWindowExtEx(hdc, &size);
641 ok(ret, "GetWindowExtEx error %u\n", GetLastError());
642 trace("window ext (%d,%d)\n", size.cx, size.cy);
643 ret = GetViewportExtEx(hdc, &size);
644 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
645 trace("vport ext (%d,%d)\n", size.cx, size.cy);
646 }
647 else
648 {
649 ok(ret, "GetWorldTransform error %u\n", GetLastError());
650 trace("eM11 %f, eM22 %f, eDx %f, eDy %f\n", xform.eM11, xform.eM22, xform.eDx, xform.eDy);
651 }
652
653 return 1;
654 }
655
656 static void test_SaveDC(void)
657 {
658 HDC hdcMetafile, hdcDisplay;
659 HENHMETAFILE hMetafile;
660 HWND hwnd;
661 int ret;
662 POINT pt;
663 SIZE size;
664 HFONT hFont,hFont2,hFontOld,hFontCheck;
665 static const RECT rc = { 0, 0, 150, 150 };
666
667 /* Win9x doesn't play EMFs on invisible windows */
668 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
669 0, 0, 200, 200, 0, 0, 0, NULL);
670 ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
671
672 hdcDisplay = GetDC(hwnd);
673 ok(hdcDisplay != 0, "GetDC error %d\n", GetLastError());
674
675 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
676 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
677
678 SetMapMode(hdcMetafile, MM_ANISOTROPIC);
679
680 /* Need to write something to the emf, otherwise Windows won't play it back */
681 LineTo(hdcMetafile, 150, 150);
682
683 SetWindowOrgEx(hdcMetafile, 0, 0, NULL);
684 SetViewportOrgEx(hdcMetafile, 0, 0, NULL);
685 SetWindowExtEx(hdcMetafile, 110, 110, NULL );
686 SetViewportExtEx(hdcMetafile, 120, 120, NULL );
687
688 /* Force Win9x to update DC state */
689 SetPixelV(hdcMetafile, 50, 50, 0);
690
691 ret = GetViewportOrgEx(hdcMetafile, &pt);
692 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
693 ok(pt.x == 0,"Expecting ViewportOrg x of 0, got %i\n",pt.x);
694 ret = GetViewportExtEx(hdcMetafile, &size);
695 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
696 ok(size.cx == 120,"Expecting ViewportExt cx of 120, got %i\n",size.cx);
697 ret = SaveDC(hdcMetafile);
698 ok(ret == 1, "ret = %d\n", ret);
699
700 SetWindowOrgEx(hdcMetafile, -1, -1, NULL);
701 SetViewportOrgEx(hdcMetafile, 10, 10, NULL);
702 SetWindowExtEx(hdcMetafile, 150, 150, NULL );
703 SetViewportExtEx(hdcMetafile, 200, 200, NULL );
704
705 /* Force Win9x to update DC state */
706 SetPixelV(hdcMetafile, 50, 50, 0);
707
708 ret = GetViewportOrgEx(hdcMetafile, &pt);
709 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
710 ok(pt.x == 10,"Expecting ViewportOrg x of 10, got %i\n",pt.x);
711 ret = GetViewportExtEx(hdcMetafile, &size);
712 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
713 ok(size.cx == 200,"Expecting ViewportExt cx of 200, got %i\n",size.cx);
714 ret = SaveDC(hdcMetafile);
715 ok(ret == 2, "ret = %d\n", ret);
716
717 SetWindowOrgEx(hdcMetafile, -2, -2, NULL);
718 SetViewportOrgEx(hdcMetafile, 20, 20, NULL);
719 SetWindowExtEx(hdcMetafile, 120, 120, NULL );
720 SetViewportExtEx(hdcMetafile, 300, 300, NULL );
721 SetPolyFillMode( hdcMetafile, ALTERNATE );
722 SetBkColor( hdcMetafile, 0 );
723
724 /* Force Win9x to update DC state */
725 SetPixelV(hdcMetafile, 50, 50, 0);
726
727 ret = GetViewportOrgEx(hdcMetafile, &pt);
728 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
729 ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
730 ret = GetViewportExtEx(hdcMetafile, &size);
731 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
732 ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
733 ret = SaveDC(hdcMetafile);
734 ok(ret == 3, "ret = %d\n", ret);
735
736 SetWindowOrgEx(hdcMetafile, -3, -3, NULL);
737 SetViewportOrgEx(hdcMetafile, 30, 30, NULL);
738 SetWindowExtEx(hdcMetafile, 200, 200, NULL );
739 SetViewportExtEx(hdcMetafile, 400, 400, NULL );
740
741 SetPolyFillMode( hdcMetafile, WINDING );
742 SetBkColor( hdcMetafile, 0x123456 );
743 ok( GetPolyFillMode( hdcMetafile ) == WINDING, "PolyFillMode not restored\n" );
744 ok( GetBkColor( hdcMetafile ) == 0x123456, "Background color not restored\n" );
745
746 /* Force Win9x to update DC state */
747 SetPixelV(hdcMetafile, 50, 50, 0);
748
749 ret = GetViewportOrgEx(hdcMetafile, &pt);
750 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
751 ok(pt.x == 30,"Expecting ViewportOrg x of 30, got %i\n",pt.x);
752 ret = GetViewportExtEx(hdcMetafile, &size);
753 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
754 ok(size.cx == 400,"Expecting ViewportExt cx of 400, got %i\n",size.cx);
755 ret = RestoreDC(hdcMetafile, -1);
756 ok(ret, "ret = %d\n", ret);
757
758 ret = GetViewportOrgEx(hdcMetafile, &pt);
759 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
760 ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
761 ret = GetViewportExtEx(hdcMetafile, &size);
762 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
763 ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
764 ok( GetPolyFillMode( hdcMetafile ) == ALTERNATE, "PolyFillMode not restored\n" );
765 ok( GetBkColor( hdcMetafile ) == 0, "Background color not restored\n" );
766 ret = SaveDC(hdcMetafile);
767 ok(ret == 3, "ret = %d\n", ret);
768
769 ret = GetViewportOrgEx(hdcMetafile, &pt);
770 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
771 ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
772 ret = GetViewportExtEx(hdcMetafile, &size);
773 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
774 ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
775 ret = RestoreDC(hdcMetafile, 1);
776 ok(ret, "ret = %d\n", ret);
777 ret = GetViewportOrgEx(hdcMetafile, &pt);
778 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
779 ok(pt.x == 0,"Expecting ViewportOrg x of 0, got %i\n",pt.x);
780 ret = GetViewportExtEx(hdcMetafile, &size);
781 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
782 ok(size.cx == 120,"Expecting ViewportExt cx of 120, got %i\n",size.cx);
783
784 SetWindowOrgEx(hdcMetafile, -4, -4, NULL);
785 SetViewportOrgEx(hdcMetafile, 40, 40, NULL);
786 SetWindowExtEx(hdcMetafile, 500, 500, NULL );
787 SetViewportExtEx(hdcMetafile, 50, 50, NULL );
788
789 /* Force Win9x to update DC state */
790 SetPixelV(hdcMetafile, 50, 50, 0);
791
792 ret = GetViewportOrgEx(hdcMetafile, &pt);
793 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
794 ok(pt.x == 40,"Expecting ViewportOrg x of 40, got %i\n",pt.x);
795 ret = GetViewportExtEx(hdcMetafile, &size);
796 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
797 ok(size.cx == 50,"Expecting ViewportExt cx of 50, got %i\n",size.cx);
798 ret = SaveDC(hdcMetafile);
799 ok(ret == 1, "ret = %d\n", ret);
800
801 ret = GetViewportOrgEx(hdcMetafile, &pt);
802 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
803 ok(pt.x == 40,"Expecting ViewportOrg x of 40, got %i\n",pt.x);
804 ret = GetViewportExtEx(hdcMetafile, &size);
805 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
806 ok(size.cx == 50,"Expecting ViewportExt cx of 50, got %i\n",size.cx);
807 ret = SaveDC(hdcMetafile);
808 ok(ret == 2, "ret = %d\n", ret);
809
810 memset(&orig_lf, 0, sizeof(orig_lf));
811 orig_lf.lfCharSet = ANSI_CHARSET;
812 orig_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
813 orig_lf.lfWeight = FW_DONTCARE;
814 orig_lf.lfHeight = 7;
815 orig_lf.lfQuality = DEFAULT_QUALITY;
816 lstrcpyA(orig_lf.lfFaceName, "Arial");
817 hFont = CreateFontIndirectA(&orig_lf);
818 ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
819
820 hFontOld = SelectObject(hdcMetafile, hFont);
821
822 hFont2 = CreateFontIndirectA(&orig_lf);
823 ok(hFont2 != 0, "CreateFontIndirectA error %d\n", GetLastError());
824 hFontCheck = SelectObject(hdcMetafile, hFont2);
825 ok(hFontCheck == hFont, "Font not selected\n");
826
827 /* Force Win9x to update DC state */
828 SetPixelV(hdcMetafile, 50, 50, 0);
829
830 ret = RestoreDC(hdcMetafile, 1);
831 ok(ret, "ret = %d\n", ret);
832 ret = GetViewportOrgEx(hdcMetafile, &pt);
833 ok(ret, "GetViewportOrgEx error %u\n", GetLastError());
834 ok(pt.x == 40,"Expecting ViewportOrg x of 40, got %i\n",pt.x);
835 ret = GetViewportExtEx(hdcMetafile, &size);
836 ok(ret, "GetViewportExtEx error %u\n", GetLastError());
837 ok(size.cx == 50,"Expecting ViewportExt cx of 50, got %i\n",size.cx);
838
839 hFontCheck = SelectObject(hdcMetafile, hFontOld);
840 ok(hFontOld == hFontCheck && hFontCheck != hFont && hFontCheck != hFont2,
841 "Font not reverted with DC Restore\n");
842
843 ret = RestoreDC(hdcMetafile, -20);
844 ok(!ret, "ret = %d\n", ret);
845 ret = RestoreDC(hdcMetafile, 20);
846 ok(!ret, "ret = %d\n", ret);
847
848 hMetafile = CloseEnhMetaFile(hdcMetafile);
849 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
850
851 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, savedc_emf_enum_proc, 0, &rc);
852 ok( ret == 1, "EnumEnhMetaFile rets %d\n", ret);
853
854 ret = DeleteObject(hFont);
855 ok( ret, "DeleteObject error %d\n", GetLastError());
856 ret = DeleteObject(hFont2);
857 ok( ret, "DeleteObject error %d\n", GetLastError());
858 ret = DeleteEnhMetaFile(hMetafile);
859 ok( ret, "DeleteEnhMetaFile error %d\n", GetLastError());
860 ret = ReleaseDC(hwnd, hdcDisplay);
861 ok( ret, "ReleaseDC error %d\n", GetLastError());
862 DestroyWindow(hwnd);
863 }
864
865 static void test_mf_SaveDC(void)
866 {
867 HDC hdcMetafile;
868 HMETAFILE hMetafile;
869 int ret;
870 POINT pt;
871 SIZE size;
872 HFONT hFont,hFont2,hFontOld,hFontCheck;
873
874 hdcMetafile = CreateMetaFileA(NULL);
875 ok(hdcMetafile != 0, "CreateMetaFileA error %d\n", GetLastError());
876
877 ret = SetMapMode(hdcMetafile, MM_ANISOTROPIC);
878 ok (ret, "SetMapMode should not fail\n");
879
880 /* Need to write something to the emf, otherwise Windows won't play it back */
881 LineTo(hdcMetafile, 150, 150);
882
883 pt.x = pt.y = 5555;
884 SetWindowOrgEx(hdcMetafile, 0, 0, &pt);
885 ok( pt.x == 5555 && pt.y == 5555, "wrong origin %d,%d\n", pt.x, pt.y);
886 pt.x = pt.y = 5555;
887 SetViewportOrgEx(hdcMetafile, 0, 0, &pt);
888 ok( pt.x == 5555 && pt.y == 5555, "wrong origin %d,%d\n", pt.x, pt.y);
889 size.cx = size.cy = 5555;
890 SetWindowExtEx(hdcMetafile, 110, 110, &size );
891 ok( size.cx == 5555 && size.cy == 5555, "wrong size %d,%d\n", size.cx, size.cy );
892 size.cx = size.cy = 5555;
893 SetViewportExtEx(hdcMetafile, 120, 120, &size );
894 ok( size.cx == 5555 && size.cy == 5555, "wrong size %d,%d\n", size.cx, size.cy );
895
896 /* Force Win9x to update DC state */
897 SetPixelV(hdcMetafile, 50, 50, 0);
898
899 ret = GetViewportOrgEx(hdcMetafile, &pt);
900 todo_wine ok (!ret, "GetViewportOrgEx should fail\n");
901 ret = GetViewportExtEx(hdcMetafile, &size);
902 todo_wine ok (!ret, "GetViewportExtEx should fail\n");
903 ret = SaveDC(hdcMetafile);
904 ok(ret == 1, "ret = %d\n", ret);
905
906 SetWindowOrgEx(hdcMetafile, -1, -1, NULL);
907 SetViewportOrgEx(hdcMetafile, 10, 10, NULL);
908 SetWindowExtEx(hdcMetafile, 150, 150, NULL );
909 SetViewportExtEx(hdcMetafile, 200, 200, NULL );
910
911 /* Force Win9x to update DC state */
912 SetPixelV(hdcMetafile, 50, 50, 0);
913
914 ret = SaveDC(hdcMetafile);
915 ok(ret == 1, "ret = %d\n", ret);
916
917 SetWindowOrgEx(hdcMetafile, -2, -2, NULL);
918 SetViewportOrgEx(hdcMetafile, 20, 20, NULL);
919 SetWindowExtEx(hdcMetafile, 120, 120, NULL );
920 SetViewportExtEx(hdcMetafile, 300, 300, NULL );
921
922 /* Force Win9x to update DC state */
923 SetPixelV(hdcMetafile, 50, 50, 0);
924 SetPolyFillMode( hdcMetafile, ALTERNATE );
925 SetBkColor( hdcMetafile, 0 );
926
927 ret = SaveDC(hdcMetafile);
928 ok(ret == 1, "ret = %d\n", ret);
929
930 SetWindowOrgEx(hdcMetafile, -3, -3, NULL);
931 SetViewportOrgEx(hdcMetafile, 30, 30, NULL);
932 SetWindowExtEx(hdcMetafile, 200, 200, NULL );
933 SetViewportExtEx(hdcMetafile, 400, 400, NULL );
934
935 SetPolyFillMode( hdcMetafile, WINDING );
936 SetBkColor( hdcMetafile, 0x123456 );
937 todo_wine ok( !GetPolyFillMode( hdcMetafile ), "GetPolyFillMode succeeded\n" );
938 todo_wine ok( GetBkColor( hdcMetafile ) == CLR_INVALID, "GetBkColor succeeded\n" );
939
940 /* Force Win9x to update DC state */
941 SetPixelV(hdcMetafile, 50, 50, 0);
942
943 ret = RestoreDC(hdcMetafile, -1);
944 ok(ret, "ret = %d\n", ret);
945
946 ret = SaveDC(hdcMetafile);
947 ok(ret == 1, "ret = %d\n", ret);
948
949 ret = RestoreDC(hdcMetafile, 1);
950 ok(ret, "ret = %d\n", ret);
951
952 SetWindowOrgEx(hdcMetafile, -4, -4, NULL);
953 SetViewportOrgEx(hdcMetafile, 40, 40, NULL);
954 SetWindowExtEx(hdcMetafile, 500, 500, NULL );
955 SetViewportExtEx(hdcMetafile, 50, 50, NULL );
956
957 /* Force Win9x to update DC state */
958 SetPixelV(hdcMetafile, 50, 50, 0);
959
960 ret = SaveDC(hdcMetafile);
961 ok(ret == 1, "ret = %d\n", ret);
962
963 ret = SaveDC(hdcMetafile);
964 ok(ret == 1, "ret = %d\n", ret);
965
966 memset(&orig_lf, 0, sizeof(orig_lf));
967 orig_lf.lfCharSet = ANSI_CHARSET;
968 orig_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
969 orig_lf.lfWeight = FW_DONTCARE;
970 orig_lf.lfHeight = 7;
971 orig_lf.lfQuality = DEFAULT_QUALITY;
972 lstrcpyA(orig_lf.lfFaceName, "Arial");
973 hFont = CreateFontIndirectA(&orig_lf);
974 ok(hFont != 0, "CreateFontIndirectA error %d\n", GetLastError());
975
976 hFontOld = SelectObject(hdcMetafile, hFont);
977
978 hFont2 = CreateFontIndirectA(&orig_lf);
979 ok(hFont2 != 0, "CreateFontIndirectA error %d\n", GetLastError());
980 hFontCheck = SelectObject(hdcMetafile, hFont2);
981 ok(hFontCheck == hFont, "Font not selected\n");
982
983 /* Force Win9x to update DC state */
984 SetPixelV(hdcMetafile, 50, 50, 0);
985
986 ret = RestoreDC(hdcMetafile, 1);
987 ok(ret, "ret = %d\n", ret);
988
989 hFontCheck = SelectObject(hdcMetafile, hFontOld);
990 ok(hFontOld != hFontCheck && hFontCheck == hFont2, "Font incorrectly reverted with DC Restore\n");
991
992 /* restore level is ignored */
993 ret = RestoreDC(hdcMetafile, -20);
994 ok(ret, "ret = %d\n", ret);
995 ret = RestoreDC(hdcMetafile, 20);
996 ok(ret, "ret = %d\n", ret);
997 ret = RestoreDC(hdcMetafile, 0);
998 ok(ret, "ret = %d\n", ret);
999
1000 hMetafile = CloseMetaFile(hdcMetafile);
1001 ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
1002
1003 ret = DeleteMetaFile(hMetafile);
1004 ok( ret, "DeleteMetaFile error %d\n", GetLastError());
1005 ret = DeleteObject(hFont);
1006 ok( ret, "DeleteObject error %d\n", GetLastError());
1007 ret = DeleteObject(hFont2);
1008 ok( ret, "DeleteObject error %d\n", GetLastError());
1009 }
1010
1011
1012 /* Win-format metafile (mfdrv) tests */
1013 /* These tests compare the generated metafiles byte-by-byte */
1014 /* with the nominal results. */
1015
1016 /* Maximum size of sample metafiles in bytes. */
1017 #define MF_BUFSIZE 1024
1018
1019 /* 8x8 bitmap data for a pattern brush */
1020 static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
1021 0x01, 0x00, 0x02, 0x00,
1022 0x03, 0x00, 0x04, 0x00,
1023 0x05, 0x00, 0x06, 0x00,
1024 0x07, 0x00, 0x08, 0x00
1025 };
1026
1027 /* Sample metafiles to be compared to the outputs of the
1028 * test functions.
1029 */
1030
1031 static const unsigned char MF_BLANK_BITS[] = {
1032 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x0c, 0x00,
1033 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1034 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
1035 };
1036
1037 static const unsigned char MF_GRAPHICS_BITS[] = {
1038 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x22, 0x00,
1039 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1040 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
1041 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
1042 0x13, 0x02, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00,
1043 0x00, 0x00, 0x14, 0x02, 0x01, 0x00, 0x01, 0x00,
1044 0x07, 0x00, 0x00, 0x00, 0x18, 0x04, 0x02, 0x00,
1045 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
1046 0x00, 0x00, 0x00, 0x00
1047 };
1048
1049 static const unsigned char MF_PATTERN_BRUSH_BITS[] = {
1050 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x3d, 0x00,
1051 0x00, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00,
1052 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x42, 0x01,
1053 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1054 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1055 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1056 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1057 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1058 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1059 0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00,
1060 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1061 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1062 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1063 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1064 0x2d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1065 0x00, 0x00
1066 };
1067
1068 static const unsigned char MF_DCBRUSH_BITS[] =
1069 {
1070 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x2a, 0x00,
1071 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00,
1072 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xfc, 0x02,
1073 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1074 0x04, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x00, 0x00,
1075 0x08, 0x00, 0x00, 0x00, 0xfa, 0x02, 0x00, 0x00,
1076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077 0x04, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x01, 0x00,
1078 0x07, 0x00, 0x00, 0x00, 0x1b, 0x04, 0x14, 0x00,
1079 0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x03, 0x00,
1080 0x00, 0x00, 0x00, 0x00
1081 };
1082
1083 static const unsigned char MF_TEXTOUT_ON_PATH_BITS[] =
1084 {
1085 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
1086 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1087 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
1088 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
1089 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
1090 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
1091 0x00, 0x00
1092 };
1093
1094 static const unsigned char EMF_TEXTOUT_ON_PATH_BITS[] =
1095 {
1096 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1098 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1099 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
1101 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1102 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1103 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1105 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1106 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
1109 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
1110 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
1111 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1113 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
1114 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
1115 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
1116 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
1117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1119 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
1120 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
1121 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1122 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1123 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1124 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1125 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1126 0x14, 0x00, 0x00, 0x00
1127 };
1128
1129 static const unsigned char EMF_TEXTOUT_OUTLINE_ON_PATH_BITS[] =
1130 {
1131 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1133 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1135 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff,
1136 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1137 0x0c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1138 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140 0x90, 0x06, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00,
1141 0x51, 0x02, 0x00, 0x00, 0x72, 0x01, 0x00, 0x00,
1142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143 0x00, 0x00, 0x00, 0x00, 0x1a, 0x0b, 0x09, 0x00,
1144 0xf0, 0xa6, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00,
1145 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80,
1146 0x3b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1147 0x54, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1149 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1150 0x01, 0x00, 0x00, 0x00, 0xc3, 0x30, 0x0d, 0x42,
1151 0xcf, 0xf3, 0x0c, 0x42, 0x0b, 0x00, 0x00, 0x00,
1152 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1153 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1155 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1156 0x54, 0x00, 0x00, 0x00, 0x54, 0x00, 0x65, 0x00,
1157 0x73, 0x00, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
1158 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1159 0x0c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
1160 0x08, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1161 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80,
1162 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1163 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1164 0x14, 0x00, 0x00, 0x00
1165 };
1166
1167 static const unsigned char MF_LINETO_BITS[] = {
1168 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1169 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1170 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1171 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1172 0x00, 0x00
1173 };
1174
1175 static const unsigned char EMF_LINETO_BITS[] = {
1176 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1178 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1180 0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00,
1181 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1182 0x38, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1183 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1186 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00,
1189 0xe0, 0x93, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00,
1190 0x48, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1191 0x47, 0x44, 0x49, 0x43, 0x01, 0x00, 0x00, 0x80,
1192 0x00, 0x03, 0x00, 0x00, 0x60, 0xe5, 0xf4, 0x73,
1193 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1194 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1195 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1196 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1197 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1198 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1199 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1200 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1201 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1202 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1203 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1204 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1205 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1206 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1207 0x07, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00,
1208 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
1209 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1210 0x0f, 0x00, 0x00, 0x80, 0x4b, 0x00, 0x00, 0x00,
1211 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1212 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1213 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
1215 };
1216
1217 static const unsigned char EMF_LINETO_MM_ANISOTROPIC_BITS[] = {
1218 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1223 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1224 0x38, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1225 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1228 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00,
1231 0xe0, 0x93, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00,
1232 0x48, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1233 0x47, 0x44, 0x49, 0x43, 0x01, 0x00, 0x00, 0x80,
1234 0x00, 0x03, 0x00, 0x00, 0xa4, 0xfe, 0xf4, 0x73,
1235 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1236 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1237 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1238 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1239 0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1240 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1241 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1242 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1243 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1244 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1245 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1246 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1247 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1248 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1249 0x07, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00,
1250 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
1251 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1252 0x0f, 0x00, 0x00, 0x80, 0x4b, 0x00, 0x00, 0x00,
1253 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1254 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1255 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
1257 };
1258
1259 static const unsigned char EMF_LINETO_MM_TEXT_BITS[] = {
1260 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1262 0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1264 0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00,
1265 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1266 0xe4, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1267 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1269 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1270 0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00,
1273 0xe0, 0x93, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
1274 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
1275 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1276 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
1277 0x00, 0x04, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
1278 0x10, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
1279 0x0f, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1280 0x0c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80,
1281 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1282 0x00, 0x00, 0x00, 0x80, 0x30, 0x00, 0x00, 0x00,
1283 0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x80,
1284 0x4b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1285 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1286 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1287 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1288 0x14, 0x00, 0x00, 0x00
1289 };
1290
1291 static const unsigned char EMF_BITBLT[] =
1292 {
1293 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1295 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1297 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
1298 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1299 0x64, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1300 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1302 0x80, 0x07, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00,
1303 0xfc, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00,
1304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1305 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
1306 0x30, 0xda, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00,
1307 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1308 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1309 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1311 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0xcc, 0x00,
1312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1313 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
1314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
1315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1316 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1317 0x64, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1318 0x8c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1319 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1320 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330 0x4c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1334 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1335 0x62, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1338 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
1339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
1343 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1345 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1347 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0xcc, 0x00,
1348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1349 0x0a, 0xd7, 0xa3, 0x3b, 0x00, 0x00, 0x00, 0x00,
1350 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0x23, 0x3c,
1351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1352 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1353 0x6c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1354 0x94, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1355 0x90, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
1356 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1357 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
1358 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1367 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1369 0x14, 0x00, 0x00, 0x00
1370 };
1371
1372 static const unsigned char EMF_DCBRUSH_BITS[] =
1373 {
1374 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1375 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1376 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1377 0x39, 0x01, 0x00, 0x00, 0x39, 0x01, 0x00, 0x00,
1378 0x52, 0x02, 0x00, 0x00, 0x52, 0x02, 0x00, 0x00,
1379 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1380 0x44, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1381 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
1384 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
1385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1386 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
1387 0x80, 0xa9, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00,
1388 0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x80,
1389 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1390 0x13, 0x00, 0x00, 0x80, 0x27, 0x00, 0x00, 0x00,
1391 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1392 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x00,
1393 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1394 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1395 0x26, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
1396 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1398 0x33, 0x44, 0x55, 0x00, 0x25, 0x00, 0x00, 0x00,
1399 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1400 0x2b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
1401 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1402 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1403 0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1404 0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1405 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1406 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x00,
1407 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1408 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1409 0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1410 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1411 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1412 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1413 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1414 0x14, 0x00, 0x00, 0x00
1415 };
1416
1417 static const unsigned char EMF_BEZIER_BITS[] =
1418 {
1419 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1421 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1423 0x1a, 0x2a, 0x0d, 0x00, 0x1a, 0x2f, 0x0d, 0x00,
1424 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1425 0x44, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1426 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1429 0x51, 0x01, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00,
1430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431 0x00, 0x00, 0x00, 0x00, 0x68, 0x24, 0x05, 0x00,
1432 0xb0, 0x1e, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
1433 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1435 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1436 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00,
1437 0x0f, 0x00, 0x0f, 0x00, 0x55, 0x00, 0x00, 0x00,
1438 0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1439 0x0a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1440 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1441 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00,
1442 0x0f, 0x00, 0x0f, 0x00, 0x19, 0x00, 0x19, 0x00,
1443 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
1444 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1445 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1446 0x04, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1447 0x01, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1448 0x14, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1449 0x0f, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1450 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1451 0x34, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1452 0x0f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1453 0x01, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1454 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1455 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1456 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1457 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1459 0x14, 0x00, 0x00, 0x00
1460 };
1461
1462 static const unsigned char EMF_POLYPOLYLINE_BITS[] =
1463 {
1464 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1465 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1466 0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1467 0x61, 0x01, 0x00, 0x00, 0xc2, 0x02, 0x00, 0x00,
1468 0x7a, 0xd4, 0x13, 0x00, 0xe8, 0x44, 0x00, 0x00,
1469 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1470 0x84, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1471 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1473 0xa1, 0x05, 0x00, 0x00, 0x47, 0x03, 0x00, 0x00,
1474 0xfc, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
1475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc1, 0x07, 0x00,
1477 0x2c, 0x84, 0x04, 0x00, 0x5a, 0x00, 0x00, 0x00,
1478 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1479 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1480 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
1481 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
1482 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1484 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
1485 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1486 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00,
1487 0x5a, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1490 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1491 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1492 0x0a, 0x00, 0x14, 0x00, 0x64, 0x00, 0xc8, 0x00,
1493 0x07, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1496 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1497 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1498 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1499 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
1500 0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1501 0x07, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
1502 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1503 0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1504 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1505 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1506 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1507 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
1508 0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1509 0x90, 0x01, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1510 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1511 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1512 0x14, 0x00, 0x00, 0x00
1513 };
1514
1515 static const unsigned char EMF_GRADIENTFILL_BITS[] =
1516 {
1517 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1518 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1519 0x2b, 0x01, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00,
1520 0x23, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00,
1521 0x31, 0x29, 0x00, 0x00, 0xa3, 0x2a, 0x00, 0x00,
1522 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1523 0x0c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1524 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1526 0x40, 0x05, 0x00, 0x00, 0x46, 0x03, 0x00, 0x00,
1527 0xda, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
1528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1529 0x00, 0x00, 0x00, 0x00, 0x15, 0x3c, 0x07, 0x00,
1530 0xcb, 0x82, 0x04, 0x00, 0x76, 0x00, 0x00, 0x00,
1531 0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1532 0x0a, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00,
1533 0x35, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1534 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1535 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1536 0x00, 0xff, 0x00, 0x80, 0x00, 0x00, 0x01, 0x80,
1537 0xc8, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00,
1538 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
1539 0xb4, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00,
1540 0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, 0xf0, 0xde,
1541 0x2c, 0x01, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
1542 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
1543 0x90, 0x01, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00,
1544 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
1545 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1546 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1547 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1548 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1549 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1550 0x14, 0x00, 0x00, 0x00
1551 };
1552
1553 /* For debugging or dumping the raw metafiles produced by
1554 * new test functions.
1555 */
1556 static INT CALLBACK mf_enum_proc(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
1557 INT nobj, LPARAM param)
1558 {
1559 trace("hdc %p, mr->rdFunction %04x, mr->rdSize %u, param %p\n",
1560 hdc, mr->rdFunction, mr->rdSize, (void *)param);
1561 return TRUE;
1562 }
1563
1564 /* For debugging or dumping the raw metafiles produced by
1565 * new test functions.
1566 */
1567
1568 static void dump_mf_bits (const HMETAFILE mf, const char *desc)
1569 {
1570 BYTE buf[MF_BUFSIZE];
1571 UINT mfsize, i;
1572
1573 if (!winetest_debug) return;
1574
1575 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
1576 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
1577
1578 printf ("MetaFile %s has bits:\n{\n ", desc);
1579 for (i=0; i<mfsize; i++)
1580 {
1581 printf ("0x%02x", buf[i]);
1582 if (i == mfsize-1)
1583 printf ("\n");
1584 else if (i % 8 == 7)
1585 printf (",\n ");
1586 else
1587 printf (", ");
1588 }
1589 printf ("};\n");
1590 }
1591
1592 /* Compare the metafile produced by a test function with the
1593 * expected raw metafile data in "bits".
1594 * Return value is 0 for a perfect match,
1595 * -1 if lengths aren't equal,
1596 * otherwise returns the number of non-matching bytes.
1597 */
1598
1599 static int compare_mf_bits (const HMETAFILE mf, const unsigned char *bits, UINT bsize,
1600 const char *desc)
1601 {
1602 unsigned char buf[MF_BUFSIZE];
1603 UINT mfsize, i;
1604 int diff;
1605
1606 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
1607 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
1608 if (mfsize < MF_BUFSIZE)
1609 ok (mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n",
1610 desc, mfsize, bsize);
1611 else
1612 ok (bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d.\n",
1613 desc, mfsize, bsize);
1614 if (mfsize != bsize)
1615 return -1;
1616
1617 diff = 0;
1618 for (i=0; i<bsize; i++)
1619 {
1620 if (buf[i] != bits[i])
1621 diff++;
1622 }
1623 ok (diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
1624 desc, mfsize, bsize, diff);
1625
1626 return diff;
1627 }
1628
1629 static int compare_mf_disk_bits(LPCSTR name, const BYTE *bits, UINT bsize, const char *desc)
1630 {
1631 unsigned char buf[MF_BUFSIZE];
1632 DWORD mfsize, rd_size, i;
1633 int diff;
1634 HANDLE hfile;
1635 BOOL ret;
1636
1637 hfile = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1638 assert(hfile != INVALID_HANDLE_VALUE);
1639
1640 mfsize = GetFileSize(hfile, NULL);
1641 assert(mfsize <= MF_BUFSIZE);
1642
1643 ret = ReadFile(hfile, buf, sizeof(buf), &rd_size, NULL);
1644 ok( ret && rd_size == mfsize, "ReadFile: error %d\n", GetLastError());
1645
1646 CloseHandle(hfile);
1647
1648 ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n", desc, mfsize, bsize);
1649
1650 if (mfsize != bsize)
1651 return -1;
1652
1653 diff = 0;
1654 for (i=0; i<bsize; i++)
1655 {
1656 if (buf[i] != bits[i])
1657 diff++;
1658 }
1659 ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
1660 desc, mfsize, bsize, diff);
1661
1662 return diff;
1663 }
1664
1665 /* For debugging or dumping the raw EMFs produced by
1666 * new test functions.
1667 */
1668 static void dump_emf_bits(const HENHMETAFILE mf, const char *desc)
1669 {
1670 BYTE buf[MF_BUFSIZE];
1671 UINT mfsize, i;
1672
1673 if (!winetest_debug) return;
1674
1675 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1676 ok (mfsize > 0, "%s: GetEnhMetaFileBits failed\n", desc);
1677
1678 printf("EMF %s has bits:\n{\n ", desc);
1679 for (i = 0; i < mfsize; i++)
1680 {
1681 printf ("0x%02x", buf[i]);
1682 if (i == mfsize-1)
1683 printf ("\n");
1684 else if (i % 8 == 7)
1685 printf (",\n ");
1686 else
1687 printf (", ");
1688 }
1689 printf ("};\n");
1690 }
1691
1692 static void dump_emf_records(const HENHMETAFILE mf, const char *desc)
1693 {
1694 BYTE *emf;
1695 BYTE buf[MF_BUFSIZE];
1696 UINT mfsize, offset;
1697
1698 if (!winetest_debug) return;
1699
1700 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1701 ok (mfsize > 0, "%s: GetEnhMetaFileBits error %d\n", desc, GetLastError());
1702
1703 printf("EMF %s has records:\n", desc);
1704
1705 emf = buf;
1706 offset = 0;
1707 while(offset < mfsize)
1708 {
1709 EMR *emr = (EMR *)(emf + offset);
1710 printf("emr->iType %d, emr->nSize %u\n", emr->iType, emr->nSize);
1711 /*trace("emr->iType 0x%04lx, emr->nSize 0x%04lx\n", emr->iType, emr->nSize);*/
1712 offset += emr->nSize;
1713 }
1714 }
1715
1716 static void dump_emf_record(const ENHMETARECORD *emr, const char *desc)
1717 {
1718 const BYTE *buf;
1719 DWORD i;
1720
1721 if (!winetest_debug) return;
1722
1723 printf ("%s: EMF record %u has bits:\n{\n", desc, emr->iType);
1724 buf = (const BYTE *)emr;
1725 for (i = 0; i < emr->nSize; i++)
1726 {
1727 printf ("0x%02x", buf[i]);
1728 if (i == emr->nSize - 1)
1729 printf ("\n");
1730 else if (i % 8 == 7)
1731 printf (",\n");
1732 else
1733 printf (", ");
1734 }
1735 printf ("};\n");
1736 }
1737
1738 static void dump_EMREXTTEXTOUT(const EMREXTTEXTOUTW *eto)
1739 {
1740 trace("rclBounds %d,%d - %d,%d\n", eto->rclBounds.left, eto->rclBounds.top,
1741 eto->rclBounds.right, eto->rclBounds.bottom);
1742 trace("iGraphicsMode %u\n", eto->iGraphicsMode);
1743 trace("exScale: %f\n", eto->exScale);
1744 trace("eyScale: %f\n", eto->eyScale);
1745 trace("emrtext.ptlReference %d,%d\n", eto->emrtext.ptlReference.x, eto->emrtext.ptlReference.y);
1746 trace("emrtext.nChars %u\n", eto->emrtext.nChars);
1747 trace("emrtext.offString %#x\n", eto->emrtext.offString);
1748 trace("emrtext.fOptions %#x\n", eto->emrtext.fOptions);
1749 trace("emrtext.rcl %d,%d - %d,%d\n", eto->emrtext.rcl.left, eto->emrtext.rcl.top,
1750 eto->emrtext.rcl.right, eto->emrtext.rcl.bottom);
1751 trace("emrtext.offDx %#x\n", eto->emrtext.offDx);
1752 }
1753
1754 static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr2,
1755 const char *desc, BOOL ignore_scaling)
1756 {
1757 int diff;
1758
1759 ok(emr1->iType == emr2->iType, "%s: emr->iType %u != %u\n",
1760 desc, emr1->iType, emr2->iType);
1761
1762 ok(emr1->nSize == emr2->nSize, "%s: emr->nSize %u != %u\n",
1763 desc, emr1->nSize, emr2->nSize);
1764
1765 /* iType and nSize mismatches are fatal */
1766 if (emr1->iType != emr2->iType || emr1->nSize != emr2->nSize) return FALSE;
1767
1768 /* contents of EMR_GDICOMMENT are not interesting */
1769 if (emr1->iType == EMR_GDICOMMENT) return TRUE;
1770
1771 /* different Windows versions setup DC scaling differently when
1772 * converting an old style metafile to an EMF.
1773 */
1774 if (ignore_scaling && (emr1->iType == EMR_SETWINDOWEXTEX ||
1775 emr1->iType == EMR_SETVIEWPORTEXTEX))
1776 return TRUE;
1777
1778 if (emr1->iType == EMR_EXTTEXTOUTW || emr1->iType == EMR_EXTTEXTOUTA)
1779 {
1780 EMREXTTEXTOUTW *eto1, *eto2;
1781
1782 eto1 = HeapAlloc(GetProcessHeap(), 0, emr1->nSize);
1783 memcpy(eto1, emr1, emr1->nSize);
1784 eto2 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
1785 memcpy(eto2, emr2, emr2->nSize);
1786
1787 /* different Windows versions setup DC scaling differently */
1788 eto1->exScale = eto1->eyScale = 0.0;
1789 eto2->exScale = eto2->eyScale = 0.0;
1790
1791 diff = memcmp(eto1, eto2, emr1->nSize);
1792 if (diff)
1793 {
1794 dump_EMREXTTEXTOUT(eto1);
1795 dump_EMREXTTEXTOUT(eto2);
1796 }
1797 HeapFree(GetProcessHeap(), 0, eto1);
1798 HeapFree(GetProcessHeap(), 0, eto2);
1799 }
1800 else if (emr1->iType == EMR_EXTSELECTCLIPRGN && !lstrcmpA(desc, "emf_clipping"))
1801 {
1802 /* We have to take care of NT4 differences here */
1803 diff = memcmp(emr1, emr2, emr1->nSize);
1804 if (diff)
1805 {
1806 ENHMETARECORD *emr_nt4;
1807
1808 emr_nt4 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
1809 memcpy(emr_nt4, emr2, emr2->nSize);
1810 /* Correct the nRgnSize field */
1811 emr_nt4->dParm[5] = sizeof(RECT);
1812
1813 diff = memcmp(emr1, emr_nt4, emr1->nSize);
1814 if (!diff)
1815 win_skip("Catered for NT4 differences\n");
1816
1817 HeapFree(GetProcessHeap(), 0, emr_nt4);
1818 }
1819 }
1820 else if (emr1->iType == EMR_POLYBEZIERTO16 || emr1->iType == EMR_POLYBEZIER16)
1821 {
1822 EMRPOLYBEZIER16 *eto1, *eto2;
1823
1824 eto1 = (EMRPOLYBEZIER16*)emr1;
1825 eto2 = (EMRPOLYBEZIER16*)emr2;
1826
1827 diff = eto1->cpts != eto2->cpts;
1828 if(!diff)
1829 diff = memcmp(eto1->apts, eto2->apts, eto1->cpts * sizeof(POINTS));
1830 }
1831 else if (emr1->iType == EMR_POLYBEZIERTO || emr1->iType == EMR_POLYBEZIER)
1832 {
1833 EMRPOLYBEZIER *eto1, *eto2;
1834
1835 eto1 = (EMRPOLYBEZIER*)emr1;
1836 eto2 = (EMRPOLYBEZIER*)emr2;
1837
1838 diff = eto1->cptl != eto2->cptl;
1839 if(!diff)
1840 diff = memcmp(eto1->aptl, eto2->aptl, eto1->cptl * sizeof(POINTL));
1841 }
1842 else
1843 diff = memcmp(emr1, emr2, emr1->nSize);
1844
1845 ok(diff == 0, "%s: contents of record %u don't match\n", desc, emr1->iType);
1846
1847 if (diff)
1848 {
1849 dump_emf_record(emr1, "expected bits");
1850 dump_emf_record(emr2, "actual bits");
1851 }
1852
1853 return diff == 0; /* report all non-fatal record mismatches */
1854 }
1855
1856 /* Compare the EMF produced by a test function with the
1857 * expected raw EMF data in "bits".
1858 * Return value is 0 for a perfect match,
1859 * -1 if lengths aren't equal,
1860 * otherwise returns the number of non-matching bytes.
1861 */
1862 static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
1863 UINT bsize, const char *desc,
1864 BOOL ignore_scaling)
1865 {
1866 unsigned char buf[MF_BUFSIZE];
1867 UINT mfsize, offset1, offset2, diff_nt4, diff_9x;
1868 const ENHMETAHEADER *emh1, *emh2;
1869
1870 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1871 ok (mfsize > 0, "%s: GetEnhMetaFileBits error %d\n", desc, GetLastError());
1872
1873 /* ENHMETAHEADER size could differ, depending on platform */
1874 diff_nt4 = sizeof(SIZEL);
1875 diff_9x = sizeof(SIZEL) + 3 * sizeof(DWORD);
1876
1877 if (mfsize < MF_BUFSIZE)
1878 {
1879 ok(mfsize == bsize ||
1880 broken(mfsize == bsize - diff_nt4) || /* NT4 */
1881 broken(mfsize == bsize - diff_9x), /* Win9x/WinME */
1882 "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize);
1883 }
1884 else
1885 ok(bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d\n",
1886 desc, mfsize, bsize);
1887
1888 /* basic things must match */
1889 emh1 = (const ENHMETAHEADER *)bits;
1890 emh2 = (const ENHMETAHEADER *)buf;
1891 ok(emh1->iType == EMR_HEADER, "expected EMR_HEADER, got %u\n", emh1->iType);
1892 ok(emh1->nSize == sizeof(ENHMETAHEADER), "expected sizeof(ENHMETAHEADER), got %u\n", emh1->nSize);
1893 ok(emh2->nBytes == mfsize, "expected emh->nBytes %u, got %u\n", mfsize, emh2->nBytes);
1894 ok(emh1->dSignature == ENHMETA_SIGNATURE, "expected ENHMETA_SIGNATURE, got %u\n", emh1->dSignature);
1895
1896 ok(emh1->iType == emh2->iType, "expected EMR_HEADER, got %u\n", emh2->iType);
1897 ok(emh1->nSize == emh2->nSize ||
1898 broken(emh1->nSize - diff_nt4 == emh2->nSize) ||
1899 broken(emh1->nSize - diff_9x == emh2->nSize),
1900 "expected nSize %u, got %u\n", emh1->nSize, emh2->nSize);
1901 ok(emh1->rclBounds.left == emh2->rclBounds.left, "%s: expected rclBounds.left = %d, got %d\n",
1902 desc, emh1->rclBounds.left, emh2->rclBounds.left);
1903 ok(emh1->rclBounds.top == emh2->rclBounds.top, "%s: expected rclBounds.top = %d, got %d\n",
1904 desc, emh1->rclBounds.top, emh2->rclBounds.top);
1905 ok(emh1->rclBounds.right == emh2->rclBounds.right, "%s: expected rclBounds.right = %d, got %d\n",
1906 desc, emh1->rclBounds.right, emh2->rclBounds.right);
1907 ok(emh1->rclBounds.bottom == emh2->rclBounds.bottom, "%s: expected rclBounds.bottom = %d, got %d\n",
1908 desc, emh1->rclBounds.bottom, emh2->rclBounds.bottom);
1909 ok(emh1->dSignature == emh2->dSignature, "expected dSignature %u, got %u\n", emh1->dSignature, emh2->dSignature);
1910 ok(emh1->nBytes == emh2->nBytes ||
1911 broken(emh1->nBytes - diff_nt4 == emh2->nBytes) ||
1912 broken(emh1->nBytes - diff_9x == emh2->nBytes),
1913 "expected nBytes %u, got %u\n", emh1->nBytes, emh2->nBytes);
1914 ok(emh1->nRecords == emh2->nRecords, "expected nRecords %u, got %u\n", emh1->nRecords, emh2->nRecords);
1915
1916 offset1 = emh1->nSize;
1917 offset2 = emh2->nSize; /* Needed for Win9x/WinME/NT4 */
1918 while (offset1 < emh1->nBytes)
1919 {
1920 const ENHMETARECORD *emr1 = (const ENHMETARECORD *)(bits + offset1);
1921 const ENHMETARECORD *emr2 = (const ENHMETARECORD *)(buf + offset2);
1922
1923 trace("%s: EMF record %u, size %u/record %u, size %u\n",
1924 desc, emr1->iType, emr1->nSize, emr2->iType, emr2->nSize);
1925
1926 if (!match_emf_record(emr1, emr2, desc, ignore_scaling)) return -1;
1927
1928 /* We have already bailed out if iType or nSize don't match */
1929 offset1 += emr1->nSize;
1930 offset2 += emr2->nSize;
1931 }
1932 return 0;
1933 }
1934
1935
1936 /* tests blitting to an EMF */
1937 static void test_emf_BitBlt(void)
1938 {
1939 HDC hdcDisplay, hdcMetafile, hdcBitmap;
1940 HBITMAP hBitmap, hOldBitmap;
1941 HENHMETAFILE hMetafile;
1942 #define BMP_DIM 4
1943 BITMAPINFOHEADER bmih =
1944 {
1945 sizeof(BITMAPINFOHEADER),
1946 BMP_DIM,/* biWidth */
1947 BMP_DIM,/* biHeight */
1948 1, /* biPlanes */
1949 24, /* biBitCount */
1950 BI_RGB, /* biCompression */
1951 0, /* biXPelsPerMeter */
1952 0, /* biYPelsPerMeter */
1953 0, /* biClrUsed */
1954 0, /* biClrImportant */
1955 };
1956 void *bits;
1957 XFORM xform;
1958 BOOL ret;
1959
1960 hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL);
1961 ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() );
1962
1963 hdcBitmap = CreateCompatibleDC(hdcDisplay);
1964 ok( hdcBitmap != 0, "CreateCompatibleDC failed\n" );
1965 ok(SetGraphicsMode(hdcBitmap, GM_ADVANCED), "SetGraphicsMode failed\n");
1966 bmih.biXPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSX), 100, 3937);
1967 bmih.biYPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSY), 100, 3937);
1968 hBitmap = CreateDIBSection(hdcDisplay, (const BITMAPINFO *)&bmih,
1969 DIB_RGB_COLORS, &bits, NULL, 0);
1970 hOldBitmap = SelectObject(hdcBitmap, hBitmap);
1971
1972 hdcMetafile = CreateEnhMetaFileA(hdcBitmap, NULL, NULL, NULL);
1973 ok( hdcMetafile != 0, "CreateEnhMetaFileA failed\n" );
1974
1975 /* First fill the bitmap DC with something recognizable, like BLACKNESS */
1976 ret = BitBlt(hdcBitmap, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, BLACKNESS);
1977 ok( ret, "BitBlt(BLACKNESS) failed\n" );
1978
1979 ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, hdcBitmap, 0, 0, SRCCOPY);
1980 ok( ret, "BitBlt(SRCCOPY) failed\n" );
1981 ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, WHITENESS);
1982 ok( ret, "BitBlt(WHITENESS) failed\n" );
1983
1984 ok(SetMapMode(hdcBitmap, MM_ANISOTROPIC), "SetMapMode failed\n");
1985 ok(SetWindowOrgEx(hdcBitmap, 0, 0, NULL), "SetWindowOrgEx failed\n");
1986 ok(SetWindowExtEx(hdcBitmap, 400, 400, NULL), "SetWindowExtEx failed\n");
1987 ok(SetViewportOrgEx(hdcBitmap, 0, 0, NULL), "SetViewportOrgEx failed\n");
1988 ok(SetViewportExtEx(hdcBitmap, BMP_DIM, BMP_DIM, NULL), "SetViewportExtEx failed\n");
1989 memset(&xform, 0, sizeof(xform));
1990 xform.eM11 = 0.5;
1991 xform.eM22 = 1.0;
1992 ok(SetWorldTransform(hdcBitmap, &xform), "SetWorldTransform failed\n");
1993
1994 ret = StretchBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, hdcBitmap, 0, 0, 400, 400, SRCCOPY);
1995 ok( ret, "StretchBlt(SRCCOPY) failed\n" );
1996
1997 hMetafile = CloseEnhMetaFile(hdcMetafile);
1998 ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
1999
2000 if(compare_emf_bits(hMetafile, EMF_BITBLT, sizeof(EMF_BITBLT),
2001 "emf_BitBlt", FALSE) != 0)
2002 {
2003 dump_emf_bits(hMetafile, "emf_BitBlt");
2004 dump_emf_records(hMetafile, "emf_BitBlt");
2005 }
2006
2007 SelectObject(hdcBitmap, hOldBitmap);
2008 DeleteObject(hBitmap);
2009 DeleteDC(hdcBitmap);
2010 DeleteDC(hdcDisplay);
2011 #undef BMP_DIM
2012 }
2013
2014 static void test_emf_DCBrush(void)
2015 {
2016 HDC hdcMetafile;
2017 HENHMETAFILE hMetafile;
2018 HBRUSH hBrush;
2019 HPEN hPen;
2020 BOOL ret;
2021 COLORREF color;
2022
2023 if (!pSetDCBrushColor || !pSetDCPenColor)
2024 {
2025 win_skip( "SetDCBrush/PenColor not supported\n" );
2026 return;
2027 }
2028
2029 hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
2030 ok( hdcMetafile != 0, "CreateEnhMetaFileA failed\n" );
2031
2032 hBrush = SelectObject(hdcMetafile, GetStockObject(DC_BRUSH));
2033 ok(hBrush != 0, "SelectObject error %d.\n", GetLastError());
2034
2035 hPen = SelectObject(hdcMetafile, GetStockObject(DC_PEN));
2036 ok(hPen != 0, "SelectObject error %d.\n", GetLastError());
2037
2038 color = pSetDCBrushColor( hdcMetafile, RGB(0x55,0x55,0x55) );
2039 ok( color == 0xffffff, "SetDCBrushColor returned %x\n", color );
2040
2041 color = pSetDCPenColor( hdcMetafile, RGB(0x33,0x44,0x55) );
2042 ok( color == 0, "SetDCPenColor returned %x\n", color );
2043
2044 Rectangle( hdcMetafile, 10, 10, 20, 20 );
2045
2046 color = pSetDCBrushColor( hdcMetafile, RGB(0x12,0x34,0x56) );
2047 ok( color == 0x555555, "SetDCBrushColor returned %x\n", color );
2048
2049 hMetafile = CloseEnhMetaFile(hdcMetafile);
2050 ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
2051
2052 if (compare_emf_bits (hMetafile, EMF_DCBRUSH_BITS, sizeof(EMF_DCBRUSH_BITS),
2053 "emf_DC_Brush", FALSE ) != 0)
2054 {
2055 dump_emf_bits(hMetafile, "emf_DC_Brush");
2056 dump_emf_records(hMetafile, "emf_DC_Brush");
2057 }
2058 ret = DeleteEnhMetaFile(hMetafile);
2059 ok( ret, "DeleteEnhMetaFile error %d\n", GetLastError());
2060 ret = DeleteObject(hBrush);
2061 ok( ret, "DeleteObject(HBRUSH) error %d\n", GetLastError());
2062 ret = DeleteObject(hPen);
2063 ok( ret, "DeleteObject(HPEN) error %d\n", GetLastError());
2064 }
2065
2066 /* Test a blank metafile. May be used as a template for new tests. */
2067
2068 static void test_mf_Blank(void)
2069 {
2070 HDC hdcMetafile;
2071 HMETAFILE hMetafile;
2072 INT caps;
2073 BOOL ret;
2074 INT type;
2075
2076 hdcMetafile = CreateMetaFileA(NULL);
2077 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2078 trace("hdcMetafile %p\n", hdcMetafile);
2079
2080 /* Tests on metafile initialization */
2081 caps = GetDeviceCaps (hdcMetafile, TECHNOLOGY);
2082 ok (caps == DT_METAFILE,
2083 "GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE.\n", caps);
2084
2085 hMetafile = CloseMetaFile(hdcMetafile);
2086 ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2087 type = GetObjectType(hMetafile);
2088 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
2089 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
2090
2091 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
2092 "mf_blank") != 0)
2093 {
2094 dump_mf_bits(hMetafile, "mf_Blank");
2095 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2096 }
2097
2098 ret = DeleteMetaFile(hMetafile);
2099 ok( ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2100 }
2101
2102 static void test_CopyMetaFile(void)
2103 {
2104 HDC hdcMetafile;
2105 HMETAFILE hMetafile, hmf_copy;
2106 BOOL ret;
2107 char temp_path[MAX_PATH];
2108 char mf_name[MAX_PATH];
2109 INT type;
2110
2111 hdcMetafile = CreateMetaFileA(NULL);
2112 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2113 trace("hdcMetafile %p\n", hdcMetafile);
2114
2115 hMetafile = CloseMetaFile(hdcMetafile);
2116 ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2117 type = GetObjectType(hMetafile);
2118 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
2119
2120 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
2121 "mf_blank") != 0)
2122 {
2123 dump_mf_bits(hMetafile, "mf_Blank");
2124 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2125 }
2126
2127 GetTempPathA(MAX_PATH, temp_path);
2128 GetTempFileNameA(temp_path, "wmf", 0, mf_name);
2129
2130 hmf_copy = CopyMetaFileA(hMetafile, mf_name);
2131 ok(hmf_copy != 0, "CopyMetaFile error %d\n", GetLastError());
2132
2133 type = GetObjectType(hmf_copy);
2134 ok(type == OBJ_METAFILE, "CopyMetaFile created object with type %d\n", type);
2135
2136 ret = DeleteMetaFile(hMetafile);
2137 ok( ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2138
2139 if (compare_mf_disk_bits(mf_name, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0)
2140 {
2141 dump_mf_bits(hmf_copy, "mf_Blank");
2142 EnumMetaFile(0, hmf_copy, mf_enum_proc, 0);
2143 }
2144
2145 ret = DeleteMetaFile(hmf_copy);
2146 ok( ret, "DeleteMetaFile(%p) error %d\n", hmf_copy, GetLastError());
2147
2148 DeleteFileA(mf_name);
2149 }
2150
2151 static void test_SetMetaFileBits(void)
2152 {
2153 HMETAFILE hmf;
2154 INT type;
2155 BOOL ret;
2156 BYTE buf[256];
2157 METAHEADER *mh;
2158
2159 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), MF_GRAPHICS_BITS);
2160 trace("hmf %p\n", hmf);
2161 ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2162 type = GetObjectType(hmf);
2163 ok(type == OBJ_METAFILE, "SetMetaFileBitsEx created object with type %d\n", type);
2164
2165 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2166 {
2167 dump_mf_bits(hmf, "mf_Graphics");
2168 EnumMetaFile(0, hmf, mf_enum_proc, 0);
2169 }
2170
2171 ret = DeleteMetaFile(hmf);
2172 ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2173
2174 /* NULL data crashes XP SP1 */
2175 /*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/
2176
2177 /* Now with zero size */
2178 SetLastError(0xdeadbeef);
2179 hmf = SetMetaFileBitsEx(0, MF_GRAPHICS_BITS);
2180 trace("hmf %p\n", hmf);
2181 ok(!hmf, "SetMetaFileBitsEx should fail\n");
2182 ok(GetLastError() == ERROR_INVALID_DATA ||
2183 broken(GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2184 "wrong error %d\n", GetLastError());
2185
2186 /* Now with odd size */
2187 SetLastError(0xdeadbeef);
2188 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS) - 1, MF_GRAPHICS_BITS);
2189 trace("hmf %p\n", hmf);
2190 ok(!hmf, "SetMetaFileBitsEx should fail\n");
2191 ok(GetLastError() == 0xdeadbeef /* XP SP1 */, "wrong error %d\n", GetLastError());
2192
2193 /* Now with zeroed out header fields */
2194 assert(sizeof(buf) >= sizeof(MF_GRAPHICS_BITS));
2195 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
2196 mh = (METAHEADER *)buf;
2197 /* corruption of any of the below fields leads to a failure */
2198 mh->mtType = 0;
2199 mh->mtVersion = 0;
2200 mh->mtHeaderSize = 0;
2201 SetLastError(0xdeadbeef);
2202 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2203 trace("hmf %p\n", hmf);
2204 ok(!hmf, "SetMetaFileBitsEx should fail\n");
2205 ok(GetLastError() == ERROR_INVALID_DATA ||
2206 broken(GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2207 "wrong error %d\n", GetLastError());
2208
2209 /* Now with corrupted mtSize field */
2210 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
2211 mh = (METAHEADER *)buf;
2212 /* corruption of mtSize doesn't lead to a failure */
2213 mh->mtSize *= 2;
2214 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2215 trace("hmf %p\n", hmf);
2216 ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2217
2218 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2219 {
2220 dump_mf_bits(hmf, "mf_Graphics");
2221 EnumMetaFile(0, hmf, mf_enum_proc, 0);
2222 }
2223
2224 ret = DeleteMetaFile(hmf);
2225 ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2226
2227 #ifndef _WIN64 /* Generates access violation on XP x64 and Win2003 x64 */
2228 /* Now with zeroed out mtSize field */
2229 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
2230 mh = (METAHEADER *)buf;
2231 /* zeroing mtSize doesn't lead to a failure */
2232 mh->mtSize = 0;
2233 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2234 trace("hmf %p\n", hmf);
2235 ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2236
2237 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2238 {
2239 dump_mf_bits(hmf, "mf_Graphics");
2240 EnumMetaFile(0, hmf, mf_enum_proc, 0);
2241 }
2242
2243 ret = DeleteMetaFile(hmf);
2244 ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2245 #endif
2246 }
2247
2248 /* Simple APIs from mfdrv/graphics.c
2249 */
2250
2251 static void test_mf_Graphics(void)
2252 {
2253 HDC hdcMetafile;
2254 HMETAFILE hMetafile;
2255 POINT oldpoint;
2256 BOOL ret;
2257
2258 hdcMetafile = CreateMetaFileA(NULL);
2259 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2260 trace("hdcMetafile %p\n", hdcMetafile);
2261
2262 ret = MoveToEx(hdcMetafile, 1, 1, NULL);
2263 ok( ret, "MoveToEx error %d.\n", GetLastError());
2264 ret = LineTo(hdcMetafile, 2, 2);
2265 ok( ret, "LineTo error %d.\n", GetLastError());
2266 ret = MoveToEx(hdcMetafile, 1, 1, &oldpoint);
2267 ok( ret, "MoveToEx error %d.\n", GetLastError());
2268
2269 /* oldpoint gets garbage under Win XP, so the following test would
2270 * work u