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