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 MF_LINETO_BITS[] = {
1126     0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1127     0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1128     0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1129     0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1130     0x00, 0x00
1131 };
1132 
1133 static const unsigned char EMF_LINETO_BITS[] = {
1134     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1135     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1136     0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1137     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1138     0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00,
1139     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1140     0x38, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1141     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143     0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1144     0x7c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1145     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1146     0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0x05, 0x00,
1147     0xe0, 0x93, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00,
1148     0x48, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1149     0x47, 0x44, 0x49, 0x43, 0x01, 0x00, 0x00, 0x80,
1150     0x00, 0x03, 0x00, 0x00, 0x60, 0xe5, 0xf4, 0x73,
1151     0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1152     0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x11, 0x00,
1153     0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1154     0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
1155     0x0f, 0x00, 0x37, 0x00, 0x03, 0x00, 0x00, 0x00,
1156     0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1157     0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1158     0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1159     0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1160     0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1161     0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1162     0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1163     0x37, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1164     0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1165     0x07, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x00,
1166     0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
1167     0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1168     0x0f, 0x00, 0x00, 0x80, 0x4b, 0x00, 0x00, 0x00,
1169     0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1170     0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1171     0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1172     0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
1173 };
1174 
1175 static const unsigned char EMF_LINETO_MM_ANISOTROPIC_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     0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 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, 0xa4, 0xfe, 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     0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1202     0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1203     0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 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_TEXT_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     0x61, 0x06, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00,
1223     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1224     0xe4, 0x00, 0x00, 0x00, 0x09, 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, 0x0b, 0x00, 0x00, 0x00,
1232     0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
1233     0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1234     0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
1235     0x00, 0x04, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
1236     0x10, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
1237     0x0f, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1238     0x0c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80,
1239     0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1240     0x00, 0x00, 0x00, 0x80, 0x30, 0x00, 0x00, 0x00,
1241     0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x80,
1242     0x4b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1243     0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1244     0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1245     0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1246     0x14, 0x00, 0x00, 0x00
1247 };
1248 
1249 static const unsigned char EMF_BITBLT[] =
1250 {
1251     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1252     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253     0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1254     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1255     0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
1256     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1257     0x64, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1258     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1259     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1260     0x80, 0x07, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00,
1261     0xfc, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00,
1262     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1263     0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
1264     0x30, 0xda, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00,
1265     0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1266     0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1267     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1268     0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1269     0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0xcc, 0x00,
1270     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271     0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
1272     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
1273     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1274     0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1275     0x64, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1276     0x8c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1277     0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1278     0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
1279     0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1280     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1282     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1283     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1284     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1285     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1286     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1287     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1288     0x4c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1289     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1290     0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1291     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1292     0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1293     0x62, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1294     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
1295     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1296     0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
1297     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1298     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1299     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1300     0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
1301     0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1302     0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1303     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1304     0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1305     0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0xcc, 0x00,
1306     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307     0x0a, 0xd7, 0xa3, 0x3b, 0x00, 0x00, 0x00, 0x00,
1308     0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0x23, 0x3c,
1309     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310     0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
1311     0x6c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1312     0x94, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1313     0x90, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
1314     0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1315     0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
1316     0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1317     0x00, 0x00, 0x00, 0x00, 0x00, 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     0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1326     0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1327     0x14, 0x00, 0x00, 0x00
1328 };
1329 
1330 static const unsigned char EMF_DCBRUSH_BITS[] =
1331 {
1332     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1333     0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1334     0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1335     0x39, 0x01, 0x00, 0x00, 0x39, 0x01, 0x00, 0x00,
1336     0x52, 0x02, 0x00, 0x00, 0x52, 0x02, 0x00, 0x00,
1337     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1338     0x44, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1339     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1341     0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
1342     0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
1343     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344     0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
1345     0x80, 0xa9, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00,
1346     0x0c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x80,
1347     0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1348     0x13, 0x00, 0x00, 0x80, 0x27, 0x00, 0x00, 0x00,
1349     0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1350     0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x00,
1351     0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1352     0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1353     0x26, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
1354     0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1355     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1356     0x33, 0x44, 0x55, 0x00, 0x25, 0x00, 0x00, 0x00,
1357     0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1358     0x2b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
1359     0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1360     0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1361     0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1362     0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1363     0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1364     0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x00,
1365     0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1366     0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1367     0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1368     0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1369     0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1370     0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1371     0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1372     0x14, 0x00, 0x00, 0x00
1373 };
1374 
1375 static const unsigned char EMF_BEZIER_BITS[] =
1376 {
1377     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1378     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1379     0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1380     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381     0x1a, 0x2a, 0x0d, 0x00, 0x1a, 0x2f, 0x0d, 0x00,
1382     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1383     0x44, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1384     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1385     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1386     0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1387     0x51, 0x01, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00,
1388     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1389     0x00, 0x00, 0x00, 0x00, 0x68, 0x24, 0x05, 0x00,
1390     0xb0, 0x1e, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
1391     0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1392     0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1393     0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1394     0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00,
1395     0x0f, 0x00, 0x0f, 0x00, 0x55, 0x00, 0x00, 0x00,
1396     0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1397     0x0a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1398     0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1399     0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x14, 0x00,
1400     0x0f, 0x00, 0x0f, 0x00, 0x19, 0x00, 0x19, 0x00,
1401     0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
1402     0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1403     0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1404     0x04, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1405     0x01, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1406     0x14, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1407     0x0f, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1408     0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1409     0x34, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1410     0x0f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1411     0x01, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1412     0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
1413     0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1414     0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1415     0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1416     0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1417     0x14, 0x00, 0x00, 0x00
1418 };
1419 
1420 static const unsigned char EMF_POLYPOLYLINE_BITS[] =
1421 {
1422     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1423     0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1424     0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1425     0x61, 0x01, 0x00, 0x00, 0xc2, 0x02, 0x00, 0x00,
1426     0x7a, 0xd4, 0x13, 0x00, 0xe8, 0x44, 0x00, 0x00,
1427     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1428     0x84, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1429     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1430     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431     0xa1, 0x05, 0x00, 0x00, 0x47, 0x03, 0x00, 0x00,
1432     0xfc, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
1433     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434     0x00, 0x00, 0x00, 0x00, 0xc0, 0xc1, 0x07, 0x00,
1435     0x2c, 0x84, 0x04, 0x00, 0x5a, 0x00, 0x00, 0x00,
1436     0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1437     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1438     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
1439     0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
1440     0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1441     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
1442     0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
1443     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1444     0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00,
1445     0x5a, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1446     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1448     0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1449     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1450     0x0a, 0x00, 0x14, 0x00, 0x64, 0x00, 0xc8, 0x00,
1451     0x07, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
1452     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1453     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1454     0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1455     0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1456     0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1457     0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
1458     0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1459     0x07, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
1460     0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1461     0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1462     0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1463     0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1464     0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1465     0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
1466     0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
1467     0x90, 0x01, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
1468     0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1469     0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1470     0x14, 0x00, 0x00, 0x00
1471 };
1472 
1473 static const unsigned char EMF_GRADIENTFILL_BITS[] =
1474 {
1475     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
1476     0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1477     0x2b, 0x01, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00,
1478     0x23, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00,
1479     0x31, 0x29, 0x00, 0x00, 0xa3, 0x2a, 0x00, 0x00,
1480     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
1481     0x0c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1482     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1484     0x40, 0x05, 0x00, 0x00, 0x46, 0x03, 0x00, 0x00,
1485     0xda, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
1486     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1487     0x00, 0x00, 0x00, 0x00, 0x15, 0x3c, 0x07, 0x00,
1488     0xcb, 0x82, 0x04, 0x00, 0x76, 0x00, 0x00, 0x00,
1489     0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1490     0x0a, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00,
1491     0x35, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1492     0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1493     0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1494     0x00, 0xff, 0x00, 0x80, 0x00, 0x00, 0x01, 0x80,
1495     0xc8, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00,
1496     0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
1497     0xb4, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00,
1498     0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, 0xf0, 0xde,
1499     0x2c, 0x01, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
1500     0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
1501     0x90, 0x01, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00,
1502     0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
1503     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1504     0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1505     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 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 /* For debugging or dumping the raw metafiles produced by
1512  * new test functions.
1513  */
1514 static INT CALLBACK mf_enum_proc(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
1515                                  INT nobj, LPARAM param)
1516 {
1517     trace("hdc %p, mr->rdFunction %04x, mr->rdSize %u, param %p\n",
1518            hdc, mr->rdFunction, mr->rdSize, (void *)param);
1519     return TRUE;
1520 }
1521 
1522 /* For debugging or dumping the raw metafiles produced by
1523  * new test functions.
1524  */
1525 
1526 static void dump_mf_bits (const HMETAFILE mf, const char *desc)
1527 {
1528     BYTE buf[MF_BUFSIZE];
1529     UINT mfsize, i;
1530 
1531     if (!winetest_debug) return;
1532 
1533     mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
1534     ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
1535 
1536     printf ("MetaFile %s has bits:\n{\n    ", desc);
1537     for (i=0; i<mfsize; i++)
1538     {
1539         printf ("0x%02x", buf[i]);
1540         if (i == mfsize-1)
1541             printf ("\n");
1542         else if (i % 8 == 7)
1543             printf (",\n    ");
1544         else
1545             printf (", ");
1546     }
1547     printf ("};\n");
1548 }
1549 
1550 /* Compare the metafile produced by a test function with the
1551  * expected raw metafile data in "bits".
1552  * Return value is 0 for a perfect match,
1553  * -1 if lengths aren't equal,
1554  * otherwise returns the number of non-matching bytes.
1555  */
1556 
1557 static int compare_mf_bits (const HMETAFILE mf, const unsigned char *bits, UINT bsize,
1558     const char *desc)
1559 {
1560     unsigned char buf[MF_BUFSIZE];
1561     UINT mfsize, i;
1562     int diff;
1563 
1564     mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
1565     ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
1566     if (mfsize < MF_BUFSIZE)
1567         ok (mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n",
1568             desc, mfsize, bsize);
1569     else
1570         ok (bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d.\n",
1571             desc, mfsize, bsize);
1572     if (mfsize != bsize)
1573         return -1;
1574 
1575     diff = 0;
1576     for (i=0; i<bsize; i++)
1577     {
1578        if (buf[i] !=  bits[i])
1579            diff++;
1580     }
1581     ok (diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
1582         desc, mfsize, bsize, diff);
1583 
1584     return diff;
1585 }
1586 
1587 static int compare_mf_disk_bits(LPCSTR name, const BYTE *bits, UINT bsize, const char *desc)
1588 {
1589     unsigned char buf[MF_BUFSIZE];
1590     DWORD mfsize, rd_size, i;
1591     int diff;
1592     HANDLE hfile;
1593     BOOL ret;
1594 
1595     hfile = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1596     assert(hfile != INVALID_HANDLE_VALUE);
1597 
1598     mfsize = GetFileSize(hfile, NULL);
1599     assert(mfsize <= MF_BUFSIZE);
1600 
1601     ret = ReadFile(hfile, buf, sizeof(buf), &rd_size, NULL);
1602     ok( ret && rd_size == mfsize, "ReadFile: error %d\n", GetLastError());
1603 
1604     CloseHandle(hfile);
1605 
1606     ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n", desc, mfsize, bsize);
1607 
1608     if (mfsize != bsize)
1609         return -1;
1610 
1611     diff = 0;
1612     for (i=0; i<bsize; i++)
1613     {
1614         if (buf[i] != bits[i])
1615             diff++;
1616     }
1617     ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
1618         desc, mfsize, bsize, diff);
1619 
1620     return diff;
1621 }
1622 
1623 /* For debugging or dumping the raw EMFs produced by
1624  * new test functions.
1625  */
1626 static void dump_emf_bits(const HENHMETAFILE mf, const char *desc)
1627 {
1628     BYTE buf[MF_BUFSIZE];
1629     UINT mfsize, i;
1630 
1631     if (!winetest_debug) return;
1632 
1633     mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1634     ok (mfsize > 0, "%s: GetEnhMetaFileBits failed\n", desc);
1635 
1636     printf("EMF %s has bits:\n{\n    ", desc);
1637     for (i = 0; i < mfsize; i++)
1638     {
1639         printf ("0x%02x", buf[i]);
1640         if (i == mfsize-1)
1641             printf ("\n");
1642         else if (i % 8 == 7)
1643             printf (",\n    ");
1644         else
1645             printf (", ");
1646     }
1647     printf ("};\n");
1648 }
1649 
1650 static void dump_emf_records(const HENHMETAFILE mf, const char *desc)
1651 {
1652     BYTE *emf;
1653     BYTE buf[MF_BUFSIZE];
1654     UINT mfsize, offset;
1655 
1656     if (!winetest_debug) return;
1657 
1658     mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1659     ok (mfsize > 0, "%s: GetEnhMetaFileBits error %d\n", desc, GetLastError());
1660 
1661     printf("EMF %s has records:\n", desc);
1662 
1663     emf = buf;
1664     offset = 0;
1665     while(offset < mfsize)
1666     {
1667         EMR *emr = (EMR *)(emf + offset);
1668         printf("emr->iType %d, emr->nSize %u\n", emr->iType, emr->nSize);
1669         /*trace("emr->iType 0x%04lx, emr->nSize 0x%04lx\n", emr->iType, emr->nSize);*/
1670         offset += emr->nSize;
1671     }
1672 }
1673 
1674 static void dump_emf_record(const ENHMETARECORD *emr, const char *desc)
1675 {
1676     const BYTE *buf;
1677     DWORD i;
1678 
1679     if (!winetest_debug) return;
1680 
1681     printf ("%s: EMF record %u has bits:\n{\n", desc, emr->iType);
1682     buf = (const BYTE *)emr;
1683     for (i = 0; i < emr->nSize; i++)
1684     {
1685         printf ("0x%02x", buf[i]);
1686         if (i == emr->nSize - 1)
1687             printf ("\n");
1688         else if (i % 8 == 7)
1689             printf (",\n");
1690         else
1691             printf (", ");
1692     }
1693     printf ("};\n");
1694 }
1695 
1696 static void dump_EMREXTTEXTOUT(const EMREXTTEXTOUTW *eto)
1697 {
1698     trace("rclBounds %d,%d - %d,%d\n", eto->rclBounds.left, eto->rclBounds.top,
1699           eto->rclBounds.right, eto->rclBounds.bottom);
1700     trace("iGraphicsMode %u\n", eto->iGraphicsMode);
1701     trace("exScale: %f\n", eto->exScale);
1702     trace("eyScale: %f\n", eto->eyScale);
1703     trace("emrtext.ptlReference %d,%d\n", eto->emrtext.ptlReference.x, eto->emrtext.ptlReference.y);
1704     trace("emrtext.nChars %u\n", eto->emrtext.nChars);
1705     trace("emrtext.offString %#x\n", eto->emrtext.offString);
1706     trace("emrtext.fOptions %#x\n", eto->emrtext.fOptions);
1707     trace("emrtext.rcl %d,%d - %d,%d\n", eto->emrtext.rcl.left, eto->emrtext.rcl.top,
1708           eto->emrtext.rcl.right, eto->emrtext.rcl.bottom);
1709     trace("emrtext.offDx %#x\n", eto->emrtext.offDx);
1710 }
1711 
1712 static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr2,
1713                              const char *desc, BOOL ignore_scaling)
1714 {
1715     int diff;
1716 
1717     ok(emr1->iType == emr2->iType, "%s: emr->iType %u != %u\n",
1718        desc, emr1->iType, emr2->iType);
1719 
1720     ok(emr1->nSize == emr2->nSize, "%s: emr->nSize %u != %u\n",
1721        desc, emr1->nSize, emr2->nSize);
1722 
1723     /* iType and nSize mismatches are fatal */
1724     if (emr1->iType != emr2->iType || emr1->nSize != emr2->nSize) return FALSE;
1725 
1726     /* contents of EMR_GDICOMMENT are not interesting */
1727     if (emr1->iType == EMR_GDICOMMENT) return TRUE;
1728 
1729     /* different Windows versions setup DC scaling differently when
1730      * converting an old style metafile to an EMF.
1731      */
1732     if (ignore_scaling && (emr1->iType == EMR_SETWINDOWEXTEX ||
1733                            emr1->iType == EMR_SETVIEWPORTEXTEX))
1734         return TRUE;
1735 
1736     if (emr1->iType == EMR_EXTTEXTOUTW || emr1->iType == EMR_EXTTEXTOUTA)
1737     {
1738         EMREXTTEXTOUTW *eto1, *eto2;
1739 
1740         eto1 = HeapAlloc(GetProcessHeap(), 0, emr1->nSize);
1741         memcpy(eto1, emr1, emr1->nSize);
1742         eto2 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
1743         memcpy(eto2, emr2, emr2->nSize);
1744 
1745         /* different Windows versions setup DC scaling differently */
1746         eto1->exScale = eto1->eyScale = 0.0;
1747         eto2->exScale = eto2->eyScale = 0.0;
1748 
1749         diff = memcmp(eto1, eto2, emr1->nSize);
1750         if (diff)
1751         {
1752             dump_EMREXTTEXTOUT(eto1);
1753             dump_EMREXTTEXTOUT(eto2);
1754         }
1755         HeapFree(GetProcessHeap(), 0, eto1);
1756         HeapFree(GetProcessHeap(), 0, eto2);
1757     }
1758     else if (emr1->iType == EMR_EXTSELECTCLIPRGN && !lstrcmpA(desc, "emf_clipping"))
1759     {
1760         /* We have to take care of NT4 differences here */
1761         diff = memcmp(emr1, emr2, emr1->nSize);
1762         if (diff)
1763         {
1764             ENHMETARECORD *emr_nt4;
1765 
1766             emr_nt4 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
1767             memcpy(emr_nt4, emr2, emr2->nSize);
1768             /* Correct the nRgnSize field */
1769             emr_nt4->dParm[5] = sizeof(RECT);
1770 
1771             diff = memcmp(emr1, emr_nt4, emr1->nSize);
1772             if (!diff)
1773                 win_skip("Catered for NT4 differences\n");
1774 
1775             HeapFree(GetProcessHeap(), 0, emr_nt4);
1776         }
1777     }
1778     else if (emr1->iType == EMR_POLYBEZIERTO16 || emr1->iType == EMR_POLYBEZIER16)
1779     {
1780         EMRPOLYBEZIER16 *eto1, *eto2;
1781 
1782         eto1 = (EMRPOLYBEZIER16*)emr1;
1783         eto2 = (EMRPOLYBEZIER16*)emr2;
1784 
1785         diff = eto1->cpts != eto2->cpts;
1786         if(!diff)
1787             diff = memcmp(eto1->apts, eto2->apts, eto1->cpts * sizeof(POINTS));
1788     }
1789     else if (emr1->iType == EMR_POLYBEZIERTO || emr1->iType == EMR_POLYBEZIER)
1790     {
1791         EMRPOLYBEZIER *eto1, *eto2;
1792 
1793         eto1 = (EMRPOLYBEZIER*)emr1;
1794         eto2 = (EMRPOLYBEZIER*)emr2;
1795 
1796         diff = eto1->cptl != eto2->cptl;
1797         if(!diff)
1798             diff = memcmp(eto1->aptl, eto2->aptl, eto1->cptl * sizeof(POINTL));
1799     }
1800     else
1801         diff = memcmp(emr1, emr2, emr1->nSize);
1802 
1803     ok(diff == 0, "%s: contents of record %u don't match\n", desc, emr1->iType);
1804 
1805     if (diff)
1806     {
1807         dump_emf_record(emr1, "expected bits");
1808         dump_emf_record(emr2, "actual bits");
1809     }
1810 
1811     return diff == 0; /* report all non-fatal record mismatches */
1812 }
1813 
1814 /* Compare the EMF produced by a test function with the
1815  * expected raw EMF data in "bits".
1816  * Return value is 0 for a perfect match,
1817  * -1 if lengths aren't equal,
1818  * otherwise returns the number of non-matching bytes.
1819  */
1820 static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
1821                             UINT bsize, const char *desc,
1822                             BOOL ignore_scaling)
1823 {
1824     unsigned char buf[MF_BUFSIZE];
1825     UINT mfsize, offset1, offset2, diff_nt4, diff_9x;
1826     const ENHMETAHEADER *emh1, *emh2;
1827 
1828     mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
1829     ok (mfsize > 0, "%s: GetEnhMetaFileBits error %d\n", desc, GetLastError());
1830 
1831     /* ENHMETAHEADER size could differ, depending on platform */
1832     diff_nt4 = sizeof(SIZEL);
1833     diff_9x = sizeof(SIZEL) + 3 * sizeof(DWORD);
1834 
1835     if (mfsize < MF_BUFSIZE)
1836     {
1837         ok(mfsize == bsize ||
1838            broken(mfsize == bsize - diff_nt4) ||  /* NT4 */
1839            broken(mfsize == bsize - diff_9x), /* Win9x/WinME */
1840            "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize);
1841     }
1842     else
1843         ok(bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d\n",
1844            desc, mfsize, bsize);
1845 
1846     /* basic things must match */
1847     emh1 = (const ENHMETAHEADER *)bits;
1848     emh2 = (const ENHMETAHEADER *)buf;
1849     ok(emh1->iType == EMR_HEADER, "expected EMR_HEADER, got %u\n", emh1->iType);
1850     ok(emh1->nSize == sizeof(ENHMETAHEADER), "expected sizeof(ENHMETAHEADER), got %u\n", emh1->nSize);
1851     ok(emh2->nBytes == mfsize, "expected emh->nBytes %u, got %u\n", mfsize, emh2->nBytes);
1852     ok(emh1->dSignature == ENHMETA_SIGNATURE, "expected ENHMETA_SIGNATURE, got %u\n", emh1->dSignature);
1853 
1854     ok(emh1->iType == emh2->iType, "expected EMR_HEADER, got %u\n", emh2->iType);
1855     ok(emh1->nSize == emh2->nSize ||
1856        broken(emh1->nSize - diff_nt4 == emh2->nSize) ||
1857        broken(emh1->nSize - diff_9x == emh2->nSize),
1858        "expected nSize %u, got %u\n", emh1->nSize, emh2->nSize);
1859     ok(emh1->rclBounds.left == emh2->rclBounds.left, "%s: expected rclBounds.left = %d, got %d\n",
1860             desc, emh1->rclBounds.left, emh2->rclBounds.left);
1861     ok(emh1->rclBounds.top == emh2->rclBounds.top, "%s: expected rclBounds.top = %d, got %d\n",
1862             desc, emh1->rclBounds.top, emh2->rclBounds.top);
1863     ok(emh1->rclBounds.right == emh2->rclBounds.right, "%s: expected rclBounds.right = %d, got %d\n",
1864             desc, emh1->rclBounds.right, emh2->rclBounds.right);
1865     ok(emh1->rclBounds.bottom == emh2->rclBounds.bottom, "%s: expected rclBounds.bottom = %d, got %d\n",
1866             desc, emh1->rclBounds.bottom, emh2->rclBounds.bottom);
1867     ok(emh1->dSignature == emh2->dSignature, "expected dSignature %u, got %u\n", emh1->dSignature, emh2->dSignature);
1868     ok(emh1->nBytes == emh2->nBytes ||
1869        broken(emh1->nBytes - diff_nt4 == emh2->nBytes) ||
1870        broken(emh1->nBytes - diff_9x == emh2->nBytes),
1871        "expected nBytes %u, got %u\n", emh1->nBytes, emh2->nBytes);
1872     ok(emh1->nRecords == emh2->nRecords, "expected nRecords %u, got %u\n", emh1->nRecords, emh2->nRecords);
1873 
1874     offset1 = emh1->nSize;
1875     offset2 = emh2->nSize; /* Needed for Win9x/WinME/NT4 */
1876     while (offset1 < emh1->nBytes)
1877     {
1878         const ENHMETARECORD *emr1 = (const ENHMETARECORD *)(bits + offset1);
1879         const ENHMETARECORD *emr2 = (const ENHMETARECORD *)(buf + offset2);
1880 
1881         trace("%s: EMF record %u, size %u/record %u, size %u\n",
1882               desc, emr1->iType, emr1->nSize, emr2->iType, emr2->nSize);
1883 
1884         if (!match_emf_record(emr1, emr2, desc, ignore_scaling)) return -1;
1885 
1886         /* We have already bailed out if iType or nSize don't match */
1887         offset1 += emr1->nSize;
1888         offset2 += emr2->nSize;
1889     }
1890     return 0;
1891 }
1892 
1893 
1894 /* tests blitting to an EMF */
1895 static void test_emf_BitBlt(void)
1896 {
1897     HDC hdcDisplay, hdcMetafile, hdcBitmap;
1898     HBITMAP hBitmap, hOldBitmap;
1899     HENHMETAFILE hMetafile;
1900 #define BMP_DIM 4
1901     BITMAPINFOHEADER bmih =
1902     {
1903         sizeof(BITMAPINFOHEADER),
1904         BMP_DIM,/* biWidth */
1905         BMP_DIM,/* biHeight */
1906         1,      /* biPlanes */
1907         24,     /* biBitCount */
1908         BI_RGB, /* biCompression */
1909         0,      /* biXPelsPerMeter */
1910         0,      /* biYPelsPerMeter */
1911         0,      /* biClrUsed */
1912         0,      /* biClrImportant */
1913     };
1914     void *bits;
1915     XFORM xform;
1916     BOOL ret;
1917 
1918     hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL);
1919     ok( hdcDisplay != 0, "CreateDCA error %d\n", GetLastError() );
1920 
1921     hdcBitmap = CreateCompatibleDC(hdcDisplay);
1922     ok( hdcBitmap != 0, "CreateCompatibleDC failed\n" );
1923     ok(SetGraphicsMode(hdcBitmap, GM_ADVANCED), "SetGraphicsMode failed\n");
1924     bmih.biXPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSX), 100, 3937);
1925     bmih.biYPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSY), 100, 3937);
1926     hBitmap = CreateDIBSection(hdcDisplay, (const BITMAPINFO *)&bmih,
1927                                DIB_RGB_COLORS, &bits, NULL, 0);
1928     hOldBitmap = SelectObject(hdcBitmap, hBitmap);
1929 
1930     hdcMetafile = CreateEnhMetaFileA(hdcBitmap, NULL, NULL, NULL);
1931     ok( hdcMetafile != 0, "CreateEnhMetaFileA failed\n" );
1932 
1933     /* First fill the bitmap DC with something recognizable, like BLACKNESS */
1934     ret = BitBlt(hdcBitmap, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, BLACKNESS);
1935     ok( ret, "BitBlt(BLACKNESS) failed\n" );
1936 
1937     ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, hdcBitmap, 0, 0, SRCCOPY);
1938     ok( ret, "BitBlt(SRCCOPY) failed\n" );
1939     ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, WHITENESS);
1940     ok( ret, "BitBlt(WHITENESS) failed\n" );
1941 
1942     ok(SetMapMode(hdcBitmap, MM_ANISOTROPIC), "SetMapMode failed\n");
1943     ok(SetWindowOrgEx(hdcBitmap, 0, 0, NULL), "SetWindowOrgEx failed\n");
1944     ok(SetWindowExtEx(hdcBitmap, 400, 400, NULL), "SetWindowExtEx failed\n");
1945     ok(SetViewportOrgEx(hdcBitmap, 0, 0, NULL), "SetViewportOrgEx failed\n");
1946     ok(SetViewportExtEx(hdcBitmap, BMP_DIM, BMP_DIM, NULL), "SetViewportExtEx failed\n");
1947     memset(&xform, 0, sizeof(xform));
1948     xform.eM11 = 0.5;
1949     xform.eM22 = 1.0;
1950     ok(SetWorldTransform(hdcBitmap, &xform), "SetWorldTransform failed\n");
1951 
1952     ret = StretchBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, hdcBitmap, 0, 0, 400, 400, SRCCOPY);
1953     ok( ret, "StretchBlt(SRCCOPY) failed\n" );
1954 
1955     hMetafile = CloseEnhMetaFile(hdcMetafile);
1956     ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
1957 
1958     if(compare_emf_bits(hMetafile, EMF_BITBLT, sizeof(EMF_BITBLT),
1959         "emf_BitBlt", FALSE) != 0)
1960     {
1961         dump_emf_bits(hMetafile, "emf_BitBlt");
1962         dump_emf_records(hMetafile, "emf_BitBlt");
1963     }
1964 
1965     SelectObject(hdcBitmap, hOldBitmap);
1966     DeleteObject(hBitmap);
1967     DeleteDC(hdcBitmap);
1968     DeleteDC(hdcDisplay);
1969 #undef BMP_DIM
1970 }
1971 
1972 static void test_emf_DCBrush(void)
1973 {
1974     HDC hdcMetafile;
1975     HENHMETAFILE hMetafile;
1976     HBRUSH hBrush;
1977     HPEN hPen;
1978     BOOL ret;
1979     COLORREF color;
1980 
1981     if (!pSetDCBrushColor || !pSetDCPenColor)
1982     {
1983         win_skip( "SetDCBrush/PenColor not supported\n" );
1984         return;
1985     }
1986 
1987     hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
1988     ok( hdcMetafile != 0, "CreateEnhMetaFileA failed\n" );
1989 
1990     hBrush = SelectObject(hdcMetafile, GetStockObject(DC_BRUSH));
1991     ok(hBrush != 0, "SelectObject error %d.\n", GetLastError());
1992 
1993     hPen = SelectObject(hdcMetafile, GetStockObject(DC_PEN));
1994     ok(hPen != 0, "SelectObject error %d.\n", GetLastError());
1995 
1996     color = pSetDCBrushColor( hdcMetafile, RGB(0x55,0x55,0x55) );
1997     ok( color == 0xffffff, "SetDCBrushColor returned %x\n", color );
1998 
1999     color = pSetDCPenColor( hdcMetafile, RGB(0x33,0x44,0x55) );
2000     ok( color == 0, "SetDCPenColor returned %x\n", color );
2001 
2002     Rectangle( hdcMetafile, 10, 10, 20, 20 );
2003 
2004     color = pSetDCBrushColor( hdcMetafile, RGB(0x12,0x34,0x56) );
2005     ok( color == 0x555555, "SetDCBrushColor returned %x\n", color );
2006 
2007     hMetafile = CloseEnhMetaFile(hdcMetafile);
2008     ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
2009 
2010     if (compare_emf_bits (hMetafile, EMF_DCBRUSH_BITS, sizeof(EMF_DCBRUSH_BITS),
2011                           "emf_DC_Brush", FALSE ) != 0)
2012     {
2013         dump_emf_bits(hMetafile, "emf_DC_Brush");
2014         dump_emf_records(hMetafile, "emf_DC_Brush");
2015     }
2016     ret = DeleteEnhMetaFile(hMetafile);
2017     ok( ret, "DeleteEnhMetaFile error %d\n", GetLastError());
2018     ret = DeleteObject(hBrush);
2019     ok( ret, "DeleteObject(HBRUSH) error %d\n", GetLastError());
2020     ret = DeleteObject(hPen);
2021     ok( ret, "DeleteObject(HPEN) error %d\n", GetLastError());
2022 }
2023 
2024 /* Test a blank metafile.  May be used as a template for new tests. */
2025 
2026 static void test_mf_Blank(void)
2027 {
2028     HDC hdcMetafile;
2029     HMETAFILE hMetafile;
2030     INT caps;
2031     BOOL ret;
2032     INT type;
2033 
2034     hdcMetafile = CreateMetaFileA(NULL);
2035     ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2036     trace("hdcMetafile %p\n", hdcMetafile);
2037 
2038 /* Tests on metafile initialization */
2039     caps = GetDeviceCaps (hdcMetafile, TECHNOLOGY);
2040     ok (caps == DT_METAFILE,
2041         "GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE.\n", caps);
2042 
2043     hMetafile = CloseMetaFile(hdcMetafile);
2044     ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2045     type = GetObjectType(hMetafile);
2046     ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
2047     ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
2048 
2049     if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
2050         "mf_blank") != 0)
2051     {
2052         dump_mf_bits(hMetafile, "mf_Blank");
2053         EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2054     }
2055 
2056     ret = DeleteMetaFile(hMetafile);
2057     ok( ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2058 }
2059 
2060 static void test_CopyMetaFile(void)
2061 {
2062     HDC hdcMetafile;
2063     HMETAFILE hMetafile, hmf_copy;
2064     BOOL ret;
2065     char temp_path[MAX_PATH];
2066     char mf_name[MAX_PATH];
2067     INT type;
2068 
2069     hdcMetafile = CreateMetaFileA(NULL);
2070     ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2071     trace("hdcMetafile %p\n", hdcMetafile);
2072 
2073     hMetafile = CloseMetaFile(hdcMetafile);
2074     ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2075     type = GetObjectType(hMetafile);
2076     ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
2077 
2078     if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
2079         "mf_blank") != 0)
2080     {
2081         dump_mf_bits(hMetafile, "mf_Blank");
2082         EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2083     }
2084 
2085     GetTempPathA(MAX_PATH, temp_path);
2086     GetTempFileNameA(temp_path, "wmf", 0, mf_name);
2087 
2088     hmf_copy = CopyMetaFileA(hMetafile, mf_name);
2089     ok(hmf_copy != 0, "CopyMetaFile error %d\n", GetLastError());
2090 
2091     type = GetObjectType(hmf_copy);
2092     ok(type == OBJ_METAFILE, "CopyMetaFile created object with type %d\n", type);
2093 
2094     ret = DeleteMetaFile(hMetafile);
2095     ok( ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2096 
2097     if (compare_mf_disk_bits(mf_name, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0)
2098     {
2099         dump_mf_bits(hmf_copy, "mf_Blank");
2100         EnumMetaFile(0, hmf_copy, mf_enum_proc, 0);
2101     }
2102 
2103     ret = DeleteMetaFile(hmf_copy);
2104     ok( ret, "DeleteMetaFile(%p) error %d\n", hmf_copy, GetLastError());
2105 
2106     DeleteFileA(mf_name);
2107 }
2108 
2109 static void test_SetMetaFileBits(void)
2110 {
2111     HMETAFILE hmf;
2112     INT type;
2113     BOOL ret;
2114     BYTE buf[256];
2115     METAHEADER *mh;
2116 
2117     hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), MF_GRAPHICS_BITS);
2118     trace("hmf %p\n", hmf);
2119     ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2120     type = GetObjectType(hmf);
2121     ok(type == OBJ_METAFILE, "SetMetaFileBitsEx created object with type %d\n", type);
2122 
2123     if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2124     {
2125         dump_mf_bits(hmf, "mf_Graphics");
2126         EnumMetaFile(0, hmf, mf_enum_proc, 0);
2127     }
2128 
2129     ret = DeleteMetaFile(hmf);
2130     ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2131 
2132     /* NULL data crashes XP SP1 */
2133     /*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/
2134 
2135     /* Now with zero size */
2136     SetLastError(0xdeadbeef);
2137     hmf = SetMetaFileBitsEx(0, MF_GRAPHICS_BITS);
2138     trace("hmf %p\n", hmf);
2139     ok(!hmf, "SetMetaFileBitsEx should fail\n");
2140     ok(GetLastError() == ERROR_INVALID_DATA ||
2141        broken(GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2142        "wrong error %d\n", GetLastError());
2143 
2144     /* Now with odd size */
2145     SetLastError(0xdeadbeef);
2146     hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS) - 1, MF_GRAPHICS_BITS);
2147     trace("hmf %p\n", hmf);
2148     ok(!hmf, "SetMetaFileBitsEx should fail\n");
2149     ok(GetLastError() == 0xdeadbeef /* XP SP1 */, "wrong error %d\n", GetLastError());
2150 
2151     /* Now with zeroed out header fields */
2152     assert(sizeof(buf) >= sizeof(MF_GRAPHICS_BITS));
2153     memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
2154     mh = (METAHEADER *)buf;
2155     /* corruption of any of the below fields leads to a failure */
2156     mh->mtType = 0;
2157     mh->mtVersion = 0;
2158     mh->mtHeaderSize = 0;
2159     SetLastError(0xdeadbeef);
2160     hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2161     trace("hmf %p\n", hmf);
2162     ok(!hmf, "SetMetaFileBitsEx should fail\n");
2163     ok(GetLastError() == ERROR_INVALID_DATA ||
2164        broken(GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2165        "wrong error %d\n", GetLastError());
2166 
2167     /* Now with corrupted mtSize field */
2168     memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
2169     mh = (METAHEADER *)buf;
2170     /* corruption of mtSize doesn't lead to a failure */
2171     mh->mtSize *= 2;
2172     hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2173     trace("hmf %p\n", hmf);
2174     ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2175 
2176     if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2177     {
2178         dump_mf_bits(hmf, "mf_Graphics");
2179         EnumMetaFile(0, hmf, mf_enum_proc, 0);
2180     }
2181 
2182     ret = DeleteMetaFile(hmf);
2183     ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2184 
2185 #ifndef _WIN64 /* Generates access violation on XP x64 and Win2003 x64 */
2186     /* Now with zeroed out mtSize field */
2187     memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
2188     mh = (METAHEADER *)buf;
2189     /* zeroing mtSize doesn't lead to a failure */
2190     mh->mtSize = 0;
2191     hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
2192     trace("hmf %p\n", hmf);
2193     ok(hmf != 0, "SetMetaFileBitsEx error %d\n", GetLastError());
2194 
2195     if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
2196     {
2197         dump_mf_bits(hmf, "mf_Graphics");
2198         EnumMetaFile(0, hmf, mf_enum_proc, 0);
2199     }
2200 
2201     ret = DeleteMetaFile(hmf);
2202     ok(ret, "DeleteMetaFile(%p) error %d\n", hmf, GetLastError());
2203 #endif
2204 }
2205 
2206 /* Simple APIs from mfdrv/graphics.c
2207  */
2208 
2209 static void test_mf_Graphics(void)
2210 {
2211     HDC hdcMetafile;
2212     HMETAFILE hMetafile;
2213     POINT oldpoint;
2214     BOOL ret;
2215 
2216     hdcMetafile = CreateMetaFileA(NULL);
2217     ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2218     trace("hdcMetafile %p\n", hdcMetafile);
2219 
2220     ret = MoveToEx(hdcMetafile, 1, 1, NULL);
2221     ok( ret, "MoveToEx error %d.\n", GetLastError());
2222     ret = LineTo(hdcMetafile, 2, 2);
2223     ok( ret, "LineTo error %d.\n", GetLastError());
2224     ret = MoveToEx(hdcMetafile, 1, 1, &oldpoint);
2225     ok( ret, "MoveToEx error %d.\n", GetLastError());
2226 
2227 /* oldpoint gets garbage under Win XP, so the following test would
2228  * work under Wine but fails under Windows:
2229  *
2230  *   ok((oldpoint.x == 2) && (oldpoint.y == 2),
2231  *       "MoveToEx: (x, y) = (%ld, %ld), should be (2, 2).\n",
2232  *       oldpoint.x, oldpoint.y);
2233  */
2234 
2235     ret = Ellipse(hdcMetafile, 0, 0, 2, 2);
2236     ok( ret, "Ellipse error %d.\n", GetLastError());
2237 
2238     hMetafile = CloseMetaFile(hdcMetafile);
2239     ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2240     ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
2241 
2242     if (compare_mf_bits (hMetafile, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS),
2243         "mf_Graphics") != 0)
2244     {
2245         dump_mf_bits(hMetafile, "mf_Graphics");
2246         EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2247     }
2248 
2249     ret = DeleteMetaFile(hMetafile);
2250     ok( ret, "DeleteMetaFile(%p) error %d\n",
2251         hMetafile, GetLastError());
2252 }
2253 
2254 static void test_mf_PatternBrush(void)
2255 {
2256     HDC hdcMetafile;
2257     HMETAFILE hMetafile;
2258     LOGBRUSH *orig_lb;
2259     HBRUSH hBrush;
2260     BOOL ret;
2261 
2262     orig_lb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGBRUSH));
2263 
2264     orig_lb->lbStyle = BS_PATTERN;
2265     orig_lb->lbColor = RGB(0, 0, 0);
2266     orig_lb->lbHatch = (ULONG_PTR)CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH);
2267     ok((HBITMAP)orig_lb->lbHatch != NULL, "CreateBitmap error %d.\n", GetLastError());
2268 
2269     hBrush = CreateBrushIndirect (orig_lb);
2270     ok(hBrush != 0, "CreateBrushIndirect error %d\n", GetLastError());
2271 
2272     hdcMetafile = CreateMetaFileA(NULL);
2273     ok(hdcMetafile != 0, "CreateMetaFileA error %d\n", GetLastError());
2274     trace("hdcMetafile %p\n", hdcMetafile);
2275 
2276     hBrush = SelectObject(hdcMetafile, hBrush);
2277     ok(hBrush != 0, "SelectObject error %d.\n", GetLastError());
2278 
2279     hMetafile = CloseMetaFile(hdcMetafile);
2280     ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2281     ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
2282 
2283     if (compare_mf_bits (hMetafile, MF_PATTERN_BRUSH_BITS, sizeof(MF_PATTERN_BRUSH_BITS),
2284         "mf_Pattern_Brush") != 0)
2285     {
2286         dump_mf_bits(hMetafile, "mf_Pattern_Brush");
2287         EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2288     }
2289 
2290     ret = DeleteMetaFile(hMetafile);
2291     ok( ret, "DeleteMetaFile error %d\n", GetLastError());
2292     ret = DeleteObject(hBrush);
2293     ok( ret, "DeleteObject(HBRUSH) error %d\n", GetLastError());
2294     ret = DeleteObject((HBITMAP)orig_lb->lbHatch);
2295     ok( ret, "DeleteObject(HBITMAP) error %d\n",
2296         GetLastError());
2297     HeapFree (GetProcessHeap(), 0, orig_lb);
2298 }
2299 
2300 static void test_mf_DCBrush(void)
2301 {
2302     HDC hdcMetafile;
2303     HMETAFILE hMetafile;
2304     HBRUSH hBrush;
2305     HPEN hPen;
2306     BOOL ret;
2307     COLORREF color;
2308 
2309     if (!pSetDCBrushColor || !pSetDCPenColor)
2310     {
2311         win_skip( "SetDCBrush/PenColor not supported\n" );
2312         return;
2313     }
2314 
2315     hdcMetafile = CreateMetaFileA(NULL);
2316     ok( hdcMetafile != 0, "CreateMetaFileA failed\n" );
2317 
2318     hBrush = SelectObject(hdcMetafile, GetStockObject(DC_BRUSH));
2319     ok(hBrush != 0, "SelectObject error %d.\n", GetLastError());
2320 
2321     hPen = SelectObject(hdcMetafile, GetStockObject(DC_PEN));
2322     ok(hPen != 0, "SelectObject error %d.\n", GetLastError());
2323 
2324     color = pSetDCBrushColor( hdcMetafile, RGB(0x55,0x55,0x55) );
2325     ok( color == CLR_INVALID, "SetDCBrushColor returned %x\n", color );
2326 
2327     color = pSetDCPenColor( hdcMetafile, RGB(0x33,0x44,0x55) );
2328     ok( color == CLR_INVALID, "SetDCPenColor returned %x\n", color );
2329 
2330     Rectangle( hdcMetafile, 10, 10, 20, 20 );
2331 
2332     color = pSetDCBrushColor( hdcMetafile, RGB(0x12,0x34,0x56) );
2333     ok( color == CLR_INVALID, "SetDCBrushColor returned %x\n", color );
2334 
2335     hMetafile = CloseMetaFile(hdcMetafile);
2336     ok( hMetafile != 0, "CloseMetaFile failed\n" );
2337 
2338     if (compare_mf_bits(hMetafile, MF_DCBRUSH_BITS, sizeof(MF_DCBRUSH_BITS), "mf_DCBrush") != 0)
2339     {
2340         dump_mf_bits(hMetafile, "mf_DCBrush");
2341         EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2342     }
2343     ret = DeleteMetaFile(hMetafile);
2344     ok(ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2345 }
2346 
2347 static void test_mf_ExtTextOut_on_path(void)
2348 {
2349     HDC hdcMetafile;
2350     HMETAFILE hMetafile;
2351     BOOL ret;
2352     static const INT dx[4] = { 3, 5, 8, 12 };
2353 
2354     hdcMetafile = CreateMetaFileA(NULL);
2355     ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %d\n", GetLastError());
2356     trace("hdcMetafile %p\n", hdcMetafile);
2357 
2358     ret = BeginPath(hdcMetafile);
2359     ok(!ret, "BeginPath on metafile DC should fail\n");
2360 
2361     ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
2362     ok(ret, "ExtTextOut error %d\n", GetLastError());
2363 
2364     ret = EndPath(hdcMetafile);
2365     ok(!ret, "EndPath on metafile DC should fail\n");
2366 
2367     hMetafile = CloseMetaFile(hdcMetafile);
2368     ok(hMetafile != 0, "CloseMetaFile error %d\n", GetLastError());
2369 
2370     if (compare_mf_bits(hMetafile, MF_TEXTOUT_ON_PATH_BITS, sizeof(MF_TEXTOUT_ON_PATH_BITS),
2371         "mf_TextOut_on_path") != 0)
2372     {
2373         dump_mf_bits(hMetafile, "mf_TextOut_on_path");
2374         EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
2375     }
2376 
2377     ret = DeleteMetaFile(hMetafile);
2378     ok(ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
2379 }
2380 
2381 static void test_emf_ExtTextOut_on_path(void)
2382 {
2383     HWND hwnd;
2384     HDC hdcDisplay, hdcMetafile;
2385     HENHMETAFILE hMetafile;
2386     BOOL ret;
2387     static const INT dx[4] = { 3, 5, 8, 12 };
2388 
2389     /* Win9x doesn't play EMFs on invisible windows */
2390     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
2391                            0, 0, 200, 200, 0, 0, 0, NULL);
2392     ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
2393 
2394     hdcDisplay = GetDC(hwnd);
2395     ok(hdcDisplay != 0, "GetDC error %d\n", GetLastError());
2396 
2397     hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
2398     ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
2399 
2400     ret = BeginPath(hdcMetafile);
2401     ok(ret, "BeginPath error %d\n", GetLastError());
2402 
2403     ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
2404     todo_wine ok(ret, "ExtTextOut error %d\n", GetLastError());
2405 
2406     ret = EndPath(hdcMetafile);
2407     ok(ret, "EndPath error %d\n", GetLastError());
2408 
2409     hMetafile = CloseEnhMetaFile(hdcMetafile);
2410     ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
2411 
2412     /* this doesn't succeed yet: EMF has correct size, all EMF records
2413      * are there, but their contents don't match for different reasons.
2414      */
2415     if (compare_emf_bits(hMetafile, EMF_TEXTOUT_ON_PATH_BITS, sizeof(EMF_TEXTOUT_ON_PATH_BITS),
2416         "emf_TextOut_on_path", FALSE) != 0)
2417     {
2418         dump_emf_bits(hMetafile, "emf_TextOut_on_path");
2419         dump_emf_records(hMetafile, "emf_TextOut_on_path");
2420     }
2421 
2422     ret = DeleteEnhMetaFile(hMetafile);
2423     ok(ret, "DeleteEnhMetaFile error %d\n", GetLastError());
2424     ret = ReleaseDC(hwnd, hdcDisplay);
2425     ok(ret, "ReleaseDC error %d\n", GetLastError());
2426     DestroyWindow(hwnd);
2427 }
2428 
2429 static const unsigned char EMF_CLIPPING[] =
2430 {
2431     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
2432     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2433     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2434     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2435     0x1a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
2436     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
2437     0x04, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2438     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2439     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2440     0x80, 0x07, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00,
2441     0xfc, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00,
2442     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2443     0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
2444     0x30, 0xda, 0x04, 0x00, 0x36, 0x00, 0x00, 0x00,
2445     0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2446     0x01, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
2447     0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
2448     0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
2449     0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2450     0x10, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
2451     0x64, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
2452     0x00, 0x04, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
2453     0x64, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
2454     0x00, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
2455     0x08, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
2456     0x18, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
2457     0x64, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00,
2458     0xff, 0x03, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
2459     0x08, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
2460     0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2461     0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
2462     0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
2463     0x14, 0x00, 0x00, 0x00
2464 };
2465 
2466 static void translate( POINT *pt, UINT count, const XFORM *xform )
2467 {
2468     while (count--)
2469     {
2470         FLOAT x = (FLOAT)pt->x;
2471         FLOAT y = (FLOAT)pt->y;
2472         pt->x = (LONG)floor( x * xform->eM11 + y * xform->eM21 + xform->eDx + 0.5 );
2473         pt->y = (LONG)floor( x * xform->eM12 + y * xform->eM22 + xform->eDy + 0.5 );
2474         pt++;
2475     }
2476 }
2477 
2478 /* Compare rectangles allowing rounding errors */
2479 static BOOL is_equal_rect(const RECT *rc1, const RECT *rc2)
2480 {
2481     return abs(rc1->left - rc2->left) <= 1 &&
2482            abs(rc1->top - rc2->top) <= 1 &&
2483            abs(rc1->right - rc2->right) <= 1 &&
2484            abs(rc1->bottom - rc2->bottom) <= 1;
2485 }
2486 
2487 static int CALLBACK clip_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
2488                                        const ENHMETARECORD *emr, int n_objs, LPARAM param)
2489 {
2490     if (emr->iType == EMR_EXTSELECTCLIPRGN)
2491     {
2492         const EMREXTSELECTCLIPRGN *clip = (const EMREXTSELECTCLIPRGN *)emr;
2493         union _rgn
2494         {
2495             RGNDATA data;
2496             char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)];
2497         };
2498         const union _rgn *rgn1;
2499         union _rgn rgn2;
2500         RECT rect, rc_transformed;
2501         const RECT *rc = (const RECT *)param;
2502         HRGN hrgn;
2503         XFORM xform;
2504         INT ret;
2505         BOOL is_win9x;
2506 
2507         trace("EMR_EXTSELECTCLIPRGN: cbRgnData %#x, iMode %u\n",
2508                clip->cbRgnData, clip->iMode);
2509 
2510         ok(clip->iMode == RGN_COPY, "expected RGN_COPY, got %u\n", clip->iMode);
2511         ok(clip->cbRgnData >= sizeof(RGNDATAHEADER) + sizeof(RECT),
2512            "too small data block: %u bytes\n", clip->cbRgnData);
2513         if (clip->cbRgnData < sizeof(RGNDATAHEADER) + sizeof(RECT))
2514             return 0;
2515 
2516         rgn1 = (const union _rgn *)clip->RgnData;
2517 
2518         trace("size %u, type %u, count %u, rgn size %u, bound %s\n",
2519               rgn1->data.rdh.dwSize, rgn1->data.rdh.iType,
2520               rgn1->data.rdh.nCount, rgn1->data.rdh.nRgnSize,
2521               wine_dbgstr_rect(&rgn1->data.rdh.rcBound));
2522 
2523         ok(EqualRect(&rgn1->data.rdh.rcBound, rc), "rects don't match\n");
2524 
2525         rect = *(const RECT *)rgn1->data.Buffer;
2526         trace("rect %s\n", wine_dbgstr_rect(&rect));
2527         ok(EqualRect(&rect, rc), "rects don't match\n");
2528 
2529         ok(rgn1->data.rdh.dwSize == sizeof(rgn1->data.rdh), "expected sizeof(rdh), got %u\n", rgn1->data.rdh.dwSize);
2530         ok(rgn1->data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn1->data.rdh.iType);
2531         ok(rgn1->data.rdh.nCount == 1, "expected 1, got %u\n", rgn1->data.rdh.nCount);
2532         ok(rgn1->data.rdh.nRgnSize == sizeof(RECT) ||
2533            broken(rgn1->data.rdh.nRgnSize == 168), /* NT4 */
2534            "expected sizeof(RECT), got %u\n", rgn1->data.rdh.nRgnSize);
2535 
2536         hrgn = CreateRectRgn(0, 0, 0, 0);
2537 
2538         memset(&xform, 0, sizeof(xform));
2539         SetLastError(0xdeadbeef);
2540         ret = GetWorldTransform(hdc, &xform);
2541         is_win9x = !ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED;
2542         if (!is_win9x)
2543             ok(ret, "GetWorldTransform error %u\n", GetLastError());
2544 
2545         trace("xform.eM11 %f, xform.eM22 %f\n", xform.eM11, xform.eM22);
2546 
2547         ret = GetClipRgn(hdc, hrgn);
2548         ok(ret == 0, "GetClipRgn returned %d, expected 0\n", ret);
2549 
2550         PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
2551 
2552         ret = GetClipRgn(hdc, hrgn);
2553         ok(ret == 1, "GetClipRgn returned %d, expected 1\n", ret);
2554 
2555         /* Win9x returns empty clipping region */
2556         if (is_win9x) return 1;
2557 
2558         ret = GetRegionData(hrgn, 0, NULL);
2559         ok(ret == sizeof(rgn2.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
2560 
2561         ret = GetRegionData(hrgn, sizeof(rgn2), &rgn2.data);
2562         ok(ret == sizeof(rgn2), "expected sizeof(rgn2), got %u\n", ret);
2563 
2564         trace("size %u, type %u, count %u, rgn size %u, bound %s\n", rgn2.data.rdh.dwSize,
2565               rgn2.data.rdh.iType, rgn2.data.rdh.nCount, rgn2.data.rdh.nRgnSize,
2566               wine_dbgstr_rect(&rgn2.data.rdh.rcBound));
2567 
2568         rect = rgn2.data.rdh.rcBound;
2569         rc_transformed = *rc;
2570         translate((POINT *)&rc_transformed, 2, &xform);
2571         trace("transformed %s\n", wine_dbgstr_rect(&rc_transformed));
2572         ok(is_equal_rect(&rect, &rc_transformed), "rects don't match\n");
2573 
2574         rect = *(const RECT *)rgn2.data.Buffer;
2575         trace("rect %s\n", wine_dbgstr_rect(&rect));
2576         rc_transformed = *rc;
2577         translate((POINT *)&rc_transformed, 2, &xform);
2578         trace("transformed %s\n", wine_dbgstr_rect(&rc_transformed));
2579         ok(is_equal_rect(&rect, &rc_transformed), "rects don't match\n");
2580 
2581         ok(rgn2.data.rdh.dwSize == sizeof(rgn1->data.rdh), "expected sizeof(rdh), got %u\n", rgn2.data.rdh.dwSize);
2582         ok(rgn2.data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn2.data.rdh.iType);
2583         ok(rgn2.data.rdh.nCount == 1, "expected 1, got %u\n", rgn2.data.rdh.nCount);
2584         ok(rgn2.data.rdh.nRgnSize == sizeof(RECT) ||
2585            broken(rgn2.data.rdh.nRgnSize == 168), /* NT4 */
2586            "expected sizeof(RECT), got %u\n", rgn2.data.rdh.nRgnSize);
2587 
2588         DeleteObject(hrgn);
2589     }
2590     return 1;
2591 }
2592 
2593 static void test_emf_clipping(void)
2594 {
2595     static const RECT rc = { 0, 0, 100, 100 };
2596     RECT rc_clip = { 100, 100, 1024, 1024 };
2597     HWND hwnd;
2598     HDC hdc;
2599     HENHMETAFILE hemf;
2600     HRGN hrgn;
2601     INT ret;
2602     RECT rc_res, rc_sclip;
2603 
2604     SetLastError(0xdeadbeef);
2605     hdc = CreateEnhMetaFileA(0, NULL, NULL, NULL);
2606     ok(hdc != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
2607 
2608     /* Need to write something to the emf, otherwise Windows won't play it back */
2609     LineTo(hdc, 1, 1);
2610 
2611     hrgn = CreateRectRgn(rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
2612     ret = SelectClipRgn(hdc, hrgn);
2613     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
2614 
2615     BeginPath(hdc);
2616     Rectangle(hdc, rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
2617     EndPath(hdc);
2618     ret = SelectClipPath(hdc, RGN_AND);
2619     ok(ret, "SelectClipPath error %d\n", GetLastError());
2620 
2621     SetLastError(0xdeadbeef);
2622     hemf = CloseEnhMetaFile(hdc);
2623     ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
2624 
2625     if (compare_emf_bits(hemf, EMF_CLIPPING, sizeof(EMF_CLIPPING),
2626         "emf_clipping", FALSE) != 0)
2627     {
2628         dump_emf_bits(hemf, "emf_clipping");
2629         dump_emf_records(hemf, "emf_clipping");
2630     }
2631 
2632     DeleteObject(hrgn);
2633 
2634     /* Win9x doesn't play EMFs on invisible windows */
2635     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
2636                            0, 0, 200, 200, 0, 0, 0, NULL);
2637     ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
2638 
2639     hdc = GetDC(hwnd);
2640 
2641     ret = EnumEnhMetaFile(hdc, hemf, clip_emf_enum_proc, &rc_clip, &rc);
2642     ok(ret, "EnumEnhMetaFile error %d\n", GetLastError());
2643 
2644     DeleteEnhMetaFile(hemf);
2645     ReleaseDC(hwnd, hdc);
2646     DestroyWindow(hwnd);
2647 
2648     hdc = CreateEnhMetaFileA(0, NULL, NULL, NULL);
2649 
2650     SetRect(&rc_sclip, 100, 100, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2651     hrgn = CreateRectRgn(rc_sclip.left, rc_sclip.top, rc_sclip.right, rc_sclip.bottom);
2652     SelectClipRgn(hdc, hrgn);
2653     SetRect(&rc_res, -1, -1, -1, -1);
2654     ret = GetClipBox(hdc, &rc_res);
2655     ok(ret == SIMPLEREGION, "got %d\n", ret);
2656     ok(EqualRect(&rc_res, &rc_sclip), "expected %s, got %s\n", wine_dbgstr_rect(&rc_sclip),
2657        wine_dbgstr_rect(&rc_res));
2658 
2659     OffsetRect(&rc_sclip, -100, -100);
2660     ret = OffsetClipRgn(hdc, -100, -100);
2661     ok(ret == SIMPLEREGION, "got %d\n", ret);
2662     SetRect(&rc_res, -1, -1, -1, -1);
2663     ret = GetClipBox(hdc, &rc_res);
2664     ok(ret == SIMPLEREGION, "got %d\n", ret);
2665     ok(EqualRect(&rc_res, &rc_sclip), "expected %s, got %s\n", wine_dbgstr_rect(&rc_sclip),
2666        wine_dbgstr_rect(&rc_res));
2667 
2668     ret = IntersectClipRect(hdc, 0, 0, 100, 100);
2669     ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION) /* XP */, "got %d\n", ret);
2670     if (ret == COMPLEXREGION)
2671     {
2672         /* XP returns COMPLEXREGION although region contains only 1 rect */
2673         ret = GetClipRgn(hdc, hrgn);
2674         ok(ret == 1, "expected 1, got %d\n", ret);
2675         ret = rgn_rect_count(hrgn);
2676         ok(ret == 1, "expected 1, got %d\n", ret);
2677     }
2678     SetRect(&rc_res, -1, -1, -1, -1);
2679     ret = GetClipBox(hdc, &rc_res);
2680     ok(ret == SIMPLEREGION, "got %d\n", ret);
2681     ok(EqualRect(&rc_res, &rc), "expected %s, got %s\n", wine_dbgstr_rect(&rc),
2682        wine_dbgstr_rect(&rc_res));
2683 
2684     SetRect(&rc_sclip, 0, 0, 100, 50);
2685     ret = ExcludeClipRect(hdc, 0, 50, 100, 100);
2686     ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION) /* XP */, "got %d\n", ret);
2687     if (ret == COMPLEXREGION)
2688     {
2689         /* XP returns COMPLEXREGION although region contains only 1 rect */
2690         ret = GetClipRgn(hdc, hrgn);
2691         ok(ret == 1, "expected 1, got %d\n", ret);
2692         ret = rgn_rect_count(hrgn);
2693         ok(ret == 1, "expected 1, got %d\n", ret);
2694     }
2695     SetRect(&rc_res, -1, -1, -1, -1);
2696     ret = GetClipBox(hdc, &rc_res);
2697     ok(ret == SIMPLEREGION, "got %d\n", ret);
2698     ok(EqualRect(&rc_res, &rc_sclip), "expected %s, got %s\n", wine_dbgstr_rect(&rc_sclip),
2699        wine_dbgstr_rect(&rc_res));
2700 
2701     hemf = CloseEnhMetaFile(hdc);
2702     DeleteEnhMetaFile(hemf);
2703     DeleteObject(hrgn);
2704 }
2705 
2706 static const unsigned char MF_CLIP_BITS[] = {
2707     /* METAHEADER */
2708     0x01, 0x00,             /* mtType */
2709     0x09, 0x00,             /* mtHeaderSize */
2710     0x00, 0x03,             /* mtVersion */
2711     0x32, 0x00, 0x00, 0x00, /* mtSize */
2712     0x01, 0x00,             /* mtNoObjects */
2713     0x14, 0x00, 0x00, 0x00, /* mtMaxRecord (size in words of longest record) */
2714     0x00, 0x00,             /* reserved */
2715 
2716     /* METARECORD for CreateRectRgn(0x11, 0x22, 0x33, 0x44) */
2717     0x14, 0x00, 0x00, 0x00, /* rdSize in words */
2718     0xff, 0x06,             /* META_CREATEREGION */
2719     0x00, 0x00, 0x06, 0x00, 0xf6, 0x02, 0x00, 0x00,
2720     0x24, 0x00, 0x01, 0x00, 0x02, 0x00, 0x11, 0x00,
2721     0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x02, 0x00,
2722     0x22, 0x00, 0x44, 0x00, 0x11, 0x00, 0x33, 0x00,
2723     0x02, 0x00,
2724 
2725     /* METARECORD for SelectObject */
2726     0x04, 0x00, 0x00, 0x00,
2727     0x2d, 0x01,             /* META_SELECTOBJECT (not META_SELECTCLIPREGION?!) */
2728     0x00, 0x00,
2729 
2730     /* METARECORD */
2731     0x04, 0x00, 0x00, 0x00,
2732     0xf0, 0x01,             /* META_DELETEOBJECT */
2733     0x00, 0x00,
2734 
2735     /* METARECORD for MoveTo(1,0x30) */
2736     0x05, 0x00, 0x00, 0x00, /* rdSize in words */
2737     0x14, 0x02,             /* META_MOVETO */
2738     0x30, 0x00,             /* y */
2739     0x01, 0x00,             /* x */
2740 
2741     /* METARECORD for LineTo(0x20, 0x30) */
2742     0x05, 0x00, 0x00, 0x00, /* rdSize in words */
2743     0x13, 0x02,             /* META_LINETO */
2744     0x30, 0x00,             /* y */
2745     0x20, 0x00,             /* x */
2746 
2747     /* EOF */
2748     0x03, 0x00, 0x00, 0x00,
2749     0x00, 0x00
2750 };
2751 
2752 static int clip_mf_enum_proc_seen_selectclipregion;
2753 static int clip_mf_enum_proc_seen_selectobject;
2754 
2755 static int CALLBACK clip_mf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
2756                                        METARECORD *mr, int n_objs, LPARAM param)
2757 {
2758     switch (mr->rdFunction) {
2759     case META_SELECTCLIPREGION:
2760         clip_mf_enum_proc_seen_selectclipregion++;
2761         break;
2762     case META_SELECTOBJECT:
2763         clip_mf_enum_proc_seen_selectobject++;
2764         break;
2765     }
2766     return 1;
2767 }
2768 
2769 static void test_mf_clipping(void)
2770 {
2771                           /* left top right bottom */
2772     static RECT rc_clip = { 0x11, 0x22, 0x33, 0x44 };
2773     HWND hwnd;
2774     HDC hdc;
2775     HMETAFILE hmf;
2776     HRGN hrgn;
2777     INT ret;
2778 
2779     SetLastError(0xdeadbeef);
2780     hdc = CreateMetaFileA(NULL);
2781     ok(hdc != 0, "CreateMetaFileA error %d\n", GetLastError());
2782 
2783     hrgn = CreateRectRgn(rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
2784     ret = SelectClipRgn(hdc, hrgn);
2785     /* Seems like it should be SIMPLEREGION, but windows returns NULLREGION? */
2786     ok(ret == NULLREGION, "expected NULLREGION, got %d\n", ret);
2787 
2788     /* Draw a line that starts off left of the clip region and ends inside it */
2789     MoveToEx(hdc, 0x1, 0x30, NULL);
2790     LineTo(hdc,  0x20, 0x30);
2791 
2792     SetLastError(0xdeadbeef);
2793     hmf = CloseMetaFile(hdc);
2794     ok(hmf != 0, "CloseMetaFile error %d\n", GetLastError());
2795 
2796     if (compare_mf_bits(hmf, MF_CLIP_BITS, sizeof(MF_CLIP_BITS),
2797         "mf_clipping") != 0)
2798     {
2799         dump_mf_bits(hmf, "mf_clipping");
2800     }
2801 
2802     DeleteObject(hrgn);
2803 
2804     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
2805                            0, 0, 200, 200, 0, 0, 0, NULL);
2806     ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError());
2807 
2808     hdc = GetDC(hwnd);
2809 
2810     ret = EnumMetaFile(hdc, hmf, clip_mf_enum_proc, (LPARAM)&rc_clip);
2811     ok(ret, "EnumMetaFile error %d\n", GetLastError());
2812 
2813     /* Oddly, windows doesn't seem to use META_SELECTCLIPREGION */
2814     ok(clip_mf_enum_proc_seen_selectclipregion == 0,
2815        "expected 0 selectclipregion, saw %d\n", clip_mf_enum_proc_seen_selectclipregion);
2816     ok(clip_mf_enum_proc_seen_selectobject == 1,
2817        "expected 1 selectobject, saw %d\n", clip_mf_enum_proc_seen_selectobject);
2818 
2819     DeleteMetaFile(hmf);
2820     ReleaseDC(hwnd, hdc);
2821     DestroyWindow(hwnd);
2822 }
2823 
2824 static const unsigned char MF_PATH_BITS[] =
2825 {
2826     0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x2c, 0x00,
2827     0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
2828     0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
2829     0x32, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,
2830     0x13, 0x02, 0x96, 0x00, 0x32, 0x00, 0x05, 0x00,
2831     0x00, 0x00, 0x13, 0x02, 0x96, 0x00, 0x96, 0x00,
2832     0x05, 0x00, 0x00, 0x00, 0x13, 0x02, 0x32, 0x00,
2833     0x96, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
2834     0x32, 0x00, 0x32, 0x00, 0x07, 0x00, 0x00, 0x00,
2835     0x1b, 0x04, 0x14, 0x00, 0x14, 0x00, 0x0a, 0x00,
2836     0x0a, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
2837 };
2838 
2839 static void test_mf_GetPath(void)
2840 {
2841     HDC hdc;
2842     HMETAFILE hmf;
2843     BOOL ret;
2844     int size;
2845 
2846     SetLastError(0xdeadbeef);
2847     hdc = CreateMetaFileA(NULL);
2848     ok(hdc != 0, "CreateMetaFileA error %d\n", GetLastError());
2849 
2850     BeginPath(hdc);
2851     ret = MoveToEx(hdc, 50, 50, NULL);
2852     ok( ret, "MoveToEx error %d.\n", GetLastError());
2853     ret = LineTo(hdc, 50, 150);
2854     ok( ret, "LineTo error %d.\n", GetLastError());
2855     ret = LineTo(hdc, 150, 150);
2856     ok( ret, "LineTo error %d.\n", GetLastError());
2857     ret = LineTo(hdc, 150, 50);
2858     ok( ret, "LineTo error %d.\n", GetLastError());
2859     ret = LineTo(hdc, 50, 50);
2860     ok( ret, "LineTo error %d.\n", GetLastError());
2861     Rectangle(hdc, 10, 10, 20, 20);
2862     EndPath(hdc);
2863 
2864     size = GetPath(hdc, NULL, NULL, 0);
2865     ok( size == -1, "GetPath returned %d.\n", size);
2866 
2867     hmf = CloseMetaFile(hdc);
2868     ok(hmf != 0, "CloseMetaFile error %d\n", GetLastError());
2869 
2870     if (compare_mf_bits (hmf, MF_PATH_BITS, sizeof(MF_PATH_BITS), "mf_GetPath") != 0)
2871     {
2872         dump_mf_bits(hmf, "mf_GetPath");
2873         EnumMetaFile(0, hmf, mf_enum_proc, 0);
2874     }
2875 
2876     ret = DeleteMetaFile(hmf);
2877     ok( ret, "DeleteMetaFile error %d\n", GetLastError());
2878 }
2879 
2880 static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
2881 {
2882     LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData;
2883     POINT mapping[2] = { { 0, 0 }, { 10, 10 } };
2884     /* When using MM_TEXT Win9x does not update the mapping mode
2885      * until a record is played which actually outputs something */
2886     PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
2887     LPtoDP(hdc, mapping, 2);
2888     trace("EMF record: iType %d, nSize %d, (%d,%d)-(%d,%d)\n",
2889            lpEMFR->iType, lpEMFR->nSize,
2890            mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
2891 
2892     if (lpEMFR->iType == EMR_LINETO)
2893     {
2894         INT x0, y0, x1, y1;
2895         if (!lpMFP || lpMFP->mm == MM_TEXT)
2896         {
2897             x0 = 0;
2898             y0 = 0;
2899             x1 = (INT)floor(10 * 100.0 / LINE_X + 0.5);
2900             y1 = (INT)floor(10 * 100.0 / LINE_Y + 0.5);
2901         }
2902         else
2903         {
2904             ok(lpMFP->mm == MM_ANISOTROPIC, "mm=%d\n", lpMFP->mm);
2905 
2906             x0 = MulDiv(0, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
2907             y0 = MulDiv(0, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
2908             x1 = MulDiv(10, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
2909             y1 = MulDiv(10, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
2910         }
2911         ok(mapping[0].x == x0 && mapping[0].y == y0 && mapping[1].x == x1 && mapping[1].y == y1,
2912             "(%d,%d)->(%d,%d), expected (%d,%d)->(%d,%d)\n",
2913             mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y,
2914             x0, y0, x1, y1);
2915     }
2916     return TRUE;
2917 }
2918 
2919 static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
2920 {
2921     HDC hdcMf;
2922     HMETAFILE hmf;
2923     HENHMETAFILE hemf;
2924     BOOL ret;
2925     UINT size;
2926     LPBYTE pBits;
2927 
2928     hdcMf = CreateMetaFileA(NULL);
2929     ok(hdcMf != NULL, "CreateMetaFile failed with error %d\n", GetLastError());
2930     ret = LineTo(hdcMf, (INT)LINE_X, (INT)LINE_Y);
2931     ok(ret, "LineTo failed with error %d\n", GetLastError());
2932     hmf = CloseMetaFile(hdcMf);
2933     ok(hmf != NULL, "CloseMetaFile failed with error %d\n", GetLastError());
2934 
2935     if (compare_mf_bits (hmf, MF_LINETO_BITS, sizeof(MF_LINETO_BITS), "mf_LineTo") != 0)
2936     {
2937         dump_mf_bits(hmf, "mf_LineTo");
2938         EnumMetaFile(0, hmf, mf_enum_proc, 0);
2939     }
2940 
2941     size = GetMetaFileBitsEx(hmf, 0, NULL);
2942     ok(size, "GetMetaFileBitsEx failed with error %d\n", GetLastError());
2943     pBits = HeapAlloc(GetProcessHeap(), 0, size);
2944     GetMetaFileBitsEx(hmf, size, pBits);
2945     DeleteMetaFile(hmf);
2946     hemf = SetWinMetaFileBits(size, pBits, NULL, mfp);
2947     HeapFree(GetProcessHeap(), 0, pBits);
2948     return hemf;
2949 }
2950 
2951 static void test_mf_conversions(void)
2952 {
2953     trace("Testing MF->EMF conversion (MM_ANISOTROPIC)\n");
2954     {
2955         HDC hdcOffscreen = CreateCompatibleDC(NULL);
2956         HENHMETAFILE hemf;
2957         METAFILEPICT mfp;
2958         RECT rect = { 0, 0, 100, 100 };
2959         mfp.mm = MM_ANISOTROPIC;
2960         mfp.xExt = 100;
2961         mfp.yExt = 100;
2962         mfp.hMF = NULL;
2963         hemf = create_converted_emf(&mfp);
2964 
2965         if (compare_emf_bits(hemf, EMF_LINETO_MM_ANISOTROPIC_BITS, sizeof(EMF_LINETO_MM_ANISOTROPIC_BITS),
2966                              "emf_LineTo MM_ANISOTROPIC", TRUE) != 0)
2967         {
2968             dump_emf_bits(hemf, "emf_LineTo MM_ANISOTROPIC");
2969             dump_emf_records(hemf, "emf_LineTo MM_ANISOTROPIC");
2970         }
2971 
2972         EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
2973 
2974         DeleteEnhMetaFile(hemf);
2975         DeleteDC(hdcOffscreen);
2976     }
2977 
2978     trace("Testing MF->EMF conversion (MM_TEXT)\n");
2979     {
2980         HDC hdcOffscreen = CreateCompatibleDC(NULL);
2981         HENHMETAFILE hemf;
2982         METAFILEPICT mfp;
2983         RECT rect = { 0, 0, 100, 100 };
2984         mfp.mm = MM_TEXT;
2985         mfp.xExt = 0;
2986         mfp.yExt = 0;
2987         mfp.hMF = NULL;
2988         hemf = create_converted_emf(&mfp);
2989 
2990         if (compare_emf_bits(hemf, EMF_LINETO_MM_TEXT_BITS, sizeof(EMF_LINETO_MM_TEXT_BITS),
2991                              "emf_LineTo MM_TEXT", TRUE) != 0)
2992         {
2993             dump_emf_bits(hemf, "emf_LineTo MM_TEXT");
2994             dump_emf_records(hemf, "emf_LineTo MM_TEXT");
2995         }
2996 
2997         EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
2998 
2999         DeleteEnhMetaFile(hemf);
3000         DeleteDC(hdcOffscreen);
3001     }
3002 
3003     trace("Testing MF->EMF conversion (NULL mfp)\n");
3004     {
3005         HDC hdcOffscreen = CreateCompatibleDC(NULL);
3006         HENHMETAFILE hemf;
3007         RECT rect = { 0, 0, 100, 100 };
3008         hemf = create_converted_emf(NULL);
3009 
3010         if (compare_emf_bits(hemf, EMF_LINETO_BITS, sizeof(EMF_LINETO_BITS),
3011                              "emf_LineTo NULL", TRUE) != 0)
3012         {
3013             dump_emf_bits(hemf, "emf_LineTo NULL");
3014             dump_emf_records(hemf, "emf_LineTo NULL");
3015         }
3016 
3017         EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, NULL, &rect);
3018 
3019         DeleteEnhMetaFile(hemf);
3020         DeleteDC(hdcOffscreen);
3021     }
3022 }
3023 
3024 static BOOL getConvertedFrameAndBounds(UINT buffer_size, BYTE * buffer, BOOL mfpIsNull,
3025                                        LONG mm, LONG xExt, LONG yExt,
3026                                        RECTL * rclBounds, RECTL * rclFrame)
3027 {
3028   METAFILEPICT mfp;
3029   METAFILEPICT * mfpPtr = NULL;
3030   HENHMETAFILE emf;
3031   ENHMETAHEADER header;
3032   UINT res;
3033 
3034   if (!mfpIsNull)
3035   {
3036     mfp.mm = mm;
3037     mfp.xExt = xExt;
3038     mfp.yExt = yExt;
3039     mfpPtr = &mfp;
3040   }
3041 
3042   emf = SetWinMetaFileBits(buffer_size, buffer, NULL, mfpPtr);
3043   ok(emf != NULL, "SetWinMetaFileBits failed\n");
3044   if (!emf) return FALSE;
3045   res = GetEnhMetaFileHeader(emf, sizeof(header), &header);
3046   ok(res != 0, "GetEnhMetaHeader failed\n");
3047   DeleteEnhMetaFile(emf);
3048   if (!res) return FALSE;
3049 
3050   *rclBounds = header.rclBounds;
3051   *rclFrame = header.rclFrame;
3052   return TRUE;
3053 }
3054 
3055 static void checkConvertedFrameAndBounds(UINT buffer_size, BYTE * buffer, BOOL mfpIsNull,
3056                                          LONG mm, LONG xExt, LONG yExt,
3057                                          RECTL * rclBoundsExpected, RECTL * rclFrameExpected)
3058 {
3059   RECTL rclBounds, rclFrame;
3060 
3061   if (getConvertedFrameAndBounds(buffer_size, buffer, mfpIsNull, mm, xExt, yExt, &rclBounds, &rclFrame))
3062   {
3063     const char * msg;
3064     char buf[64];
3065 
3066     if (mfpIsNull)
3067     {
3068        msg = "mfp == NULL";
3069     }
3070     else
3071     {
3072       const char * mm_str;
3073       switch (mm)
3074       {
3075          case MM_ANISOTROPIC: mm_str = "MM_ANISOTROPIC"; break;
3076          case MM_ISOTROPIC:   mm_str = "MM_ISOTROPIC"; break;
3077          default:             mm_str = "Unexpected";
3078       }
3079       sprintf(buf, "mm=%s, xExt=%d, yExt=%d", mm_str, xExt, yExt);
3080       msg = buf;
3081     }
3082 
3083     ok(rclBounds.left == rclBoundsExpected->left, "rclBounds.left: Expected %d, got %d (%s)\n", rclBoundsExpected->left, rclBounds.left, msg);
3084     ok(rclBounds.top == rclBoundsExpected->top, "rclBounds.top: Expected %d, got %d (%s)\n", rclBoundsExpected->top, rclBounds.top, msg);
3085     ok(rclBounds.right == rclBoundsExpected->right, "rclBounds.right: Expected %d, got %d (%s)\n", rclBoundsExpected->right, rclBounds.right, msg);
3086     ok(rclBounds.bottom == rclBoundsExpected->bottom, "rclBounds.bottom: Expected %d, got %d (%s)\n", rclBoundsExpected->bottom, rclBounds.bottom, msg);
3087     ok(rclFrame.left == rclFrameExpected->left, "rclFrame.left: Expected %d, got %d (%s)\n", rclFrameExpected->left, rclFrame.left, msg);
3088     ok(rclFrame.top == rclFrameExpected->top, "rclFrame.top: Expected %d, got %d (%s)\n", rclFrameExpected->top, rclFrame.top, msg);
3089     ok(rclFrame.right == rclFrameExpected->right, "rclFrame.right: Expected %d, got %d (%s)\n", rclFrameExpected->right, rclFrame.right, msg);
3090     ok(rclFrame.bottom == rclFrameExpected->bottom, "rclFrame.bottom: Expected %d, got %d (%s)\n", rclFrameExpected->bottom, rclFrame.bottom, msg);
3091   }
3092 }
3093 
3094 static void test_SetWinMetaFileBits(void)
3095 {
3096   HMETAFILE wmf;
3097   HDC wmfDC;
3098   BYTE * buffer;
3099   UINT buffer_size;
3100   RECT rect;
3101   UINT res;
3102   RECTL rclBoundsAnisotropic, rclFrameAnisotropic;
3103   RECTL rclBoundsIsotropic, rclFrameIsotropic;
3104   RECTL rclBounds, rclFrame;
3105   HDC dc;
3106   LONG diffx, diffy;
3107 
3108   wmfDC = CreateMetaFileA(NULL);
3109   ok(wmfDC != NULL, "CreateMetaFile failed\n");
3110   if (!wmfDC) return;
3111 
3112   SetWindowExtEx(wmfDC, 100, 100, NULL);
3113   SetRect(&rect, 0, 0, 50, 50);
3114   FillRect(wmfDC, &rect, GetStockObject(BLACK_BRUSH));
3115   wmf = CloseMetaFile(wmfDC);
3116   ok(wmf != NULL, "Metafile creation failed\n");
3117   if (!wmf) return;
3118 
3119   buffer_size = GetMetaFileBitsEx(wmf, 0, NULL);
3120   ok(buffer_size != 0, "GetMetaFileBitsEx failed\n");
3121   if (buffer_size == 0)
3122   {
3123     DeleteMetaFile(wmf);
3124     return;
3125   }
3126 
3127   buffer = HeapAlloc(GetProcessHeap(), 0, buffer_size);
3128   ok(buffer != NULL, "HeapAlloc failed\n");
3129   if (!buffer)
3130   {
3131     DeleteMetaFile(wmf);
3132     return;
3133   }
3134 
3135   res = GetMetaFileBitsEx(wmf, buffer_size, buffer);
3136   ok(res == buffer_size, "GetMetaFileBitsEx failed\n");
3137   DeleteMetaFile(wmf);
3138   if (res != buffer_size)
3139   {
3140      HeapFree(GetProcessHeap(), 0, buffer);
3141      return;
3142   }
3143 
3144   /* Get the reference bounds and frame */
3145   getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3146   getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, 0,  &rclBoundsIsotropic, &rclFrameIsotropic);
3147 
3148   ok(rclBoundsAnisotropic.left == 0 && rclBoundsAnisotropic.top == 0 &&
3149      rclBoundsIsotropic.left == 0 && rclBoundsIsotropic.top == 0,
3150      "SetWinMetaFileBits: Reference bounds: Left and top bound must be zero\n");
3151 
3152   ok(rclBoundsAnisotropic.right >= rclBoundsIsotropic.right, "SetWinMetaFileBits: Reference bounds: Invalid right bound\n");
3153   ok(rclBoundsAnisotropic.bottom >= rclBoundsIsotropic.bottom, "SetWinMetaFileBits: Reference bounds: Invalid bottom bound\n");
3154   diffx = rclBoundsIsotropic.right - rclBoundsIsotropic.bottom;
3155   if (diffx < 0) diffx = -diffx;
3156   ok(diffx <= 1, "SetWinMetaFileBits (MM_ISOTROPIC): Reference bounds are not isotropic\n");
3157 
3158   dc = CreateCompatibleDC(NULL);
3159 
3160   /* Allow 1 mm difference (rounding errors) */
3161   diffx = rclBoundsAnisotropic.right - GetDeviceCaps(dc, HORZRES) / 2;
3162   diffy = rclBoundsAnisotropic.bottom - GetDeviceCaps(dc, VERTRES) / 2;
3163   if (diffx < 0) diffx = -diffx;
3164   if (diffy < 0) diffy = -diffy;
3165   todo_wine
3166   {
3167   ok(diffx <= 1 && diffy <= 1,
3168      "SetWinMetaFileBits (MM_ANISOTROPIC): Reference bounds: The whole device surface must be used (%dx%d), but got (%dx%d)\n",
3169      GetDeviceCaps(dc, HORZRES) / 2, GetDeviceCaps(dc, VERTRES) / 2, rclBoundsAnisotropic.right, rclBoundsAnisotropic.bottom);
3170   }
3171 
3172   /* Allow 1 mm difference (rounding errors) */
3173   diffx = rclFrameAnisotropic.right / 100 - GetDeviceCaps(dc, HORZSIZE) / 2;
3174   diffy = rclFrameAnisotropic.bottom / 100 - GetDeviceCaps(dc, VERTSIZE) / 2;
3175   if (diffx < 0) diffx = -diffx;
3176   if (diffy < 0) diffy = -diffy;
3177   todo_wine
3178   {
3179   ok(diffx <= 1 && diffy <= 1,
3180      "SetWinMetaFileBits (MM_ANISOTROPIC): Reference frame: The whole device surface must be used (%dx%d), but got (%dx%d)\n",
3181      GetDeviceCaps(dc, HORZSIZE) / 2, GetDeviceCaps(dc, VERTSIZE) / 2, rclFrameAnisotropic.right / 100, rclFrameAnisotropic.bottom / 100);
3182   }
3183   DeleteDC(dc);
3184 
3185   /* If the METAFILEPICT pointer is NULL, the MM_ANISOTROPIC mapping mode and the whole device surface are used */
3186   checkConvertedFrameAndBounds(buffer_size, buffer, TRUE, 0, 0, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3187 
3188   /* If xExt or yExt is zero or negative, the whole device surface is used */
3189   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 10000, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3190   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 10000, 0, &rclBoundsIsotropic, &rclFrameIsotropic);
3191   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, 10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3192   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, 10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3193   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -10000, 0, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3194   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -10000, 0, &rclBoundsIsotropic, &rclFrameIsotropic);
3195   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 0, -10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3196   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 0, -10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3197   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -10000, 10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3198   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -10000, 10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3199   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 10000, -10000, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3200   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 10000, -10000, &rclBoundsIsotropic, &rclFrameIsotropic);
3201 
3202   /* MSDN says that negative xExt and yExt values specify a ratio.
3203      Check that this is wrong and the whole device surface is used */
3204   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, -1000, -100, &rclBoundsAnisotropic, &rclFrameAnisotropic);
3205   checkConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, -1000, -100, &rclBoundsIsotropic, &rclFrameIsotropic);
3206 
3207   /* Ordinary conversions */
3208 
3209   if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ANISOTROPIC, 30000, 20000, &rclBounds, &rclFrame))
3210   {
3211     ok(rclFrame.left == 0 && rclFrame.top == 0 && rclFrame.right == 30000 && rclFrame.bottom == 20000,
3212        "SetWinMetaFileBits (MM_ANISOTROPIC): rclFrame contains invalid values\n");
3213     ok(rclBounds.left == 0 && rclBounds.top == 0 && rclBounds.right > rclBounds.bottom,
3214        "SetWinMetaFileBits (MM_ANISOTROPIC): rclBounds contains invalid values\n");
3215   }
3216 
3217   if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_ISOTROPIC, 30000, 20000, &rclBounds, &rclFrame))
3218   {
3219     ok(rclFrame.left == 0 && rclFrame.top == 0 && rclFrame.right == 30000 && rclFrame.bottom == 20000,
3220        "SetWinMetaFileBits (MM_ISOTROPIC): rclFrame contains invalid values\n");
3221     ok(rclBounds.left == 0 && rclBounds.top == 0,
3222        "SetWinMetaFileBits (MM_ISOTROPIC): rclBounds contains invalid values\n");
3223 
3224     /* Wine has a rounding error */
3225     diffx = rclBounds.right - rclBounds.bottom;
3226     if (diffx < 0) diffx = -diffx;
3227     ok(diffx <= 1, "SetWinMetaFileBits (MM_ISOTROPIC): rclBounds is not isotropic\n");
3228   }
3229 
3230   if (getConvertedFrameAndBounds(buffer_size, buffer, FALSE, MM_HIMETRIC, 30000, 20000, &rclBounds, &rclFrame))
3231   {
3232     ok(rclFrame.right - rclFrame.left != 30000 && rclFrame.bottom - rclFrame.top != 20000,
3233        "SetWinMetaFileBits: xExt and yExt must be ignored for mapping modes other than MM_ANISOTROPIC and MM_ISOTROPIC\n");
3234   }
3235 
3236   HeapFree(GetProcessHeap(), 0, buffer);
3237 }
3238 
3239 static BOOL near_match(int x, int y)
3240 {
3241     int epsilon = min(abs(x), abs(y));
3242 
3243     epsilon = max(epsilon/100, 2);
3244 
3245     if(x < y - epsilon || x > y + epsilon) return FALSE;
3246     return TRUE;
3247 }
3248 
3249 static void getwinmetafilebits(UINT mode, int scale, RECT *rc)
3250 {
3251     HENHMETAFILE emf, emf2;
3252     HDC display_dc, emf_dc;
3253     ENHMETAHEADER *enh_header, *enh2_header;
3254     UINT size, emf_size, i, emf2_size;
3255     WORD check = 0;
3256     DWORD rec_num = 0;
3257     METAHEADER *mh = NULL;
3258     METARECORD *rec;
3259     INT horz_res, vert_res, horz_size, vert_size;
3260     INT curve_caps, line_caps, poly_caps;
3261     METAFILEPICT mfp;
3262 
3263     display_dc = GetDC(NULL);
3264     ok(display_dc != NULL, "display_dc is NULL\n");
3265 
3266     horz_res = GetDeviceCaps(display_dc, HORZRES);
3267     vert_res = GetDeviceCaps(display_dc, VERTRES);
3268     horz_size = GetDeviceCaps(display_dc, HORZSIZE);
3269     vert_size = GetDeviceCaps(display_dc, VERTSIZE);
3270 
3271     emf_dc = CreateEnhMetaFileA(display_dc, NULL, rc, NULL);
3272     ok(emf_dc != NULL, "emf_dc is NULL\n");
3273 
3274     curve_caps = GetDeviceCaps(emf_dc, CURVECAPS);
3275     ok(curve_caps == 511, "expect 511 got %d\n", curve_caps);
3276 
3277     line_caps = GetDeviceCaps(emf_dc, LINECAPS);
3278     ok(line_caps == 254, "expect 254 got %d\n", line_caps);
3279 
3280     poly_caps = GetDeviceCaps(emf_dc, POLYGONALCAPS);
3281     ok(poly_caps == 255, "expect 511 got %d\n", poly_caps);
3282 
3283     for(i = 0; i < 3000; i++) /* This is enough to take emf_size > 0xffff */
3284         Rectangle(emf_dc, 0, 0, 1000, 20);
3285     emf = CloseEnhMetaFile(emf_dc);
3286     ok(emf != NULL, "emf is NULL\n");
3287 
3288     emf_size = GetEnhMetaFileBits(emf, 0, NULL);
3289     enh_header = HeapAlloc(GetProcessHeap(), 0, emf_size);
3290     emf_size = GetEnhMetaFileBits(emf, emf_size, (BYTE*)enh_header);
3291     DeleteEnhMetaFile(emf);
3292     /* multiply szlDevice.cx by scale, when scale != 1 the recording and playback dcs
3293        have different resolutions */
3294     enh_header->szlDevice.cx *= scale;
3295     emf = SetEnhMetaFileBits(emf_size, (BYTE*)enh_header);
3296     ok(emf != NULL, "emf is NULL\n");
3297     ok(EqualRect((RECT*)&enh_header->rclFrame, rc), "Frame rectangles differ\n");
3298 
3299     size = GetWinMetaFileBits(emf, 0, NULL, mode, display_dc);
3300     ok(size ||
3301        broken(size == 0), /* some versions of winxp fail for some reason */
3302        "GetWinMetaFileBits returns 0\n");
3303     if(!size) goto end;
3304     mh = HeapAlloc(GetProcessHeap(), 0, size);
3305     GetWinMetaFileBits(emf, size, (BYTE*)mh, mode, display_dc);
3306 
3307     for(i = 0; i < size / 2; i++) check += ((WORD*)mh)[i];
3308     ok(check == 0, "check %04x\n", check);
3309 
3310     rec = (METARECORD*)(mh + 1);
3311 
3312     while(rec->rdSize && rec->rdFunction)
3313     {
3314         const DWORD chunk_size = 0x2000;
3315         DWORD mfcomment_chunks = (emf_size + chunk_size - 1) / chunk_size;
3316 
3317         if(rec_num < mfcomment_chunks)
3318         {
3319             DWORD this_chunk_size = chunk_size;
3320 
3321             if(rec_num == mfcomment_chunks - 1)
3322                 this_chunk_size = emf_size - rec_num * chunk_size;
3323 
3324             ok(rec->rdSize == (this_chunk_size + 44) / 2, "%04x: got %04x expected %04x\n", rec_num, rec->rdSize, (this_chunk_size + 44) / 2);
3325             ok(rec->rdFunction == META_ESCAPE, "%04x: got %04x\n", rec_num, rec->rdFunction);
3326             if(rec->rdSize < (this_chunk_size + 44) / 2) break;
3327             ok(rec->rdParm[0] == MFCOMMENT, "got %04x\n", rec->rdParm[0]);
3328             ok(rec->rdParm[1] == this_chunk_size + 34, "got %04x %x\n", rec->rdParm[1], emf_size + 34);
3329             ok(rec->rdParm[2] == 0x4d57, "got %04x\n", rec->rdParm[2]); /* WMFC */
3330             ok(rec->rdParm[3] == 0x4346, "got %04x\n", rec->rdParm[3]); /*  "   */
3331             ok(rec->rdParm[4] == 1, "got %04x\n", rec->rdParm[4]);
3332             ok(rec->rdParm[5] == 0, "got %04x\n", rec->rdParm[5]);
3333             ok(rec->rdParm[6] == 0, "got %04x\n", rec->rdParm[6]);
3334             ok(rec->rdParm[7] == 1, "got %04x\n", rec->rdParm[7]);
3335             /* parm[8] is the checksum, tested above */
3336             if(rec_num > 0) ok(rec->rdParm[8] == 0, "got %04x\n", rec->rdParm[8]);
3337             ok(rec->rdParm[9] == 0, "got %04x\n", rec->rdParm[9]);
3338             ok(rec->rdParm[10] == 0, "got %04x\n", rec->rdParm[10]);
3339             ok(rec->rdParm[11] == mfcomment_chunks, "got %04x\n", rec->rdParm[11]); /* num chunks */
3340             ok(rec->rdParm[12] == 0, "got %04x\n", rec->rdParm[12]);
3341             ok(rec->rdParm[13] == this_chunk_size, "got %04x expected %04x\n", rec->rdParm[13], this_chunk_size);
3342             ok(rec->rdParm[14] == 0, "got %04x\n", rec->rdParm[14]);
3343             ok(*(DWORD*)(rec->rdParm + 15) == emf_size - this_chunk_size - rec_num * chunk_size, "got %08x\n", *(DWORD*)(rec->rdParm + 15));  /* DWORD size remaining after current chunk */
3344             ok(*(DWORD*)(rec->rdParm + 17) == emf_size, "got %08x emf_size %08x\n", *(DWORD*)(rec->rdParm + 17), emf_size);
3345             ok(!memcmp(rec->rdParm + 19, (char*)enh_header + rec_num * chunk_size, this_chunk_size), "bits mismatch\n");
3346         }
3347 
3348         else if(rec_num == mfcomment_chunks)
3349         {
3350             ok(rec->rdFunction == META_SETMAPMODE, "got %04x\n", rec->rdFunction);
3351             ok(rec->rdParm[0] == mode, "got %04x\n", rec->rdParm[0]);
3352         }
3353         else if(rec_num == mfcomment_chunks + 1)
3354         {
3355             POINT pt;
3356             ok(rec->rdFunction == META_SETWINDOWORG, "got %04x\n", rec->rdFunction);
3357             switch(mode)
3358             {
3359             case MM_TEXT:
3360             case MM_ISOTROPIC:
3361             case MM_ANISOTROPIC:
3362                 pt.y = MulDiv(rc->top, vert_res, vert_size * 100) + 1;
3363                 pt.x = MulDiv(rc->left, horz_res, horz_size * 100);
3364                 break;
3365             case MM_LOMETRIC:
3366                 pt.y = MulDiv(-rc->top, 1, 10) + 1;
3367                 pt.x = MulDiv( rc->left, 1, 10);
3368                 break;
3369             case MM_HIMETRIC:
3370                 pt.y = -rc->top + 1;
3371                 pt.x = (rc->left >= 0) ? rc->left : rc->left + 1; /* strange but true */
3372                 break;
3373             case MM_LOENGLISH:
3374                 pt.y = MulDiv(-rc->top, 10, 254) + 1;
3375                 pt.x = MulDiv( rc->left, 10, 254);
3376                 break;
3377             case MM_HIENGLISH:
3378                 pt.y = MulDiv(-rc->top, 100, 254) + 1;
3379                 pt.x = MulDiv( rc->left, 100, 254);
3380                 break;
3381             case MM_TWIPS:
3382                 pt.y = MulDiv(-rc->top, 72 * 20, 2540) + 1;
3383                 pt.x = MulDiv( rc->left, 72 * 20, 2540);
3384                 break;
3385             default:
3386                 pt.x = pt.y = 0;
3387             }
3388             ok(near_match((short)rec->rdParm[0], pt.y), "got %d expect %d\n", (short)rec->rdParm[0], pt.y);
3389             ok(near_match((short)rec->rdParm[1], pt.x), "got %d expect %d\n", (short)rec->rdParm[1], pt.x);
3390         }
3391         if(rec_num == mfcomment_chunks + 2)
3392         {
3393             ok(rec->rdFunction == META_SETWINDOWEXT, "got %04x\n", rec->rdFunction);
3394             ok(near_match((short)rec->rdParm[0], MulDiv(rc->bottom - rc->top, vert_res, vert_size * 100)),
3395                "got %d\n", (short)rec->rdParm[0]);
3396             ok(near_match((short)rec->rdParm[1], MulDiv(rc->right - rc->left, horz_res, horz_size * 100)),
3397                "got %d\n", (short)rec->rdParm[1]);
3398         }
3399 
3400         rec_num++;
3401         rec = (METARECORD*)((WORD*)rec + rec->rdSize);
3402     }
3403 
3404     /* Show that we get the original back when we do the reverse conversion.
3405        mfp is ignored in this case. */
3406     mfp.mm = MM_ISOTROPIC;
3407     mfp.xExt = 0xcafe;
3408     mfp.yExt = 0xbeef;
3409     emf2 = SetWinMetaFileBits( size, (BYTE*)mh, NULL, &mfp );
3410     ok( !!emf2, "got NULL\n" );
3411     emf2_size = GetEnhMetaFileBits( emf2, 0, NULL );
3412     enh2_header = HeapAlloc( GetProcessHeap(), 0, emf2_size );
3413     emf2_size = GetEnhMetaFileBits( emf2, emf2_size, (BYTE*)enh2_header );
3414     ok( emf_size == emf2_size, "%d %d\n", emf_size, emf2_size );
3415     ok( !memcmp( enh_header, enh2_header, emf_size ), "mismatch\n" );
3416     HeapFree( GetProcessHeap(), 0, enh2_header );
3417     DeleteEnhMetaFile( emf2 );
3418 
3419 end:
3420     HeapFree(GetProcessHeap(), 0, mh);
3421     HeapFree(GetProcessHeap(), 0, enh_header);
3422     DeleteEnhMetaFile(emf);
3423 
3424     ReleaseDC(NULL, display_dc);
3425 }
3426 
3427 static void test_GetWinMetaFileBits(void)
3428 {
3429     UINT mode;
3430     RECT frames[] =
3431     {
3432         { 1000,  2000, 3000, 6000},
3433         {-1000,  2000, 3000, 6000},
3434         { 1000, -2000, 3000, 6000},
3435         { 1005,  2005, 3000, 6000},
3436         {-1005, -2005, 3000, 6000},
3437         {-1005, -2010, 3000, 6000},
3438         {-1005,  2010, 3000, 6000},
3439         {    0,     0,    1,    1},
3440         {   -1,    -1,    1,    1},
3441         {    0,     0,    0,    0}
3442     };
3443 
3444     for(mode = MM_MIN; mode <= MM_MAX; mode++)
3445     {
3446         RECT *rc;
3447         for(rc = frames; rc->right - rc->left > 0; rc++)
3448         {
3449             getwinmetafilebits(mode, 1, rc);
3450             getwinmetafilebits(mode, 2, rc);
3451         }
3452     }
3453 }
3454 
3455 static BOOL (WINAPI *pGdiIsMetaPrintDC)(HDC);
3456 static BOOL (WINAPI *pGdiIsMetaFileDC)(HDC);
3457 static BOOL (WINAPI *pGdiIsPlayMetafileDC)(HDC);
3458 
3459 static void test_gdiis(void)
3460 {
3461     RECT rect = {0,0,100,100};
3462     HDC hdc, hemfDC, hmfDC;
3463     HENHMETAFILE hemf;
3464     HMODULE hgdi32;
3465 
3466     /* resolve all the functions */
3467     hgdi32 = GetModuleHandleA("gdi32.dll");
3468     pGdiIsMetaPrintDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaPrintDC");
3469     pGdiIsMetaFileDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaFileDC");
3470     pGdiIsPlayMetafileDC = (void*) GetProcAddress(hgdi32, "GdiIsPlayMetafileDC");
3471 
3472     if(!pGdiIsMetaPrintDC || !pGdiIsMetaFileDC || !pGdiIsPlayMetafileDC)
3473     {
3474         win_skip("Needed GdiIs* functions are not available\n");
3475         return;
3476     }
3477 
3478     /* try with nothing */
3479     ok(!pGdiIsMetaPrintDC(NULL), "ismetaprint with NULL parameter\n");
3480     ok(!pGdiIsMetaFileDC(NULL), "ismetafile with NULL parameter\n");
3481     ok(!pGdiIsPlayMetafileDC(NULL), "isplaymetafile with NULL parameter\n");
3482 
3483     /* try with a metafile */
3484     hmfDC = CreateMetaFileA(NULL);
3485     ok(!pGdiIsMetaPrintDC(hmfDC), "ismetaprint on metafile\n");
3486     ok(pGdiIsMetaFileDC(hmfDC), "ismetafile on metafile\n");
3487     ok(!pGdiIsPlayMetafileDC(hmfDC), "isplaymetafile on metafile\n");
3488     DeleteMetaFile(CloseMetaFile(hmfDC));
3489 
3490     /* try with an enhanced metafile */
3491     hdc = GetDC(NULL);
3492     hemfDC = CreateEnhMetaFileW(hdc, NULL, &rect, NULL);
3493     ok(hemfDC != NULL, "failed to create emf\n");
3494 
3495     ok(!pGdiIsMetaPrintDC(hemfDC), "ismetaprint on emf\n");
3496     ok(pGdiIsMetaFileDC(hemfDC), "ismetafile on emf\n");
3497     ok(!pGdiIsPlayMetafileDC(hemfDC), "isplaymetafile on emf\n");
3498 
3499     hemf = CloseEnhMetaFile(hemfDC);
3500     ok(hemf != NULL, "failed to close EMF\n");
3501     DeleteEnhMetaFile(hemf);
3502     ReleaseDC(NULL,hdc);
3503 }
3504 
3505 static void test_SetEnhMetaFileBits(void)
3506 {
3507     BYTE data[256];
3508     HENHMETAFILE hemf;
3509     ENHMETAHEADER *emh;
3510 
3511     memset(data, 0xAA, sizeof(data));
3512     SetLastError(0xdeadbeef);
3513     hemf = SetEnhMetaFileBits(sizeof(data), data);
3514     ok(!hemf, "SetEnhMetaFileBits should fail\n");
3515     ok(GetLastError() == ERROR_INVALID_DATA ||
3516        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x, WinMe */
3517        "expected ERROR_INVALID_DATA or ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
3518 
3519     emh = (ENHMETAHEADER *)data;
3520     memset(emh, 0, sizeof(*emh));
3521 
3522     emh->iType = EMR_HEADER;
3523     emh->nSize = sizeof(*emh);
3524     emh->dSignature = ENHMETA_SIGNATURE;
3525     /* emh->nVersion  = 0x10000; XP doesn't care about version */
3526     emh->nBytes = sizeof(*emh);
3527     /* emh->nRecords = 1; XP doesn't care about records */
3528     emh->nHandles = 1; /* XP refuses to load a EMF if nHandles == 0 */
3529 
3530     SetLastError(0xdeadbeef);
3531     hemf = SetEnhMetaFileBits(emh->nBytes, data);
3532     ok(hemf != 0, "SetEnhMetaFileBits error %u\n", GetLastError());
3533     DeleteEnhMetaFile(hemf);
3534 
3535     /* XP refuses to load unaligned EMF */
3536     emh->nBytes++;
3537     SetLastError(0xdeadbeef);
3538     hemf = SetEnhMetaFileBits(emh->nBytes, data);
3539     ok(!hemf ||
3540        broken(hemf != NULL), /* Win9x, WinMe */
3541        "SetEnhMetaFileBits should fail\n");
3542     ok(GetLastError() == 0xdeadbeef, "Expected deadbeef, got %u\n", GetLastError());
3543     DeleteEnhMetaFile(hemf);
3544 
3545     emh->dSignature = 0;
3546     emh->nBytes--;
3547     SetLastError(0xdeadbeef);
3548     hemf = SetEnhMetaFileBits(emh->nBytes, data);
3549     ok(!hemf ||
3550        broken(hemf != NULL), /* Win9x, WinMe */
3551        "SetEnhMetaFileBits should fail\n");
3552     ok(GetLastError() == 0xdeadbeef, "Expected deadbeef, got %u\n", GetLastError());
3553     DeleteEnhMetaFile(hemf);
3554 }
3555 
3556 static void test_emf_polybezier(void)
3557 {
3558     HDC hdcMetafile;
3559     HENHMETAFILE hemf;
3560     POINT pts[4];
3561     BOOL ret;
3562 
3563     SetLastError(0xdeadbeef);
3564     hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3565     ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3566 
3567     pts[0].x = pts[0].y = 10;
3568     pts[1].x = pts[1].y = 20;
3569     pts[2].x = pts[2].y = 15;
3570     pts[3].x = pts[3].y = 25;
3571     ret = PolyBezierTo(hdcMetafile, pts, 3);  /* EMR_POLYBEZIERTO16 */
3572     ok( ret, "PolyBezierTo failed\n" );
3573     ret = PolyBezier(hdcMetafile, pts, 4);    /* EMR_POLYBEZIER16   */
3574     ok( ret, "PolyBezier failed\n" );
3575 
3576     pts[0].x = pts[0].y = 32769;
3577     ret = PolyBezier(hdcMetafile, pts, 4);    /* EMR_POLYBEZIER   */
3578     ok( ret, "PolyBezier failed\n" );
3579     ret = PolyBezierTo(hdcMetafile, pts, 3);  /* EMR_POLYBEZIERTO */
3580     ok( ret, "PolyBezierTo failed\n" );
3581 
3582     hemf = CloseEnhMetaFile(hdcMetafile);
3583     ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3584 
3585     if(compare_emf_bits(hemf, EMF_BEZIER_BITS, sizeof(EMF_BEZIER_BITS),
3586         "emf_Bezier", FALSE) != 0)
3587     {
3588         dump_emf_bits(hemf, "emf_Bezier");
3589         dump_emf_records(hemf, "emf_Bezier");
3590     }
3591 
3592     DeleteEnhMetaFile(hemf);
3593 }
3594 
3595 static const unsigned char EMF_PATH_BITS[] =
3596 {
3597     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
3598     0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3599     0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3600     0x90, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
3601     0x70, 0x17, 0x00, 0x00, 0x70, 0x17, 0x00, 0x00,
3602     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
3603     0xf8, 0x02, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
3604     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3605     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3606     0x20, 0x03, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00,
3607     0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
3608     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3609     0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
3610     0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
3611     0x08, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
3612     0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
3613     0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3614     0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
3615     0x96, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3616     0x10, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3617     0x96, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3618     0x10, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3619     0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
3620     0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
3621     0x32, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
3622     0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3623     0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
3624     0x13, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
3625     0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3626     0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
3627     0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
3628     0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3629     0x15, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
3630     0x28, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
3631     0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
3632     0x1a, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
3633     0x1b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
3634     0x17, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
3635     0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3636     0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
3637     0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
3638     0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3639     0x15, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
3640     0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3641     0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
3642     0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
3643     0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
3644     0x15, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
3645     0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3646     0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
3647     0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
3648     0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3649     0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
3650     0x13, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
3651     0x05, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
3652     0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3653     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3654     0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
3655     0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00,
3656     0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00,
3657     0x59, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
3658     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3659     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3660     0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00,
3661     0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00,
3662     0x14, 0x00, 0x14, 0x00, 0x5a, 0x00, 0x00, 0x00,
3663     0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3664     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3665     0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
3666     0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
3667     0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00,
3668     0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00,
3669     0x14, 0x00, 0x14, 0x00, 0x5c, 0x00, 0x00, 0x00,
3670     0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3671     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3672     0xff, 0xff, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00,
3673     0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00,
3674     0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00,
3675     0x1e, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x14, 0x00,
3676     0x14, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x14, 0x00,
3677     0x14, 0x00, 0x0a, 0x00, 0x06, 0x02, 0x04, 0x04,
3678     0x04, 0x02, 0x03, 0x06, 0x02, 0x00, 0x00, 0x00,
3679     0x29, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
3680     0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
3681     0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x42,
3682     0x00, 0x00, 0x34, 0x43, 0x3c, 0x00, 0x00, 0x00,
3683     0x08, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
3684     0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
3685     0x0a, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
3686     0x96, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
3687     0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3688     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
3689     0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00,
3690     0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3691     0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
3692 };
3693 
3694 static const unsigned char EMF_EMPTY_PATH_BITS[] =
3695 {
3696     0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
3697     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3698     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3699     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3700     0xd8, 0xff, 0xff, 0xff, 0xd8, 0xff, 0xff, 0xff,
3701     0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
3702     0xc8, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
3703     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3704     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3705     0x20, 0x03, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00,
3706     0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
3707     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3708     0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
3709     0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
3710     0x08, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00,
3711     0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
3712     0x08, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
3713     0x08, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
3714     0x08, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00,
3715     0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
3716     0x08, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
3717     0x08, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
3718     0x08, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
3719     0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3720     0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
3721 };
3722 
3723 static void test_emf_paths(void)
3724 {
3725     POINT pts[9] = {{10, 10}, {20, 10}, {10, 20}, {20, 20}, {30, 30}, {40, 20}, {20, 30}, {20, 20}, {20, 10}};
3726     DWORD counts[2] = {2, 2};
3727     BYTE types[9] = { PT_MOVETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO,
3728                       PT_LINETO | PT_CLOSEFIGURE, PT_MOVETO, PT_LINETO };
3729     HDC hdcMetafile;
3730     HENHMETAFILE hemf;
3731     BOOL ret;
3732     int size;
3733 
3734     SetLastError(0xdeadbeef);
3735     hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3736     ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3737 
3738     BeginPath(hdcMetafile);
3739     ret = MoveToEx(hdcMetafile, 50, 50, NULL);
3740     ok( ret, "MoveToEx error %d.\n", GetLastError());
3741     ret = LineTo(hdcMetafile, 50, 150);
3742     ok( ret, "LineTo error %d.\n", GetLastError());
3743     ret = LineTo(hdcMetafile, 150, 150);
3744     ok( ret, "LineTo error %d.\n", GetLastError());
3745     ret = LineTo(hdcMetafile, 150, 50);
3746     ok( ret, "LineTo error %d.\n", GetLastError());
3747     ret = LineTo(hdcMetafile, 50, 50);
3748     ok( ret, "LineTo error %d.\n", GetLastError());
3749     Rectangle(hdcMetafile, 10, 10, 20, 20);
3750     Arc(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
3751     ArcTo(hdcMetafile, 23, 23, 37, 27, 37, 27, 23, 23);
3752     Chord(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
3753     Pie(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
3754     Ellipse(hdcMetafile, 10, 10, 20, 20);
3755     RoundRect(hdcMetafile, 10, 10, 20, 20, 3, 5);
3756     Polyline(hdcMetafile, pts, 4);
3757     PolylineTo(hdcMetafile, pts, 4);
3758     PolyPolyline(hdcMetafile, pts, counts, 2);
3759     PolyDraw(hdcMetafile, pts, types, 9);
3760     AngleArc(hdcMetafile, 37, 36, 23, 90, 180);
3761     EndPath(hdcMetafile);
3762 
3763     size = GetPath(hdcMetafile, NULL, NULL, 0);
3764     ok( size == 112, "GetPath returned %d.\n", size);
3765 
3766     ret = StrokeAndFillPath( hdcMetafile );
3767     ok( ret, "StrokeAndFillPath failed err %d\n", GetLastError() );
3768     ret = StrokeAndFillPath( hdcMetafile );
3769     ok( !ret, "StrokeAndFillPath succeeded\n" );
3770 
3771     hemf = CloseEnhMetaFile(hdcMetafile);
3772     ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3773 
3774     if (compare_emf_bits(hemf, EMF_PATH_BITS, sizeof(EMF_PATH_BITS), "test_emf_paths", FALSE) != 0)
3775     {
3776         dump_emf_bits(hemf, "test_emf_paths");
3777         dump_emf_records(hemf, "test_emf_paths");
3778     }
3779 
3780     DeleteEnhMetaFile(hemf);
3781 
3782     SetLastError(0xdeadbeef);
3783     hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3784     ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3785 
3786     ret = BeginPath(hdcMetafile);
3787     ok( ret, "BeginPath failed error %d\n", GetLastError() );
3788     ret = CloseFigure(hdcMetafile);
3789     ok( ret, "CloseFigure failed error %d\n", GetLastError() );
3790     ret = BeginPath(hdcMetafile);
3791     ok( ret, "BeginPath failed error %d\n", GetLastError() );
3792     ret = EndPath(hdcMetafile);
3793     ok( ret, "EndPath failed error %d\n", GetLastError() );
3794     ret = EndPath(hdcMetafile);
3795     ok( !ret, "EndPath succeeded\n" );
3796     ret = CloseFigure(hdcMetafile);
3797     ok( !ret, "CloseFigure succeeded\n" );
3798     ret = BeginPath(hdcMetafile);
3799     ok( ret, "BeginPath failed error %d\n", GetLastError() );
3800     ret = AbortPath(hdcMetafile);
3801     ok( ret, "AbortPath failed error %d\n", GetLastError() );
3802     ret = AbortPath(hdcMetafile);
3803     ok( ret, "AbortPath failed error %d\n", GetLastError() );
3804 
3805     hemf = CloseEnhMetaFile(hdcMetafile);
3806     ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3807 
3808     if (compare_emf_bits(hemf, EMF_EMPTY_PATH_BITS, sizeof(EMF_EMPTY_PATH_BITS), "empty path", FALSE) != 0)
3809     {
3810         dump_emf_bits(hemf, "empty path");
3811         dump_emf_records(hemf, "empty path");
3812     }
3813 
3814     DeleteEnhMetaFile(hemf);
3815 }
3816 
3817 static void test_emf_PolyPolyline(void)
3818 {
3819     HDC hdcMetafile;
3820     HENHMETAFILE hemf;
3821     POINT pts[4] = {{10, 20}, {100, 200}, {0x9000,300}, {400, 500}};
3822     DWORD counts[2];
3823     BOOL ret;
3824 
3825     SetLastError(0xdeadbeef);
3826     hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
3827     ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
3828 
3829     ret = PolyPolyline(hdcMetafile, NULL, NULL, 0);
3830     ok( !ret, "PolyPolyline\n" );
3831 
3832     SetLastError( 0xdeadbeef );
3833     counts[0] = 0;
3834     counts[1] = 1;
3835     ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3836     ok( !ret, "PolyPolyline\n" );
3837     ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
3838 
3839     SetLastError( 0xdeadbeef );
3840     counts[0] = 1;
3841     counts[1] = 1;
3842     ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3843     ok( !ret, "PolyPolyline\n" );
3844     ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
3845 
3846     SetLastError( 0xdeadbeef );
3847     counts[0] = 2;
3848     counts[1] = 1;
3849     ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3850     ok( !ret, "PolyPolyline\n" );
3851     ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
3852 
3853     counts[0] = 2;
3854     counts[1] = 2;
3855     ret = PolyPolyline(hdcMetafile, pts, counts, 2);
3856     ok( ret, "PolyPolyline\n" );
3857 
3858     hemf = CloseEnhMetaFile(hdcMetafile);
3859     ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
3860 
3861     if(compare_emf_bits(hemf, EMF_POLYPOLYLINE_BITS, sizeof(EMF_POLYPOLYLINE_BITS),
3862         "emf_PolyPolyline", FALSE) != 0)
3863     {
3864         dump_emf_bits(hemf, "emf_PolyPolyline");
3865         dump_emf_records(hemf, "emf_PolyPolyline");
3866     }
3867 
3868     DeleteEnhMetaFile(hemf);
3869 }
3870 
3871 static void test_emf_GradientFill(void)
3872 {
3873     HDC mf;
3874     HENHMETAFILE hemf;
3875     TRIVERTEX v[] =
3876     {
3877         {   1,  10, 0xff00, 0x8000, 0x0000, 0x8001 },
3878         { 200, 210, 0x0000, 0x0000, 0xff00, 0xff00 },
3879         { 180, 190, 0x1234, 0x5678, 0x9abc, 0xdef0 },
3880         { 300, 310, 0xff00, 0xff00, 0xff00, 0x0000 },
3881         { 400, 410, 0xff00, 0xff00, 0xff00, 0x0000 }
3882     };
3883     GRADIENT_TRIANGLE tri[] = { { 0, 1, 2 }, { 3, 1, 0 } };
3884     BOOL ret;
3885 
3886     mf = CreateEnhMetaFileA( GetDC( 0 ), NULL, NULL, NULL );
3887     ok( mf != 0, "CreateEnhMetaFileA error %d\n", GetLastError() );
3888 
3889     /* Don't test the GRADIENT_FILL_RECT_ modes since a Windows bug
3890      * means it allocates three mesh indices rather than two per
3891      * rectangle.  This results in uninitialised values being written
3892      * to the EMF which is rather difficult to test against.
3893      *
3894      * Note also that the final vertex here is not required, yet it is
3895      * written to the EMF, but is not considered in the bounds
3896      * calculation.
3897      */
3898     ret = GdiGradientFill( mf, v, sizeof(v) / sizeof(v[0]), tri, sizeof(tri) / sizeof(tri[0]),
3899                            GRADIENT_FILL_TRIANGLE );
3900     ok( ret, "GradientFill\n" );
3901 
3902     hemf = CloseEnhMetaFile( mf );
3903     ok( hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError() );
3904 
3905     if (compare_emf_bits( hemf, EMF_GRADIENTFILL_BITS, sizeof(EMF_GRADIENTFILL_BITS),
3906                           "emf_GradientFill", FALSE ) != 0)
3907     {
3908         dump_emf_bits( hemf, "emf_GradientFill" );
3909         dump_emf_records( hemf, "emf_GradientFill" );
3910     }
3911 
3912     DeleteEnhMetaFile( hemf );
3913 }
3914 
3915 START_TEST(metafile)
3916 {
3917     init_function_pointers();
3918 
3919     /* For enhanced metafiles (enhmfdrv) */
3920     test_ExtTextOut();
3921     test_ExtTextOutScale();
3922     test_SaveDC();
3923     test_emf_BitBlt();
3924     test_emf_DCBrush();
3925     test_emf_ExtTextOut_on_path();
3926     test_emf_clipping();
3927     test_emf_polybezier();
3928     test_emf_paths();
3929     test_emf_PolyPolyline();
3930     test_emf_GradientFill();
3931 
3932     /* For win-format metafiles (mfdrv) */
3933     test_mf_SaveDC();
3934     test_mf_Blank();
3935     test_mf_Graphics();
3936     test_mf_PatternBrush();
3937     test_mf_DCBrush();
3938     test_CopyMetaFile();
3939     test_SetMetaFileBits();
3940     test_mf_ExtTextOut_on_path();
3941     test_mf_clipping();
3942     test_mf_GetPath();
3943 
3944     /* For metafile conversions */
3945     test_mf_conversions();
3946     test_SetWinMetaFileBits();
3947     test_GetWinMetaFileBits();
3948 
3949     test_gdiis();
3950     test_SetEnhMetaFileBits();
3951 }
3952