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 CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
39 const ENHMETARECORD *emr, int n_objs, LPARAM param)
44 INT *orig_dx = (INT *)param;
48 trace("hdc %p, emr->iType %ld, emr->nSize %ld, param %p\n",
49 hdc, emr->iType, emr->nSize, (void *)param);
53 PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
58 ok(GetTextAlign(hdc) == 0, "text align %08x\n", GetTextAlign(hdc));
59 ok(GetBkColor(hdc) == RGB(0xff, 0xff, 0xff), "bk color %08lx\n", GetBkColor(hdc));
60 ok(GetTextColor(hdc) == RGB(0x0, 0x0, 0x0), "text color %08lx\n", GetTextColor(hdc));
61 ok(GetROP2(hdc) == R2_COPYPEN, "rop %d\n", GetROP2(hdc));
62 ok(GetArcDirection(hdc) == AD_COUNTERCLOCKWISE, "arc dir %d\n", GetArcDirection(hdc));
63 ok(GetPolyFillMode(hdc) == ALTERNATE, "poly fill %d\n", GetPolyFillMode(hdc));
64 ok(GetStretchBltMode(hdc) == BLACKONWHITE, "stretchblt mode %d\n", GetStretchBltMode(hdc));
66 /* GetBkMode, GetRelAbs do not get reset to the default value */
67 ok(GetBkMode(hdc) == OPAQUE, "bk mode %d\n", GetBkMode(hdc));
68 ok(GetRelAbs(hdc, 0) == RELATIVE, "relabs %d\n", GetRelAbs(hdc, 0));
75 const EMREXTTEXTOUTA *emr_ExtTextOutA = (const EMREXTTEXTOUTA *)emr;
76 dx = (const INT *)((const char *)emr + emr_ExtTextOutA->emrtext.offDx);
78 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
79 ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
81 /* compare up to lfOutPrecision, other values are not interesting,
82 * and in fact sometimes arbitrary adapted by Win9x.
84 ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
85 ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
87 for(i = 0; i < emr_ExtTextOutA->emrtext.nChars; i++)
89 ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
90 n_record, i, dx[i], orig_dx[i]);
99 const EMREXTTEXTOUTW *emr_ExtTextOutW = (const EMREXTTEXTOUTW *)emr;
100 dx = (const INT *)((const char *)emr + emr_ExtTextOutW->emrtext.offDx);
102 ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
103 ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
105 /* compare up to lfOutPrecision, other values are not interesting,
106 * and in fact sometimes arbitrary adapted by Win9x.
108 ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
109 ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
111 for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++)
113 ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
114 n_record, i, dx[i], orig_dx[i]);
117 emr_processed = TRUE;
128 static void test_ExtTextOut(void)
131 HDC hdcDisplay, hdcMetafile;
132 HENHMETAFILE hMetafile;
134 static const char text[] = "Simple text to test ExtTextOut on metafiles";
136 static const RECT rc = { 0, 0, 100, 100 };
139 assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
141 /* Win9x doesn't play EMFs on invisible windows */
142 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
143 0, 0, 200, 200, 0, 0, 0, NULL);
144 ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError());
146 hdcDisplay = GetDC(hwnd);
147 ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError());
149 trace("hdcDisplay %p\n", hdcDisplay);
151 SetMapMode(hdcDisplay, MM_TEXT);
153 memset(&orig_lf, 0, sizeof(orig_lf));
155 orig_lf.lfCharSet = ANSI_CHARSET;
156 orig_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
157 orig_lf.lfWeight = FW_DONTCARE;
158 orig_lf.lfHeight = 7;
159 orig_lf.lfQuality = DEFAULT_QUALITY;
160 lstrcpyA(orig_lf.lfFaceName, "Arial");
161 hFont = CreateFontIndirectA(&orig_lf);
162 ok(hFont != 0, "CreateFontIndirectA error %ld\n", GetLastError());
164 hFont = SelectObject(hdcDisplay, hFont);
166 len = lstrlenA(text);
167 for (i = 0; i < len; i++)
169 ret = GetCharWidthA(hdcDisplay, text[i], text[i], &dx[i]);
170 ok( ret, "GetCharWidthA error %ld\n", GetLastError());
172 hFont = SelectObject(hdcDisplay, hFont);
174 hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
175 ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError());
177 trace("hdcMetafile %p\n", hdcMetafile);
179 ok(GetDeviceCaps(hdcMetafile, TECHNOLOGY) == DT_RASDISPLAY,
180 "GetDeviceCaps(TECHNOLOGY) has to return DT_RASDISPLAY for a display based EMF\n");
182 hFont = SelectObject(hdcMetafile, hFont);
184 /* 1. pass NULL lpDx */
185 ret = ExtTextOutA(hdcMetafile, 0, 0, 0, &rc, text, lstrlenA(text), NULL);
186 ok( ret, "ExtTextOutA error %ld\n", GetLastError());
188 /* 2. pass custom lpDx */
189 ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
190 ok( ret, "ExtTextOutA error %ld\n", GetLastError());
192 hFont = SelectObject(hdcMetafile, hFont);
193 ret = DeleteObject(hFont);
194 ok( ret, "DeleteObject error %ld\n", GetLastError());
196 hMetafile = CloseEnhMetaFile(hdcMetafile);
197 ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError());
199 ok(!GetObjectType(hdcMetafile), "CloseEnhMetaFile has to destroy metafile hdc\n");
201 ret = PlayEnhMetaFile(hdcDisplay, hMetafile, &rc);
202 ok( ret, "PlayEnhMetaFile error %ld\n", GetLastError());
204 SetTextAlign(hdcDisplay, TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING );
205 SetBkColor(hdcDisplay, RGB(0xff, 0, 0));
206 SetTextColor(hdcDisplay, RGB(0, 0xff, 0));
207 SetROP2(hdcDisplay, R2_NOT);
208 SetArcDirection(hdcDisplay, AD_CLOCKWISE);
209 SetPolyFillMode(hdcDisplay, WINDING);
210 SetStretchBltMode(hdcDisplay, HALFTONE);
212 SetRelAbs(hdcDisplay, RELATIVE);
213 SetBkMode(hdcDisplay, OPAQUE);
215 ret = EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, &rc);
216 ok( ret, "EnumEnhMetaFile error %ld\n", GetLastError());
218 ok( GetTextAlign(hdcDisplay) == (TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING),
219 "text align %08x\n", GetTextAlign(hdcDisplay));
220 ok( GetBkColor(hdcDisplay) == RGB(0xff, 0, 0), "bk color %08lx\n", GetBkColor(hdcDisplay));
221 ok( GetTextColor(hdcDisplay) == RGB(0, 0xff, 0), "text color %08lx\n", GetTextColor(hdcDisplay));
222 ok( GetROP2(hdcDisplay) == R2_NOT, "rop2 %d\n", GetROP2(hdcDisplay));
223 ok( GetArcDirection(hdcDisplay) == AD_CLOCKWISE, "arc dir %d\n", GetArcDirection(hdcDisplay));
224 ok( GetPolyFillMode(hdcDisplay) == WINDING, "poly fill %d\n", GetPolyFillMode(hdcDisplay));
225 ok( GetStretchBltMode(hdcDisplay) == HALFTONE, "stretchblt mode %d\n", GetStretchBltMode(hdcDisplay));
227 ok(emr_processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record\n");
229 ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, NULL),
230 "A valid hdc has to require a valid rc\n");
232 ok(EnumEnhMetaFile(NULL, hMetafile, emf_enum_proc, dx, NULL),
233 "A null hdc does not require a valid rc\n");
235 ret = DeleteEnhMetaFile(hMetafile);
236 ok( ret, "DeleteEnhMetaFile error %ld\n", GetLastError());
237 ret = ReleaseDC(hwnd, hdcDisplay);
238 ok( ret, "ReleaseDC error %ld\n", GetLastError());
241 /* Win-format metafile (mfdrv) tests */
242 /* These tests compare the generated metafiles byte-by-byte */
243 /* with the nominal results. */
245 /* Maximum size of sample metafiles in bytes. */
246 #define MF_BUFSIZE 256
248 /* 8x8 bitmap data for a pattern brush */
249 static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
250 0x01, 0x00, 0x02, 0x00,
251 0x03, 0x00, 0x04, 0x00,
252 0x05, 0x00, 0x06, 0x00,
253 0x07, 0x00, 0x08, 0x00
256 /* Sample metafiles to be compared to the outputs of the
260 static const unsigned char MF_BLANK_BITS[] = {
261 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x0c, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
266 static const unsigned char MF_GRAPHICS_BITS[] = {
267 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x22, 0x00,
268 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
270 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
271 0x13, 0x02, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00,
272 0x00, 0x00, 0x14, 0x02, 0x01, 0x00, 0x01, 0x00,
273 0x07, 0x00, 0x00, 0x00, 0x18, 0x04, 0x02, 0x00,
274 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
275 0x00, 0x00, 0x00, 0x00
278 static const unsigned char MF_PATTERN_BRUSH_BITS[] = {
279 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x3d, 0x00,
280 0x00, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x42, 0x01,
282 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
283 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
284 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00,
289 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
290 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
291 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
292 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
293 0x2d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
297 /* For debugging or dumping the raw metafiles produced by
298 * new test functions.
301 static void dump_mf_bits (const HMETAFILE mf, const char *desc)
303 char buf[MF_BUFSIZE];
306 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
307 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
309 printf ("MetaFile %s has bits:\n{\n ", desc);
310 for (i=0; i<mfsize; i++)
312 printf ("0x%.2hhx", buf[i]);
323 /* Compare the metafile produced by a test function with the
324 * expected raw metafile data in "bits".
325 * Return value is 0 for a perfect match,
326 * -1 if lengths aren't equal,
327 * otherwise returns the number of non-matching bytes.
330 static int compare_mf_bits (const HMETAFILE mf, const unsigned char *bits, UINT bsize,
333 unsigned char buf[MF_BUFSIZE];
337 mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
338 ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
339 if (mfsize < MF_BUFSIZE)
340 ok (mfsize == bsize, "%s: mfsize=%d, bsize=%d.\n",
341 desc, mfsize, bsize);
343 ok (bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d.\n",
344 desc, mfsize, bsize);
349 for (i=0; i<bsize; i++)
351 if (buf[i] != bits[i])
354 ok (diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
355 desc, mfsize, bsize, diff);
360 static int compare_mf_disk_bits(LPCSTR name, const BYTE *bits, UINT bsize, const char *desc)
362 unsigned char buf[MF_BUFSIZE];
363 DWORD mfsize, rd_size, i;
368 hfile = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
369 assert(hfile != INVALID_HANDLE_VALUE);
371 mfsize = GetFileSize(hfile, NULL);
372 assert(mfsize <= MF_BUFSIZE);
374 ret = ReadFile(hfile, buf, sizeof(buf), &rd_size, NULL);
375 ok( ret && rd_size == mfsize, "ReadFile: error %ld\n", GetLastError());
379 ok(mfsize == bsize, "%s: mfsize=%ld, bsize=%d.\n", desc, mfsize, bsize);
385 for (i=0; i<bsize; i++)
387 if (buf[i] != bits[i])
390 ok(diff == 0, "%s: mfsize=%ld, bsize=%d, diff=%d\n",
391 desc, mfsize, bsize, diff);
396 /* Test a blank metafile. May be used as a template for new tests. */
398 static void test_mf_Blank(void)
406 hdcMetafile = CreateMetaFileA(NULL);
407 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
408 trace("hdcMetafile %p\n", hdcMetafile);
410 /* Tests on metafile initialization */
411 caps = GetDeviceCaps (hdcMetafile, TECHNOLOGY);
412 ok (caps == DT_METAFILE,
413 "GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE.\n", caps);
415 hMetafile = CloseMetaFile(hdcMetafile);
416 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
417 type = GetObjectType(hMetafile);
418 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
419 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
421 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
423 dump_mf_bits (hMetafile, "mf_Blank");
425 ret = DeleteMetaFile(hMetafile);
426 ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
429 static void test_CopyMetaFile(void)
432 HMETAFILE hMetafile, hmf_copy;
434 char temp_path[MAX_PATH];
435 char mf_name[MAX_PATH];
438 hdcMetafile = CreateMetaFileA(NULL);
439 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
440 trace("hdcMetafile %p\n", hdcMetafile);
442 hMetafile = CloseMetaFile(hdcMetafile);
443 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
444 type = GetObjectType(hMetafile);
445 ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
447 if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
449 dump_mf_bits (hMetafile, "mf_Blank");
451 GetTempPathA(MAX_PATH, temp_path);
452 GetTempFileNameA(temp_path, "wmf", 0, mf_name);
454 hmf_copy = CopyMetaFileA(hMetafile, mf_name);
455 ok(hmf_copy != 0, "CopyMetaFile error %ld\n", GetLastError());
457 type = GetObjectType(hmf_copy);
458 ok(type == OBJ_METAFILE, "CopyMetaFile created object with type %d\n", type);
460 ret = DeleteMetaFile(hMetafile);
461 ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
463 if (compare_mf_disk_bits(mf_name, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0)
464 dump_mf_bits(hmf_copy, "mf_Blank");
466 ret = DeleteMetaFile(hmf_copy);
467 ok( ret, "DeleteMetaFile(%p) error %ld\n", hmf_copy, GetLastError());
469 DeleteFileA(mf_name);
472 static void test_SetMetaFileBits(void)
480 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), MF_GRAPHICS_BITS);
481 ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
482 type = GetObjectType(hmf);
483 ok(type == OBJ_METAFILE, "SetMetaFileBitsEx created object with type %d\n", type);
485 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
486 dump_mf_bits(hmf, "mf_Graphics");
488 ret = DeleteMetaFile(hmf);
489 ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
491 /* NULL data crashes XP SP1 */
492 /*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/
494 /* Now with not zero size */
495 SetLastError(0xdeadbeef);
496 hmf = SetMetaFileBitsEx(0, MF_GRAPHICS_BITS);
497 ok(!hmf, "SetMetaFileBitsEx should fail\n");
498 ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError());
500 /* Now with not even size */
501 SetLastError(0xdeadbeef);
502 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS) - 1, MF_GRAPHICS_BITS);
503 ok(!hmf, "SetMetaFileBitsEx should fail\n");
504 ok(GetLastError() == 0xdeadbeef /* XP SP1 */, "wrong error %ld\n", GetLastError());
506 /* Now with zeroed out or faked some header fields */
507 assert(sizeof(buf) >= sizeof(MF_GRAPHICS_BITS));
508 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
509 mh = (METAHEADER *)buf;
510 /* corruption of any of the below fields leads to a failure */
513 mh->mtHeaderSize = 0;
514 SetLastError(0xdeadbeef);
515 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
516 ok(!hmf, "SetMetaFileBitsEx should fail\n");
517 ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError());
519 /* Now with corrupted mtSize field */
520 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
521 mh = (METAHEADER *)buf;
522 /* corruption of mtSize doesn't lead to a failure */
524 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
525 ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
527 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
528 dump_mf_bits(hmf, "mf_Graphics");
530 ret = DeleteMetaFile(hmf);
531 ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
533 /* Now with zeroed out mtSize field */
534 memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
535 mh = (METAHEADER *)buf;
536 /* zeroing mtSize doesn't lead to a failure */
538 hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
539 ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
541 if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
542 dump_mf_bits(hmf, "mf_Graphics");
544 ret = DeleteMetaFile(hmf);
545 ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
548 /* Simple APIs from mfdrv/graphics.c
551 static void test_mf_Graphics(void)
558 hdcMetafile = CreateMetaFileA(NULL);
559 ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
560 trace("hdcMetafile %p\n", hdcMetafile);
562 ret = MoveToEx(hdcMetafile, 1, 1, NULL);
563 ok( ret, "MoveToEx error %ld.\n", GetLastError());
564 ret = LineTo(hdcMetafile, 2, 2);
565 ok( ret, "LineTo error %ld.\n", GetLastError());
566 ret = MoveToEx(hdcMetafile, 1, 1, &oldpoint);
567 ok( ret, "MoveToEx error %ld.\n", GetLastError());
569 /* oldpoint gets garbage under Win XP, so the following test would
570 * work under Wine but fails under Windows:
572 * ok((oldpoint.x == 2) && (oldpoint.y == 2),
573 * "MoveToEx: (x, y) = (%ld, %ld), should be (2, 2).\n",
574 * oldpoint.x, oldpoint.y);
577 ret = Ellipse(hdcMetafile, 0, 0, 2, 2);
578 ok( ret, "Ellipse error %ld.\n", GetLastError());
580 hMetafile = CloseMetaFile(hdcMetafile);
581 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
582 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
584 if (compare_mf_bits (hMetafile, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS),
586 dump_mf_bits (hMetafile, "mf_Graphics");
588 ret = DeleteMetaFile(hMetafile);
589 ok( ret, "DeleteMetaFile(%p) error %ld\n",
590 hMetafile, GetLastError());
593 static void test_mf_PatternBrush(void)
601 orig_lb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGBRUSH));
603 orig_lb->lbStyle = BS_PATTERN;
604 orig_lb->lbColor = RGB(0, 0, 0);
605 orig_lb->lbHatch = (ULONG_PTR)CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH);
606 ok((HBITMAP)orig_lb->lbHatch != NULL, "CreateBitmap error %ld.\n", GetLastError());
608 hBrush = CreateBrushIndirect (orig_lb);
609 ok(hBrush != 0, "CreateBrushIndirect error %ld\n", GetLastError());
611 hdcMetafile = CreateMetaFileA(NULL);
612 ok(hdcMetafile != 0, "CreateMetaFileA error %ld\n", GetLastError());
613 trace("hdcMetafile %p\n", hdcMetafile);
615 hBrush = SelectObject(hdcMetafile, hBrush);
616 ok(hBrush != 0, "SelectObject error %ld.\n", GetLastError());
618 hMetafile = CloseMetaFile(hdcMetafile);
619 ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
620 ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
622 if (compare_mf_bits (hMetafile, MF_PATTERN_BRUSH_BITS, sizeof(MF_PATTERN_BRUSH_BITS),
623 "mf_Pattern_Brush") != 0)
624 dump_mf_bits (hMetafile, "mf_Pattern_Brush");
626 ret = DeleteMetaFile(hMetafile);
627 ok( ret, "DeleteMetaFile error %ld\n", GetLastError());
628 ret = DeleteObject(hBrush);
629 ok( ret, "DeleteObject(HBRUSH) error %ld\n", GetLastError());
630 ret = DeleteObject((HBITMAP)orig_lb->lbHatch);
631 ok( ret, "DeleteObject(HBITMAP) error %ld\n",
633 HeapFree (GetProcessHeap(), 0, orig_lb);
636 static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
638 LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData;
639 POINT mapping[2] = { { 0, 0 }, { 10, 10 } };
640 /* When using MM_TEXT Win9x does not update the mapping mode
641 * until a record is played which actually outputs something */
642 PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
643 LPtoDP(hdc, mapping, 2);
644 trace("Meta record: iType = %ld, (%ld,%ld)-(%ld,%ld)\n", lpEMFR->iType, mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
645 if (lpEMFR->iType == EMR_LINETO)
648 if (!lpMFP || lpMFP->mm == MM_TEXT)
652 x1 = (INT)floor(10 * 100.0 / LINE_X + 0.5);
653 y1 = (INT)floor(10 * 100.0 / LINE_Y + 0.5);
657 ok(lpMFP->mm == MM_ANISOTROPIC, "mm=%ld\n", lpMFP->mm);
659 x0 = MulDiv(0, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
660 y0 = MulDiv(0, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
661 x1 = MulDiv(10, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
662 y1 = MulDiv(10, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
664 ok(mapping[0].x == x0 && mapping[0].y == y0 && mapping[1].x == x1 && mapping[1].y == y1,
665 "(%ld,%ld)->(%ld,%ld), expected (%d,%d)->(%d,%d)\n",
666 mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y,
672 static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
680 hdcMf = CreateMetaFile(NULL);
681 ok(hdcMf != NULL, "CreateMetaFile failed with error %ld\n", GetLastError());
682 ret = LineTo(hdcMf, (INT)LINE_X, (INT)LINE_Y);
683 ok(ret, "LineTo failed with error %ld\n", GetLastError());
684 hmf = CloseMetaFile(hdcMf);
685 ok(hmf != NULL, "CloseMetaFile failed with error %ld\n", GetLastError());
686 size = GetMetaFileBitsEx(hmf, 0, NULL);
687 ok(size, "GetMetaFileBitsEx failed with error %ld\n", GetLastError());
688 pBits = HeapAlloc(GetProcessHeap(), 0, size);
689 GetMetaFileBitsEx(hmf, size, pBits);
691 return SetWinMetaFileBits(size, pBits, NULL, mfp);
694 static void test_mf_conversions(void)
696 trace("Testing MF->EMF conversion (MM_ANISOTROPIC)\n");
698 HDC hdcOffscreen = CreateCompatibleDC(NULL);
701 RECT rect = { 0, 0, 100, 100 };
702 mfp.mm = MM_ANISOTROPIC;
706 hemf = create_converted_emf(&mfp);
707 EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
708 DeleteEnhMetaFile(hemf);
709 DeleteDC(hdcOffscreen);
712 trace("Testing MF->EMF conversion (MM_TEXT)\n");
714 HDC hdcOffscreen = CreateCompatibleDC(NULL);
717 RECT rect = { 0, 0, 100, 100 };
722 hemf = create_converted_emf(&mfp);
723 EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, &mfp, &rect);
724 DeleteEnhMetaFile(hemf);
725 DeleteDC(hdcOffscreen);
728 trace("Testing MF->EMF conversion (NULL mfp)\n");
730 HDC hdcOffscreen = CreateCompatibleDC(NULL);
732 RECT rect = { 0, 0, 100, 100 };
733 hemf = create_converted_emf(NULL);
734 EnumEnhMetaFile(hdcOffscreen, hemf, EmfEnumProc, NULL, &rect);
735 DeleteEnhMetaFile(hemf);
736 DeleteDC(hdcOffscreen);
740 static BOOL (WINAPI *pGdiIsMetaPrintDC)(HDC);
741 static BOOL (WINAPI *pGdiIsMetaFileDC)(HDC);
742 static BOOL (WINAPI *pGdiIsPlayMetafileDC)(HDC);
744 static void test_gdiis(void)
746 RECT rect = {0,0,100,100};
747 HDC hdc, hemfDC, hmfDC;
751 /* resolve all the functions */
752 hgdi32 = GetModuleHandle("gdi32");
753 pGdiIsMetaPrintDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaPrintDC");
754 pGdiIsMetaFileDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaFileDC");
755 pGdiIsPlayMetafileDC = (void*) GetProcAddress(hgdi32, "GdiIsPlayMetafileDC");
757 /* they should all exist or none should exist */
758 if(!pGdiIsMetaPrintDC)
761 /* try with nothing */
762 ok(!pGdiIsMetaPrintDC(NULL), "ismetaprint with NULL parameter\n");
763 ok(!pGdiIsMetaFileDC(NULL), "ismetafile with NULL parameter\n");
764 ok(!pGdiIsPlayMetafileDC(NULL), "isplaymetafile with NULL parameter\n");
766 /* try with a metafile */
767 hmfDC = CreateMetaFile(NULL);
768 ok(!pGdiIsMetaPrintDC(hmfDC), "ismetaprint on metafile\n");
769 ok(pGdiIsMetaFileDC(hmfDC), "ismetafile on metafile\n");
770 ok(!pGdiIsPlayMetafileDC(hmfDC), "isplaymetafile on metafile\n");
771 DeleteObject(CloseMetaFile(hmfDC));
773 /* try with an enhanced metafile */
775 hemfDC = CreateEnhMetaFileW(hdc, NULL, &rect, NULL);
776 ok(hemfDC != NULL, "failed to create emf\n");
778 ok(!pGdiIsMetaPrintDC(hemfDC), "ismetaprint on emf\n");
779 ok(pGdiIsMetaFileDC(hemfDC), "ismetafile on emf\n");
780 ok(!pGdiIsPlayMetafileDC(hemfDC), "isplaymetafile on emf\n");
782 hemf = CloseEnhMetaFile(hemfDC);
783 ok(hemf != NULL, "failed to close EMF\n");
790 /* For enhanced metafiles (enhmfdrv) */
793 /* For win-format metafiles (mfdrv) */
796 test_mf_PatternBrush();
798 test_SetMetaFileBits();
800 /* For metafile conversions */
801 test_mf_conversions();