2 * Unit tests for metafile functions
4 * Copyright (c) 2002 Dmitry Timoshkov
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.
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.
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
25 #include "wine/test.h"
31 static LOGFONTA orig_lf;
32 static BOOL emr_processed = FALSE;
34 /* Arbitrarily chosen values for the second co-ordinate of a metafile line */
38 static INT (WINAPI * pGetRelAbs)(HDC, DWORD);
39 static INT (WINAPI * pSetRelAbs)(HDC, INT);
41 #define GDI_GET_PROC(func) \
42 p ## func = (void *)GetProcAddress(hGDI, #func); \
44 trace("GetProcAddress(hGDI, \"%s\") failed\n", #func); \
46 static void init_function_pointers(void)
53 hGDI = GetModuleHandleA("gdi32.dll");
55 GDI_GET_PROC(GetRelAbs);
56 GDI_GET_PROC(SetRelAbs);
59 static int CALLBACK eto_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
60 const ENHMETARECORD *emr, int n_objs, LPARAM param)
65 INT *orig_dx = (INT *)param;
69 trace("hdc %p, emr->iType %ld, emr->nSize %ld, param %p\n",
70 hdc, emr->iType, emr->nSize, (void *)param);
74 PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
79 ok(GetTextAlign(hdc) == 0, "text align %08x\n", GetTextAlign(hdc));
80 ok(GetBkColor(hdc) == RGB(0xff, 0xff, 0xff), "bk color %08lx\n", GetBkColor(hdc));
81 ok(GetTextColor(hdc) == RGB(0x0, 0x0, 0x0), "text color %08lx\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));
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));
97 const EMREXTTEXTOUTA *emr_ExtTextOutA = (const EMREXTTEXTOUTA *)emr;
98 dx = (const INT *)((const char *)emr + emr_ExtTextOutA->emrtext.offDx);
100 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
101 ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
103 /* compare up to lfOutPrecision, other values are not interesting,
104 * and in fact sometimes arbitrary adapted by Win9x.
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");
109 for(i = 0; i < emr_ExtTextOutA->emrtext.nChars; i++)
111 ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
112 n_record, i, dx[i], orig_dx[i]);
115 emr_processed = TRUE;
119 case EMR_EXTTEXTOUTW:
121 const EMREXTTEXTOUTW *emr_ExtTextOutW = (const EMREXTTEXTOUTW *)emr;
122 dx = (const INT *)((const char *)emr + emr_ExtTextOutW->emrtext.offDx);
124 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
125 ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
127 /* compare up to lfOutPrecision, other values are not interesting,
128 * and in fact sometimes arbitrary adapted by Win9x.
130 ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
131 ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
133 for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++)
135 ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
136 n_record, i, dx[i], orig_dx[i]);
139 emr_processed = TRUE;
150 static void test_ExtTextOut(void)
153 HDC hdcDisplay, hdcMetafile;
154 HENHMETAFILE hMetafile;
156 static const char text[] = "Simple text to test ExtTextOut on metafiles";
158 static const RECT rc = { 0, 0, 100, 100 };
161 assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
163 /* Win9x doesn't play EMFs on invisible windows */
164 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
165 0, 0, 200, 200, 0, 0, 0, NULL);
166 ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError());
168 hdcDisplay = GetDC(hwnd);
169 ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError());
171 trace("hdcDisplay %p\n", hdcDisplay);
173 SetMapMode(hdcDisplay, MM_TEXT);
175 memset(&orig_lf, 0, sizeof(orig_lf));
177 orig_lf.lfCharSet = ANSI_CHARSET;
178 orig_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
179 orig_lf.lfWeight = FW_DONTCARE;
180 orig_lf.lfHeight = 7;
181 orig_lf.lfQuality = DEFAULT_QUALITY;
182 lstrcpyA(orig_lf.lfFaceName, "Arial");
183 hFont = CreateFontIndirectA(&orig_lf);
184 ok(hFont != 0, "CreateFontIndirectA error %ld\n", GetLastError());
186 hFont = SelectObject(hdcDisplay, hFont);
188 len = lstrlenA(text);
189 for (i = 0; i < len; i++)
191 ret = GetCharWidthA(hdcDisplay, text[i], text[i], &dx[i]);
192 ok( ret, "GetCharWidthA error %ld\n", GetLastError());
194 hFont = SelectObject(hdcDisplay, hFont);
196 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
197 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError());
199 trace("hdcMetafile %p\n", hdcMetafile);
201 ok(GetDeviceCaps(hdcMetafile, TECHNOLOGY) == DT_RASDISPLAY,
202 "GetDeviceCaps(TECHNOLOGY) has to return DT_RASDISPLAY for a display based EMF\n");
204 hFont = SelectObject(hdcMetafile, hFont);
206 /* 1. pass NULL lpDx */
207 ret = ExtTextOutA(hdcMetafile, 0, 0, 0, &rc, text, lstrlenA(text), NULL);
208 ok( ret, "ExtTextOutA error %ld\n", GetLastError());
210 /* 2. pass custom lpDx */
211 ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
212 ok( ret, "ExtTextOutA error %ld\n", GetLastError());
214 hFont = SelectObject(hdcMetafile, hFont);
215 ret = DeleteObject(hFont);
216 ok( ret, "DeleteObject error %ld\n", GetLastError());
218 hMetafile = CloseEnhMetaFile(hdcMetafile);
219 ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError());
221 ok(!GetObjectType(hdcMetafile), "CloseEnhMetaFile has to destroy metafile hdc\n");
223 ret = PlayEnhMetaFile(hdcDisplay, hMetafile, &rc);
224 ok( ret, "PlayEnhMetaFile error %ld\n", GetLastError());
226 SetTextAlign(hdcDisplay, TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING );
227 SetBkColor(hdcDisplay, RGB(0xff, 0, 0));
228 SetTextColor(hdcDisplay, RGB(0, 0xff, 0));
229 SetROP2(hdcDisplay, R2_NOT);
230 SetArcDirection(hdcDisplay, AD_CLOCKWISE);
231 SetPolyFillMode(hdcDisplay, WINDING);
232 SetStretchBltMode(hdcDisplay, HALFTONE);
234 if(pSetRelAbs) pSetRelAbs(hdcDisplay, RELATIVE);
235 SetBkMode(hdcDisplay, OPAQUE);
237 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, &rc);
238 ok( ret, "EnumEnhMetaFile error %ld\n", GetLastError());
240 ok( GetTextAlign(hdcDisplay) == (TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING),
241 "text align %08x\n", GetTextAlign(hdcDisplay));
242 ok( GetBkColor(hdcDisplay) == RGB(0xff, 0, 0), "bk color %08lx\n", GetBkColor(hdcDisplay));
243 ok( GetTextColor(hdcDisplay) == RGB(0, 0xff, 0), "text color %08lx\n", GetTextColor(hdcDisplay));
244 ok( GetROP2(hdcDisplay) == R2_NOT, "rop2 %d\n", GetROP2(hdcDisplay));
245 ok( GetArcDirection(hdcDisplay) == AD_CLOCKWISE, "arc dir %d\n", GetArcDirection(hdcDisplay));
246 ok( GetPolyFillMode(hdcDisplay) == WINDING, "poly fill %d\n", GetPolyFillMode(hdcDisplay));
247 ok( GetStretchBltMode(hdcDisplay) == HALFTONE, "stretchblt mode %d\n", GetStretchBltMode(hdcDisplay));
249 ok(emr_processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record\n");
251 ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, eto_emf_enum_proc, dx, NULL),
252 "A valid hdc has to require a valid rc\n");
254 ok(EnumEnhMetaFile(NULL, hMetafile, eto_emf_enum_proc, dx, NULL),
255 "A null hdc does not require a valid rc\n");
257 ret = DeleteEnhMetaFile(hMetafile);
258 ok( ret, "DeleteEnhMetaFile error %ld\n", GetLastError());
259 ret = ReleaseDC(hwnd, hdcDisplay);
260 ok( ret, "ReleaseDC error %ld\n", GetLastError());
264 static int CALLBACK savedc_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
265 const ENHMETARECORD *emr, int n_objs, LPARAM param)
267 static int save_state;
268 static int restore_no;
283 EMRRESTOREDC *restoredc = (EMRRESTOREDC *)emr;
287 ok(restoredc->iRelative == -1, "first restore %ld\n", restoredc->iRelative);
291 ok(restoredc->iRelative == -3, "second restore %ld\n", restoredc->iRelative);
294 ok(restoredc->iRelative == -2, "third restore %ld\n", restoredc->iRelative);
297 ok(restore_no <= 3, "restore_no %d\n", restore_no);
298 save_state += restoredc->iRelative;
302 ok(save_state == 0, "EOF save_state %d\n", save_state);
310 void test_SaveDC(void)
312 HDC hdcMetafile, hdcDisplay;
313 HENHMETAFILE hMetafile;
316 static const RECT rc = { 0, 0, 100, 100 };
318 /* Win9x doesn't play EMFs on invisible windows */
319 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
320 0, 0, 200, 200, 0, 0, 0, NULL);
321 ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError());
323 hdcDisplay = GetDC(hwnd);
324 ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError());
326 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
327 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError());
329 /* Need to write something to the emf, otherwise Windows won't play it back */
330 LineTo(hdcMetafile, 100, 100);
332 ret = SaveDC(hdcMetafile);
333 ok(ret == 1, "ret = %d\n", ret);
335 ret = SaveDC(hdcMetafile);
336 ok(ret == 2, "ret = %d\n", ret);
338 ret = SaveDC(hdcMetafile);
339 ok(ret == 3, "ret = %d\n", ret);
341 ret = RestoreDC(hdcMetafile, -1);
342 ok(ret, "ret = %d\n", ret);
344 ret = SaveDC(hdcMetafile);
345 ok(ret == 3, "ret = %d\n", ret);
347 ret = RestoreDC(hdcMetafile, 1);
348 ok(ret, "ret = %d\n", ret);
350 ret = SaveDC(hdcMetafile);
351 ok(ret == 1, "ret = %d\n", ret);
353 ret = SaveDC(hdcMetafile);
354 ok(ret == 2, "ret = %d\n", ret);
356 hMetafile = CloseEnhMetaFile(hdcMetafile);
357 ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError());
359 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, savedc_emf_enum_proc, 0, &rc);
360 ok( ret == 1, "EnumEnhMetaFile rets %d\n", ret);
362 ret = DeleteEnhMetaFile(hMetafile);
363 ok( ret, "DeleteEnhMetaFile error %ld\n", GetLastError());
364 ret = ReleaseDC(hwnd, hdcDisplay);
365 ok( ret, "ReleaseDC error %ld\n", GetLastError());
369 /* Win-format metafile (mfdrv) tests */
370 /* These tests compare the generated metafiles byte-by-byte */
371 /* with the nominal results. */
373 /* Maximum size of sample metafiles in bytes. */
374 #define MF_BUFSIZE 256
376 /* 8x8 bitmap data for a pattern brush */
377 static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
378 0x01, 0x00, 0x02, 0x00,
379 0x03, 0x00, 0x04, 0x00,
380 0x05, 0x00, 0x06, 0x00,
381 0x07, 0x00, 0x08, 0x00
384 /* Sample metafiles to be compared to the outputs of the
388 static const unsigned char MF_BLANK_BITS[] = {
389 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x0c, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
394 static const unsigned char MF_GRAPHICS_BITS[] = {
395 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x22, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
398 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
399 0x13, 0x02, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00,
400 0x00, 0x00, 0x14, 0x02, 0x01, 0x00, 0x01, 0x00,
401 0x07, 0x00, 0x00, 0x00, 0x18, 0x04, 0x02, 0x00,
402 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
403 0x00, 0x00, 0x00, 0x00
406 static const unsigned char MF_PATTERN_BRUSH_BITS[] = {
407 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x3d, 0x00,
408 0x00, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x42, 0x01,
410 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
411 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
412 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00,
417 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
418 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
419 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
420 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
421 0x2d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
425 static const unsigned char MF_TEXTOUT_ON_PATH_BITS[] =
427 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
430 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
431 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
432 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
436 static const unsigned char EMF_TEXTOUT_ON_PATH_BITS[] =
438 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
443 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
444 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
445 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
448 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
451 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
452 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
453 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
455 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
457 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
458 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
461 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
462 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
463 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
464 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
465 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
466 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
468 0x14, 0x00, 0x00, 0x00
471 /* For debugging or dumping the raw metafiles produced by
472 * new test functions.
474 static INT CALLBACK mf_enum_proc(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
475 INT nobj, LPARAM param)
477 trace("hdc %p, mr->rdFunction %d, mr->rdSize %lu, param %p\n",
478 hdc, mr->rdFunction, mr->rdSize, (void *)param);
482 /* For debugging or dumping the raw metafiles produced by
483 * new test functions.
486 static void dump_mf_bits (const HMETAFILE mf, const char *desc)
488 char buf[MF_BUFSIZE];
491 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
492 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
494 printf ("MetaFile %s has bits:\n{\n ", desc);
495 for (i=0; i<mfsize; i++)
497 printf ("0x%.2hhx", buf[i]);
508 /* Compare the metafile produced by a test function with the
509 * expected raw metafile data in "bits".
510 * Return value is 0 for a perfect match,
511 * -1 if lengths aren't equal,
512 * otherwise returns the number of non-matching bytes.
515 static int compare_mf_bits (const HMETAFILE mf, const unsigned char *bits, UINT bsize,
518 unsigned char buf[MF_BUFSIZE];
522 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
523 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
524 if (mfsize < MF_BUFSIZE)
525 ok (mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n",
526 desc, mfsize, bsize);
528 ok (bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d.\n",
529 desc, mfsize, bsize);
534 for (i=0; i<bsize; i++)
536 if (buf[i] != bits[i])
539 ok (diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
540 desc, mfsize, bsize, diff);
545 static int compare_mf_disk_bits(LPCSTR name, const BYTE *bits, UINT bsize, const char *desc)
547 unsigned char buf[MF_BUFSIZE];
548 DWORD mfsize, rd_size, i;
553 hfile = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
554 assert(hfile != INVALID_HANDLE_VALUE);
556 mfsize = GetFileSize(hfile, NULL);
557 assert(mfsize <= MF_BUFSIZE);
559 ret = ReadFile(hfile, buf, sizeof(buf), &rd_size, NULL);
560 ok( ret && rd_size == mfsize, "ReadFile: error %ld\n", GetLastError());
564 ok(mfsize == bsize, "%s: mfsize=%ld, bsize=%d.\n", desc, mfsize, bsize);
570 for (i=0; i<bsize; i++)
572 if (buf[i] != bits[i])
575 ok(diff == 0, "%s: mfsize=%ld, bsize=%d, diff=%d\n",
576 desc, mfsize, bsize, diff);
581 /* For debugging or dumping the raw EMFs produced by
582 * new test functions.
584 static void dump_emf_bits(const HENHMETAFILE mf, const char *desc)
586 BYTE buf[MF_BUFSIZE];
589 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
590 ok (mfsize > 0, "%s: GetEnhMetaFileBits failed\n", desc);
592 printf("EMF %s has bits:\n{\n ", desc);
593 for (i = 0; i < mfsize; i++)
595 printf ("0x%02x", buf[i]);
606 static void dump_emf_records(const HENHMETAFILE mf, const char *desc)
609 BYTE buf[MF_BUFSIZE];
612 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
613 ok (mfsize > 0, "%s: GetEnhMetaFileBits failed\n", desc);
615 printf("EMF %s has records:\n", desc);
619 while(offset < mfsize)
621 EMR *emr = (EMR *)(emf + offset);
622 trace("emr->iType %ld, emr->nSize %lu\n", emr->iType, emr->nSize);
623 /*trace("emr->iType 0x%04lx, emr->nSize 0x%04lx\n", emr->iType, emr->nSize);*/
624 offset += emr->nSize;
628 /* Compare the EMF produced by a test function with the
629 * expected raw EMF data in "bits".
630 * Return value is 0 for a perfect match,
631 * -1 if lengths aren't equal,
632 * otherwise returns the number of non-matching bytes.
634 static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
635 UINT bsize, const char *desc, BOOL todo)
637 unsigned char buf[MF_BUFSIZE];
641 mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
642 ok (mfsize > 0, "%s: GetEnhMetaFileBits failed\n", desc);
644 if (mfsize < MF_BUFSIZE)
645 ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize);
647 ok(bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d\n",
648 desc, mfsize, bsize);
653 for (i = 0; i < bsize; i++)
655 if (buf[i] != bits[i])
658 if (diff != 0 && todo)
662 ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
663 desc, mfsize, bsize, diff);
669 ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
670 desc, mfsize, bsize, diff);
676 /* Test a blank metafile. May be used as a template for new tests. */
678 static void test_mf_Blank(void)
686 hdcMetafile = CreateMetaFileA(NULL);
687 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
688 trace("hdcMetafile %p\n", hdcMetafile);
690 /* Tests on metafile initialization */
691 caps = GetDeviceCaps (hdcMetafile, TECHNOLOGY);
692 ok (caps == DT_METAFILE,
693 "GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE.\n", caps);
695 hMetafile = CloseMetaFile(hdcMetafile);
696 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
697 type = GetObjectType(hMetafile);
698 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
699 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
701 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
704 dump_mf_bits(hMetafile, "mf_Blank");
705 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
708 ret = DeleteMetaFile(hMetafile);
709 ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
712 static void test_CopyMetaFile(void)
715 HMETAFILE hMetafile, hmf_copy;
717 char temp_path[MAX_PATH];
718 char mf_name[MAX_PATH];
721 hdcMetafile = CreateMetaFileA(NULL);
722 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
723 trace("hdcMetafile %p\n", hdcMetafile);
725 hMetafile = CloseMetaFile(hdcMetafile);
726 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
727 type = GetObjectType(hMetafile);
728 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
730 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
733 dump_mf_bits(hMetafile, "mf_Blank");
734 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
737 GetTempPathA(MAX_PATH, temp_path);
738 GetTempFileNameA(temp_path, "wmf", 0, mf_name);
740 hmf_copy = CopyMetaFileA(hMetafile, mf_name);
741 ok(hmf_copy != 0, "CopyMetaFile error %ld\n", GetLastError());
743 type = GetObjectType(hmf_copy);
744 ok(type == OBJ_METAFILE, "CopyMetaFile created object with type %d\n", type);
746 ret = DeleteMetaFile(hMetafile);
747 ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
749 if (compare_mf_disk_bits(mf_name, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0)
751 dump_mf_bits(hMetafile, "mf_Blank");
752 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
755 ret = DeleteMetaFile(hmf_copy);
756 ok( ret, "DeleteMetaFile(%p) error %ld\n", hmf_copy, GetLastError());
758 DeleteFileA(mf_name);
761 static void test_SetMetaFileBits(void)
769 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), MF_GRAPHICS_BITS);
770 ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
771 type = GetObjectType(hmf);
772 ok(type == OBJ_METAFILE, "SetMetaFileBitsEx created object with type %d\n", type);
774 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
776 dump_mf_bits(hmf, "mf_Graphics");
777 EnumMetaFile(0, hmf, mf_enum_proc, 0);
780 ret = DeleteMetaFile(hmf);
781 ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
783 /* NULL data crashes XP SP1 */
784 /*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/
786 /* Now with not zero size */
787 SetLastError(0xdeadbeef);
788 hmf = SetMetaFileBitsEx(0, MF_GRAPHICS_BITS);
789 ok(!hmf, "SetMetaFileBitsEx should fail\n");
790 ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError());
792 /* Now with not even size */
793 SetLastError(0xdeadbeef);
794 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS) - 1, MF_GRAPHICS_BITS);
795 ok(!hmf, "SetMetaFileBitsEx should fail\n");
796 ok(GetLastError() == 0xdeadbeef /* XP SP1 */, "wrong error %ld\n", GetLastError());
798 /* Now with zeroed out or faked some header fields */
799 assert(sizeof(buf) >= sizeof(MF_GRAPHICS_BITS));
800 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
801 mh = (METAHEADER *)buf;
802 /* corruption of any of the below fields leads to a failure */
805 mh->mtHeaderSize = 0;
806 SetLastError(0xdeadbeef);
807 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
808 ok(!hmf, "SetMetaFileBitsEx should fail\n");
809 ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError());
811 /* Now with corrupted mtSize field */
812 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
813 mh = (METAHEADER *)buf;
814 /* corruption of mtSize doesn't lead to a failure */
816 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
817 ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
819 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
821 dump_mf_bits(hmf, "mf_Graphics");
822 EnumMetaFile(0, hmf, mf_enum_proc, 0);
825 ret = DeleteMetaFile(hmf);
826 ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
828 /* Now with zeroed out mtSize field */
829 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
830 mh = (METAHEADER *)buf;
831 /* zeroing mtSize doesn't lead to a failure */
833 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
834 ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
836 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
838 dump_mf_bits(hmf, "mf_Graphics");
839 EnumMetaFile(0, hmf, mf_enum_proc, 0);
842 ret = DeleteMetaFile(hmf);
843 ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
846 /* Simple APIs from mfdrv/graphics.c
849 static void test_mf_Graphics(void)
856 hdcMetafile = CreateMetaFileA(NULL);
857 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
858 trace("hdcMetafile %p\n", hdcMetafile);
860 ret = MoveToEx(hdcMetafile, 1, 1, NULL);
861 ok( ret, "MoveToEx error %ld.\n", GetLastError());
862 ret = LineTo(hdcMetafile, 2, 2);
863 ok( ret, "LineTo error %ld.\n", GetLastError());
864 ret = MoveToEx(hdcMetafile, 1, 1, &oldpoint);
865 ok( ret, "MoveToEx error %ld.\n", GetLastError());
867 /* oldpoint gets garbage under Win XP, so the following test would
868 * work under Wine but fails under Windows:
870 * ok((oldpoint.x == 2) && (oldpoint.y == 2),
871 * "MoveToEx: (x, y) = (%ld, %ld), should be (2, 2).\n",
872 * oldpoint.x, oldpoint.y);
875 ret = Ellipse(hdcMetafile, 0, 0, 2, 2);
876 ok( ret, "Ellipse error %ld.\n", GetLastError());
878 hMetafile = CloseMetaFile(hdcMetafile);
879 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
880 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
882 if (compare_mf_bits (hMetafile, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS),
885 dump_mf_bits(hMetafile, "mf_Graphics");
886 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
889 ret = DeleteMetaFile(hMetafile);
890 ok( ret, "DeleteMetaFile(%p) error %ld\n",
891 hMetafile, GetLastError());
894 static void test_mf_PatternBrush(void)
902 orig_lb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGBRUSH));
904 orig_lb->lbStyle = BS_PATTERN;
905 orig_lb->lbColor = RGB(0, 0, 0);
906 orig_lb->lbHatch = (ULONG_PTR)CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH);
907 ok((HBITMAP)orig_lb->lbHatch != NULL, "CreateBitmap error %ld.\n", GetLastError());
909 hBrush = CreateBrushIndirect (orig_lb);
910 ok(hBrush != 0, "CreateBrushIndirect error %ld\n", GetLastError());
912 hdcMetafile = CreateMetaFileA(NULL);
913 ok(hdcMetafile != 0, "CreateMetaFileA error %ld\n", GetLastError());
914 trace("hdcMetafile %p\n", hdcMetafile);
916 hBrush = SelectObject(hdcMetafile, hBrush);
917 ok(hBrush != 0, "SelectObject error %ld.\n", GetLastError());
919 hMetafile = CloseMetaFile(hdcMetafile);
920 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
921 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
923 if (compare_mf_bits (hMetafile, MF_PATTERN_BRUSH_BITS, sizeof(MF_PATTERN_BRUSH_BITS),
924 "mf_Pattern_Brush") != 0)
926 dump_mf_bits(hMetafile, "mf_Pattern_Brush");
927 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
930 ret = DeleteMetaFile(hMetafile);
931 ok( ret, "DeleteMetaFile error %ld\n", GetLastError());
932 ret = DeleteObject(hBrush);
933 ok( ret, "DeleteObject(HBRUSH) error %ld\n", GetLastError());
934 ret = DeleteObject((HBITMAP)orig_lb->lbHatch);
935 ok( ret, "DeleteObject(HBITMAP) error %ld\n",
937 HeapFree (GetProcessHeap(), 0, orig_lb);
940 static void test_mf_ExtTextOut_on_path(void)
945 static const INT dx[4] = { 3, 5, 8, 12 };
947 hdcMetafile = CreateMetaFileA(NULL);
948 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
949 trace("hdcMetafile %p\n", hdcMetafile);
951 ret = BeginPath(hdcMetafile);
952 ok(!ret, "BeginPath on metafile DC should fail\n");
954 ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
955 ok(ret, "ExtTextOut error %ld\n", GetLastError());
957 ret = EndPath(hdcMetafile);
958 ok(!ret, "EndPath on metafile DC should fail\n");
960 hMetafile = CloseMetaFile(hdcMetafile);
961 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
963 if (compare_mf_bits(hMetafile, MF_TEXTOUT_ON_PATH_BITS, sizeof(MF_TEXTOUT_ON_PATH_BITS),
964 "mf_TextOut_on_path") != 0)
966 dump_mf_bits(hMetafile, "mf_TextOut_on_path");
967 EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
970 ret = DeleteMetaFile(hMetafile);
971 ok(ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
974 static void test_emf_ExtTextOut_on_path(void)
977 HDC hdcDisplay, hdcMetafile;
978 HENHMETAFILE hMetafile;
980 static const INT dx[4] = { 3, 5, 8, 12 };
982 /* Win9x doesn't play EMFs on invisible windows */
983 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
984 0, 0, 200, 200, 0, 0, 0, NULL);
985 ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError());
987 hdcDisplay = GetDC(hwnd);
988 ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError());
990 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
991 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError());
993 ret = BeginPath(hdcMetafile);
994 ok(ret, "BeginPath error %ld\n", GetLastError());
996 ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
997 ok(ret, "ExtTextOut error %ld\n", GetLastError());
999 ret = EndPath(hdcMetafile);
1000 ok(ret, "EndPath error %ld\n", GetLastError());
1002 hMetafile = CloseEnhMetaFile(hdcMetafile);
1003 ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError());
1005 /* this doesn't succeed yet: EMF has correct size, all EMF records
1006 * are there, but their contents don't match for different reasons.
1008 if (compare_emf_bits(hMetafile, EMF_TEXTOUT_ON_PATH_BITS, sizeof(EMF_TEXTOUT_ON_PATH_BITS),
1009 "emf_TextOut_on_path", TRUE) != 0)
1011 dump_emf_bits(hMetafile, "emf_TextOut_on_path");
1012 dump_emf_records(hMetafile, "emf_TextOut_on_path");
1015 ret = DeleteEnhMetaFile(hMetafile);
1016 ok(ret, "DeleteEnhMetaFile error %ld\n", GetLastError());
1017 ret = ReleaseDC(hwnd, hdcDisplay);
1018 ok(ret, "ReleaseDC error %ld\n", GetLastError());
1019 DestroyWindow(hwnd);
1022 static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
1024 LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData;
1025 POINT mapping[2] = { { 0, 0 }, { 10, 10 } };
1026 /* When using MM_TEXT Win9x does not update the mapping mode
1027 * until a record is played which actually outputs something */
1028 PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
1029 LPtoDP(hdc, mapping, 2);
1030 trace("Meta record: iType = %ld, (%ld,%ld)-(%ld,%ld)\n", lpEMFR->iType, mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
1031 if (lpEMFR->iType == EMR_LINETO)
1034 if (!lpMFP || lpMFP->mm == MM_TEXT)
1038 x1 = (INT)floor(10 * 100.0 / LINE_X + 0.5);
1039 y1 = (INT)floor(10 * 100.0 / LINE_Y + 0.5);
1043 ok(lpMFP->mm == MM_ANISOTROPIC, "mm=%ld\n", lpMFP->mm);
1045 x0 = MulDiv(0, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
1046 y0 = MulDiv(0, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
1047 x1 = MulDiv(10, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
1048 y1 = MulDiv(10, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
1050 ok(mapping[0].x == x0 && mapping[0].y == y0 && mapping[1].x == x1 && mapping[1].y == y1,
1051 "(%ld,%ld)->(%ld,%ld), expected (%d,%d)->(%d,%d)\n",
1052 mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y,
1058 static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
1066 hdcMf = CreateMetaFile(NULL);
1067 ok(hdcMf != NULL, "CreateMetaFile failed with error %ld\n", GetLastError());
1068 ret = LineTo(hdcMf, (INT)LINE_X, (INT)LINE_Y);
1069 ok(ret, "LineTo failed with error %ld\n", GetLastError());
1070 hmf = CloseMetaFile(hdcMf);
1071 ok(hmf != NULL, "CloseMetaFile failed with error %ld\n", GetLastError());
1072 size = GetMetaFileBitsEx(hmf, 0, NULL);
1073 ok(size, "GetMetaFileBitsEx failed with error %ld\n", GetLastError());
1074 pBits = HeapAlloc(GetProcessHeap(), 0, size);
1075 GetMetaFileBitsEx(hmf, size, pBits);
1076 DeleteMetaFile(hmf);
1077 return SetWinMetaFileBits(size, pBits, NULL, mfp);
1080 static void test_mf_conversions(void)
1082 trace("Testing MF->EMF conversion (MM_ANISOTROPIC)\n");
1084 HDC hdcOffscreen = CreateCompatibleDC(NULL);
1087 RECT rect = { 0, 0, 100, 100 };
1088 mfp.mm = MM_ANISOTROPIC;
1092 hemf = create_converted_emf(&mfp);
1093 EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
1094 DeleteEnhMetaFile(hemf);
1095 DeleteDC(hdcOffscreen);
1098 trace("Testing MF->EMF conversion (MM_TEXT)\n");
1100 HDC hdcOffscreen = CreateCompatibleDC(NULL);
1103 RECT rect = { 0, 0, 100, 100 };
1108 hemf = create_converted_emf(&mfp);
1109 EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
1110 DeleteEnhMetaFile(hemf);
1111 DeleteDC(hdcOffscreen);
1114 trace("Testing MF->EMF conversion (NULL mfp)\n");
1116 HDC hdcOffscreen = CreateCompatibleDC(NULL);
1118 RECT rect = { 0, 0, 100, 100 };
1119 hemf = create_converted_emf(NULL);
1120 EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, NULL, &rect);
1121 DeleteEnhMetaFile(hemf);
1122 DeleteDC(hdcOffscreen);
1126 static BOOL (WINAPI *pGdiIsMetaPrintDC)(HDC);
1127 static BOOL (WINAPI *pGdiIsMetaFileDC)(HDC);
1128 static BOOL (WINAPI *pGdiIsPlayMetafileDC)(HDC);
1130 static void test_gdiis(void)
1132 RECT rect = {0,0,100,100};
1133 HDC hdc, hemfDC, hmfDC;
1137 /* resolve all the functions */
1138 hgdi32 = GetModuleHandle("gdi32");
1139 pGdiIsMetaPrintDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaPrintDC");
1140 pGdiIsMetaFileDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaFileDC");
1141 pGdiIsPlayMetafileDC = (void*) GetProcAddress(hgdi32, "GdiIsPlayMetafileDC");
1143 /* they should all exist or none should exist */
1144 if(!pGdiIsMetaPrintDC)
1147 /* try with nothing */
1148 ok(!pGdiIsMetaPrintDC(NULL), "ismetaprint with NULL parameter\n");
1149 ok(!pGdiIsMetaFileDC(NULL), "ismetafile with NULL parameter\n");
1150 ok(!pGdiIsPlayMetafileDC(NULL), "isplaymetafile with NULL parameter\n");
1152 /* try with a metafile */
1153 hmfDC = CreateMetaFile(NULL);
1154 ok(!pGdiIsMetaPrintDC(hmfDC), "ismetaprint on metafile\n");
1155 ok(pGdiIsMetaFileDC(hmfDC), "ismetafile on metafile\n");
1156 ok(!pGdiIsPlayMetafileDC(hmfDC), "isplaymetafile on metafile\n");
1157 DeleteObject(CloseMetaFile(hmfDC));
1159 /* try with an enhanced metafile */
1161 hemfDC = CreateEnhMetaFileW(hdc, NULL, &rect, NULL);
1162 ok(hemfDC != NULL, "failed to create emf\n");
1164 ok(!pGdiIsMetaPrintDC(hemfDC), "ismetaprint on emf\n");
1165 ok(pGdiIsMetaFileDC(hemfDC), "ismetafile on emf\n");
1166 ok(!pGdiIsPlayMetafileDC(hemfDC), "isplaymetafile on emf\n");
1168 hemf = CloseEnhMetaFile(hemfDC);
1169 ok(hemf != NULL, "failed to close EMF\n");
1171 ReleaseDC(NULL,hdc);
1174 START_TEST(metafile)
1176 init_function_pointers();
1178 /* For enhanced metafiles (enhmfdrv) */
1182 /* For win-format metafiles (mfdrv) */
1185 test_mf_PatternBrush();
1186 test_CopyMetaFile();
1187 test_SetMetaFileBits();
1188 test_mf_ExtTextOut_on_path();
1189 test_emf_ExtTextOut_on_path();
1191 /* For metafile conversions */
1192 test_mf_conversions();