rename tests to dllname_winetest to make it less trouble on exception to change build...
[reactos.git] / reactos / regtests / winetests / gdi32 / 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 char *bits, UINT bsize,
299 const char *desc)
300 {
301 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 }