EnumThemeColors() and EnumThemeSizes() actually do not return a single
[wine] / dlls / gdi / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
39     const ENHMETARECORD *emr, int n_objs, LPARAM param)
40 {
41     static int n_record;
42     DWORD i;
43     const INT *dx;
44     INT *orig_dx = (INT *)param;
45     LOGFONTA device_lf;
46     INT ret;
47
48     trace("hdc %p, emr->iType %ld, emr->nSize %ld, param %p\n",
49            hdc, emr->iType, emr->nSize, (void *)param);
50
51     if(!hdc) return 1;
52
53     PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
54
55     switch (emr->iType)
56     {
57     case EMR_HEADER:
58         n_record = 0;
59         break;
60
61     case EMR_EXTTEXTOUTA:
62     {
63         const EMREXTTEXTOUTA *emr_ExtTextOutA = (const EMREXTTEXTOUTA *)emr;
64         dx = (const INT *)((const char *)emr + emr_ExtTextOutA->emrtext.offDx);
65
66         ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
67         ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
68
69         /* compare up to lfOutPrecision, other values are not interesting,
70          * and in fact sometimes arbitrary adapted by Win9x.
71          */
72         ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
73         ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
74
75         for(i = 0; i < emr_ExtTextOutA->emrtext.nChars; i++)
76         {
77             ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
78                                      n_record, i, dx[i], orig_dx[i]);
79         }
80         n_record++;
81         emr_processed = TRUE;
82         break;
83     }
84
85     case EMR_EXTTEXTOUTW:
86     {
87         const EMREXTTEXTOUTW *emr_ExtTextOutW = (const EMREXTTEXTOUTW *)emr;
88         dx = (const INT *)((const char *)emr + emr_ExtTextOutW->emrtext.offDx);
89
90         ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
91         ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
92
93         /* compare up to lfOutPrecision, other values are not interesting,
94          * and in fact sometimes arbitrary adapted by Win9x.
95          */
96         ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
97         ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
98
99         for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++)
100         {
101             ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
102                                      n_record, i, dx[i], orig_dx[i]);
103         }
104         n_record++;
105         emr_processed = TRUE;
106         break;
107     }
108
109     default:
110         break;
111     }
112
113     return 1;
114 }
115
116 static void test_ExtTextOut(void)
117 {
118     HWND hwnd;
119     HDC hdcDisplay, hdcMetafile;
120     HENHMETAFILE hMetafile;
121     HFONT hFont;
122     static const char text[] = "Simple text to test ExtTextOut on metafiles";
123     INT i, len, dx[256];
124     static const RECT rc = { 0, 0, 100, 100 };
125     BOOL ret;
126
127     assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
128
129     /* Win9x doesn't play EMFs on invisible windows */
130     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
131                            0, 0, 200, 200, 0, 0, 0, NULL);
132     ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError());
133
134     hdcDisplay = GetDC(hwnd);
135     ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError());
136
137     trace("hdcDisplay %p\n", hdcDisplay);
138
139     SetMapMode(hdcDisplay, MM_TEXT);
140
141     memset(&orig_lf, 0, sizeof(orig_lf));
142
143     orig_lf.lfCharSet = ANSI_CHARSET;
144     orig_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
145     orig_lf.lfWeight = FW_DONTCARE;
146     orig_lf.lfHeight = 7;
147     orig_lf.lfQuality = DEFAULT_QUALITY;
148     lstrcpyA(orig_lf.lfFaceName, "Arial");
149     hFont = CreateFontIndirectA(&orig_lf);
150     ok(hFont != 0, "CreateFontIndirectA error %ld\n", GetLastError());
151
152     hFont = SelectObject(hdcDisplay, hFont);
153
154     len = lstrlenA(text);
155     for (i = 0; i < len; i++)
156     {
157         ret = GetCharWidthA(hdcDisplay, text[i], text[i], &dx[i]);
158         ok( ret, "GetCharWidthA error %ld\n", GetLastError());
159     }
160     hFont = SelectObject(hdcDisplay, hFont);
161
162     hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
163     ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError());
164
165     trace("hdcMetafile %p\n", hdcMetafile);
166
167     ok(GetDeviceCaps(hdcMetafile, TECHNOLOGY) == DT_RASDISPLAY,
168        "GetDeviceCaps(TECHNOLOGY) has to return DT_RASDISPLAY for a display based EMF\n");
169
170     hFont = SelectObject(hdcMetafile, hFont);
171
172     /* 1. pass NULL lpDx */
173     ret = ExtTextOutA(hdcMetafile, 0, 0, 0, &rc, text, lstrlenA(text), NULL);
174     ok( ret, "ExtTextOutA error %ld\n", GetLastError());
175
176     /* 2. pass custom lpDx */
177     ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
178     ok( ret, "ExtTextOutA error %ld\n", GetLastError());
179
180     hFont = SelectObject(hdcMetafile, hFont);
181     ret = DeleteObject(hFont);
182     ok( ret, "DeleteObject error %ld\n", GetLastError());
183
184     hMetafile = CloseEnhMetaFile(hdcMetafile);
185     ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError());
186
187     ok(!GetObjectType(hdcMetafile), "CloseEnhMetaFile has to destroy metafile hdc\n");
188
189     ret = PlayEnhMetaFile(hdcDisplay, hMetafile, &rc);
190     ok( ret, "PlayEnhMetaFile error %ld\n", GetLastError());
191
192     ret = EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, &rc);
193     ok( ret, "EnumEnhMetaFile error %ld\n", GetLastError());
194
195     ok(emr_processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record\n");
196
197     ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, NULL),
198        "A valid hdc has to require a valid rc\n");
199
200     ok(EnumEnhMetaFile(NULL, hMetafile, emf_enum_proc, dx, NULL),
201        "A null hdc does not require a valid rc\n");
202
203     ret = DeleteEnhMetaFile(hMetafile);
204     ok( ret, "DeleteEnhMetaFile error %ld\n", GetLastError());
205     ret = ReleaseDC(hwnd, hdcDisplay);
206     ok( ret, "ReleaseDC error %ld\n", GetLastError());
207 }
208
209 /* Win-format metafile (mfdrv) tests */
210 /* These tests compare the generated metafiles byte-by-byte */
211 /* with the nominal results. */
212
213 /* Maximum size of sample metafiles in bytes. */
214 #define MF_BUFSIZE 256
215
216 /* 8x8 bitmap data for a pattern brush */
217 static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
218     0x01, 0x00, 0x02, 0x00,
219     0x03, 0x00, 0x04, 0x00,
220     0x05, 0x00, 0x06, 0x00,
221     0x07, 0x00, 0x08, 0x00
222 };
223
224 /* Sample metafiles to be compared to the outputs of the
225  * test functions.
226  */
227
228 static const unsigned char MF_BLANK_BITS[] = {
229     0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x0c, 0x00,
230     0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
231     0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
232 };
233
234 static const unsigned char MF_GRAPHICS_BITS[] = {
235     0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x22, 0x00,
236     0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
237     0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
238     0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
239     0x13, 0x02, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00,
240     0x00, 0x00, 0x14, 0x02, 0x01, 0x00, 0x01, 0x00,
241     0x07, 0x00, 0x00, 0x00, 0x18, 0x04, 0x02, 0x00,
242     0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
243     0x00, 0x00, 0x00, 0x00
244 };
245
246 static const unsigned char MF_PATTERN_BRUSH_BITS[] = {
247     0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x3d, 0x00,
248     0x00, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00,
249     0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x42, 0x01,
250     0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
251     0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
252     0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
253     0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256     0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00,
257     0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
258     0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
259     0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
260     0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
261     0x2d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
262     0x00, 0x00
263 };
264
265 /* For debugging or dumping the raw metafiles produced by
266  * new test functions.
267  */
268
269 static void dump_mf_bits (const HMETAFILE mf, const char *desc)
270 {
271     char buf[MF_BUFSIZE];
272     UINT mfsize, i;
273
274     mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
275     ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
276
277     printf ("MetaFile %s has bits:\n{\n    ", desc);
278     for (i=0; i<mfsize; i++)
279     {
280         printf ("0x%.2hhx", buf[i]);
281         if (i == mfsize-1)
282             printf ("\n");
283         else if (i % 8 == 7)
284             printf (",\n    ");
285         else
286             printf (", ");
287     }
288     printf ("};\n");
289 }
290
291 /* Compare the metafile produced by a test function with the
292  * expected raw metafile data in "bits".
293  * Return value is 0 for a perfect match,
294  * -1 if lengths aren't equal,
295  * otherwise returns the number of non-matching bytes.
296  */
297
298 static int compare_mf_bits (const HMETAFILE mf, const unsigned char *bits, UINT bsize,
299     const char *desc)
300 {
301     unsigned char buf[MF_BUFSIZE];
302     UINT mfsize, i;
303     int diff;
304
305     mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
306     ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
307     if (mfsize < MF_BUFSIZE)
308         ok (mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n",
309             desc, mfsize, bsize);
310     else
311         ok (bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d.\n",
312             desc, mfsize, bsize);
313     if (mfsize != bsize)
314         return -1;
315
316     diff = 0;
317     for (i=0; i<bsize; i++)
318     {
319        if (buf[i] !=  bits[i])
320            diff++;
321     }
322     ok (diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
323         desc, mfsize, bsize, diff);
324
325     return diff; 
326 }
327
328 /* Test a blank metafile.  May be used as a template for new tests. */
329
330 static void test_mf_Blank(void)
331 {
332     HDC hdcMetafile;
333     HMETAFILE hMetafile;
334     INT caps;
335     BOOL ret;
336
337     hdcMetafile = CreateMetaFileA(NULL);
338     ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
339     trace("hdcMetafile %p\n", hdcMetafile);
340
341 /* Tests on metafile initialization */
342     caps = GetDeviceCaps (hdcMetafile, TECHNOLOGY);
343     ok (caps == DT_METAFILE,
344         "GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE.\n", caps);
345
346     hMetafile = CloseMetaFile(hdcMetafile);
347     ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
348     ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
349
350     if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
351         "mf_blank") != 0)
352             dump_mf_bits (hMetafile, "mf_Blank");
353
354     ret = DeleteMetaFile(hMetafile);
355     ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
356 }
357
358 /* Simple APIs from mfdrv/graphics.c
359  */
360
361 static void test_mf_Graphics(void)
362 {
363     HDC hdcMetafile;
364     HMETAFILE hMetafile;
365     POINT oldpoint;
366     BOOL ret;
367
368     hdcMetafile = CreateMetaFileA(NULL);
369     ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
370     trace("hdcMetafile %p\n", hdcMetafile);
371
372     ret = MoveToEx(hdcMetafile, 1, 1, NULL);
373     ok( ret, "MoveToEx error %ld.\n", GetLastError());
374     ret = LineTo(hdcMetafile, 2, 2);
375     ok( ret, "LineTo error %ld.\n", GetLastError());
376     ret = MoveToEx(hdcMetafile, 1, 1, &oldpoint);
377     ok( ret, "MoveToEx error %ld.\n", GetLastError());
378
379 /* oldpoint gets garbage under Win XP, so the following test would
380  * work under Wine but fails under Windows:
381  *
382  *   ok((oldpoint.x == 2) && (oldpoint.y == 2),
383  *       "MoveToEx: (x, y) = (%ld, %ld), should be (2, 2).\n",
384  *       oldpoint.x, oldpoint.y);
385  */
386
387     ret = Ellipse(hdcMetafile, 0, 0, 2, 2);
388     ok( ret, "Ellipse error %ld.\n", GetLastError());
389
390     hMetafile = CloseMetaFile(hdcMetafile);
391     ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
392     ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
393
394     if (compare_mf_bits (hMetafile, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS),
395         "mf_Graphics") != 0)
396             dump_mf_bits (hMetafile, "mf_Graphics");
397
398     ret = DeleteMetaFile(hMetafile);
399     ok( ret, "DeleteMetaFile(%p) error %ld\n",
400         hMetafile, GetLastError());
401 }
402
403 static void test_mf_PatternBrush(void)
404 {
405     HDC hdcMetafile;
406     HMETAFILE hMetafile;
407     LOGBRUSH *orig_lb;
408     HBRUSH hBrush;
409     BOOL ret;
410
411     orig_lb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGBRUSH));
412
413     orig_lb->lbStyle = BS_PATTERN;
414     orig_lb->lbColor = RGB(0, 0, 0);
415     orig_lb->lbHatch = (INT) CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH);
416     ok((HBITMAP *)orig_lb->lbHatch != NULL, "CreateBitmap error %ld.\n", GetLastError());
417
418     hBrush = CreateBrushIndirect (orig_lb);
419     ok(hBrush != 0, "CreateBrushIndirect error %ld\n", GetLastError());
420
421     hdcMetafile = CreateMetaFileA(NULL);
422     ok(hdcMetafile != 0, "CreateMetaFileA error %ld\n", GetLastError());
423     trace("hdcMetafile %p\n", hdcMetafile);
424
425     hBrush = SelectObject(hdcMetafile, hBrush);
426     ok(hBrush != 0, "SelectObject error %ld.\n", GetLastError());
427
428     hMetafile = CloseMetaFile(hdcMetafile);
429     ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
430     ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
431
432     if (compare_mf_bits (hMetafile, MF_PATTERN_BRUSH_BITS, sizeof(MF_PATTERN_BRUSH_BITS),
433         "mf_Pattern_Brush") != 0)
434             dump_mf_bits (hMetafile, "mf_Pattern_Brush");
435
436     ret = DeleteMetaFile(hMetafile);
437     ok( ret, "DeleteMetaFile error %ld\n", GetLastError());
438     ret = DeleteObject(hBrush);
439     ok( ret, "DeleteObject(HBRUSH) error %ld\n", GetLastError());
440     ret = DeleteObject((HBITMAP *)orig_lb->lbHatch);
441     ok( ret, "DeleteObject(HBITMAP) error %ld\n",
442         GetLastError());
443     HeapFree (GetProcessHeap(), 0, orig_lb);
444 }
445
446 static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
447 {
448     LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData;
449     POINT mapping[2] = { { 0, 0 }, { 10, 10 } };
450     /* When using MM_TEXT Win9x does not update the mapping mode 
451      * until a record is played which actually outputs something */
452     PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
453     LPtoDP(hdc, mapping, 2);
454     trace("Meta record: iType = %ld, (%ld,%ld)-(%ld,%ld)\n", lpEMFR->iType, mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
455     if (lpEMFR->iType == EMR_LINETO)
456     {
457         INT x0, y0, x1, y1;
458         if (!lpMFP || lpMFP->mm == MM_TEXT)
459         {
460             x0 = 0;
461             y0 = 0;
462             x1 = (INT)floor(10 * 100.0 / LINE_X + 0.5);
463             y1 = (INT)floor(10 * 100.0 / LINE_Y + 0.5);
464         }
465         else
466         {
467             ok(lpMFP->mm == MM_ANISOTROPIC, "mm=%ld\n", lpMFP->mm);
468             
469             x0 = MulDiv(0, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
470             y0 = MulDiv(0, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
471             x1 = MulDiv(10, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
472             y1 = MulDiv(10, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
473         }
474         ok(mapping[0].x == x0 && mapping[0].y == y0 && mapping[1].x == x1 && mapping[1].y == y1,
475             "(%ld,%ld)->(%ld,%ld), expected (%d,%d)->(%d,%d)\n",
476             mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y,
477             x0, y0, x1, y1);
478     }
479     return TRUE;
480 }
481
482 static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
483 {
484     HDC hdcMf;
485     HMETAFILE hmf;
486     BOOL ret;
487     UINT size;
488     LPBYTE pBits;
489
490     hdcMf = CreateMetaFile(NULL);
491     ok(hdcMf != NULL, "CreateMetaFile failed with error %ld\n", GetLastError());
492     ret = LineTo(hdcMf, (INT)LINE_X, (INT)LINE_Y);
493     ok(ret, "LineTo failed with error %ld\n", GetLastError());
494     hmf = CloseMetaFile(hdcMf);
495     ok(hmf != NULL, "CloseMetaFile failed with error %ld\n", GetLastError());
496     size = GetMetaFileBitsEx(hmf, 0, NULL);
497     ok(size, "GetMetaFileBitsEx failed with error %ld\n", GetLastError());
498     pBits = HeapAlloc(GetProcessHeap(), 0, size);
499     GetMetaFileBitsEx(hmf, size, pBits);
500     DeleteMetaFile(hmf);
501     return SetWinMetaFileBits(size, pBits, NULL, mfp);
502 }
503
504 static void test_mf_conversions(void)
505 {
506     trace("Testing MF->EMF conversion (MM_ANISOTROPIC)\n");
507     {
508         HDC hdcOffscreen = CreateCompatibleDC(NULL);
509         HENHMETAFILE hemf;
510         METAFILEPICT mfp;
511         RECT rect = { 0, 0, 100, 100 };
512         mfp.mm = MM_ANISOTROPIC;
513         mfp.xExt = 100;
514         mfp.yExt = 100;
515         mfp.hMF = NULL;
516         hemf = create_converted_emf(&mfp);
517         EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
518         DeleteEnhMetaFile(hemf);
519         DeleteDC(hdcOffscreen);
520     }
521
522     trace("Testing MF->EMF conversion (MM_TEXT)\n");
523     {
524         HDC hdcOffscreen = CreateCompatibleDC(NULL);
525         HENHMETAFILE hemf;
526         METAFILEPICT mfp;
527         RECT rect = { 0, 0, 100, 100 };
528         mfp.mm = MM_TEXT;
529         mfp.xExt = 0;
530         mfp.yExt = 0;
531         mfp.hMF = NULL;
532         hemf = create_converted_emf(&mfp);
533         EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
534         DeleteEnhMetaFile(hemf);
535         DeleteDC(hdcOffscreen);
536     }
537
538     trace("Testing MF->EMF conversion (NULL mfp)\n");
539     {
540         HDC hdcOffscreen = CreateCompatibleDC(NULL);
541         HENHMETAFILE hemf;
542         RECT rect = { 0, 0, 100, 100 };
543         hemf = create_converted_emf(NULL);
544         EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, NULL, &rect);
545         DeleteEnhMetaFile(hemf);
546         DeleteDC(hdcOffscreen);
547     }
548 }
549
550 static BOOL (WINAPI *pGdiIsMetaPrintDC)(HDC);
551 static BOOL (WINAPI *pGdiIsMetaFileDC)(HDC);
552 static BOOL (WINAPI *pGdiIsPlayMetafileDC)(HDC);
553
554 static void test_gdiis(void)
555 {
556     RECT rect = {0,0,100,100};
557     HDC hdc, hemfDC, hmfDC;
558     HENHMETAFILE hemf;
559     HMODULE hgdi32;
560
561     /* resolve all the functions */
562     hgdi32 = GetModuleHandle("gdi32");
563     pGdiIsMetaPrintDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaPrintDC");
564     pGdiIsMetaFileDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaFileDC");
565     pGdiIsPlayMetafileDC = (void*) GetProcAddress(hgdi32, "GdiIsPlayMetafileDC");
566
567     /* they should all exist or none should exist */
568     if(!pGdiIsMetaPrintDC)
569         return;
570
571     /* try with nothing */
572     ok(!pGdiIsMetaPrintDC(NULL), "ismetaprint with NULL parameter\n");
573     ok(!pGdiIsMetaFileDC(NULL), "ismetafile with NULL parameter\n");
574     ok(!pGdiIsPlayMetafileDC(NULL), "isplaymetafile with NULL parameter\n");
575
576     /* try with a metafile */
577     hmfDC = CreateMetaFile(NULL);
578     ok(!pGdiIsMetaPrintDC(hmfDC), "ismetaprint on metafile\n");
579     ok(pGdiIsMetaFileDC(hmfDC), "ismetafile on metafile\n");
580     ok(!pGdiIsPlayMetafileDC(hmfDC), "isplaymetafile on metafile\n");
581     DeleteObject(CloseMetaFile(hmfDC));
582
583     /* try with an enhanced metafile */
584     hdc = GetDC(NULL);
585     hemfDC = CreateEnhMetaFileW(hdc, NULL, &rect, NULL);
586     ok(hemfDC != NULL, "failed to create emf\n");
587
588     ok(!pGdiIsMetaPrintDC(hemfDC), "ismetaprint on emf\n");
589     ok(pGdiIsMetaFileDC(hemfDC), "ismetafile on emf\n");
590     ok(!pGdiIsPlayMetafileDC(hemfDC), "isplaymetafile on emf\n");
591
592     hemf = CloseEnhMetaFile(hemfDC);
593     ok(hemf != NULL, "failed to close EMF\n");
594     DeleteObject(hemf);
595     ReleaseDC(NULL,hdc);
596 }
597
598 START_TEST(metafile)
599 {
600     /* For enhanced metafiles (enhmfdrv) */
601     test_ExtTextOut();
602
603     /* For win-format metafiles (mfdrv) */
604     test_mf_Blank();
605     test_mf_Graphics();
606     test_mf_PatternBrush();
607
608     /* For metafile conversions */
609     test_mf_conversions();
610
611     test_gdiis();
612 }