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