gdiplus: Add option to save metafile tests to files.
[wine.git] / dlls / gdiplus / tests / metafile.c
blobf9a50926582913d4d4935746e84fbb0e60901b53
1 /*
2 * Unit test suite for metafiles
4 * Copyright (C) 2011 Vincent Povirk for CodeWeavers
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <math.h>
23 #include "objbase.h"
24 #include "gdiplus.h"
25 #include "wine/test.h"
27 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
28 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
30 static BOOL save_metafiles;
32 typedef struct emfplus_record
34 BOOL todo;
35 ULONG record_type;
36 BOOL playback_todo;
37 } emfplus_record;
39 typedef struct emfplus_check_state
41 const char *desc;
42 int count;
43 const struct emfplus_record *expected;
44 GpMetafile *metafile;
45 } emfplus_check_state;
47 static void check_record(int count, const char *desc, const struct emfplus_record *expected, const struct emfplus_record *actual)
49 if (expected->todo)
50 todo_wine ok(expected->record_type == actual->record_type,
51 "%s.%i: Expected record type 0x%x, got 0x%x\n", desc, count,
52 expected->record_type, actual->record_type);
53 else
54 ok(expected->record_type == actual->record_type,
55 "%s.%i: Expected record type 0x%x, got 0x%x\n", desc, count,
56 expected->record_type, actual->record_type);
59 typedef struct EmfPlusRecordHeader
61 WORD Type;
62 WORD Flags;
63 DWORD Size;
64 DWORD DataSize;
65 } EmfPlusRecordHeader;
67 static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
68 int nObj, LPARAM lpData)
70 emfplus_check_state *state = (emfplus_check_state*)lpData;
71 emfplus_record actual;
73 if (lpEMFR->iType == EMR_GDICOMMENT)
75 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
77 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
79 int offset = 4;
81 while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
83 const EmfPlusRecordHeader *record = (const EmfPlusRecordHeader*)&comment->Data[offset];
85 ok(record->Size == record->DataSize + sizeof(EmfPlusRecordHeader),
86 "%s: EMF+ record datasize %u and size %u mismatch\n", state->desc, record->DataSize, record->Size);
88 ok(offset + record->DataSize <= comment->cbData,
89 "%s: EMF+ record truncated\n", state->desc);
91 if (offset + record->DataSize > comment->cbData)
92 return 0;
94 if (state->expected[state->count].record_type)
96 actual.todo = FALSE;
97 actual.record_type = record->Type;
99 check_record(state->count, state->desc, &state->expected[state->count], &actual);
101 state->count++;
103 else
105 ok(0, "%s: Unexpected EMF+ 0x%x record\n", state->desc, record->Type);
108 offset += record->Size;
111 ok(offset == comment->cbData, "%s: truncated EMF+ record data?\n", state->desc);
113 return 1;
117 if (state->expected[state->count].record_type)
119 actual.todo = FALSE;
120 actual.record_type = lpEMFR->iType;
122 check_record(state->count, state->desc, &state->expected[state->count], &actual);
124 state->count++;
126 else
128 ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, lpEMFR->iType);
131 return 1;
134 static void check_emfplus(HENHMETAFILE hemf, const emfplus_record *expected, const char *desc)
136 emfplus_check_state state;
138 state.desc = desc;
139 state.count = 0;
140 state.expected = expected;
142 EnumEnhMetaFile(0, hemf, enum_emf_proc, &state, NULL);
144 if (expected[state.count].todo)
145 todo_wine ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
146 else
147 ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
150 static BOOL CALLBACK enum_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
151 unsigned int dataSize, const unsigned char *pStr, void *userdata)
153 emfplus_check_state *state = (emfplus_check_state*)userdata;
154 emfplus_record actual;
156 actual.todo = FALSE;
157 actual.record_type = record_type;
159 if (dataSize == 0)
160 ok(pStr == NULL, "non-NULL pStr\n");
162 if (state->expected[state->count].record_type)
164 check_record(state->count, state->desc, &state->expected[state->count], &actual);
166 state->count++;
168 else
170 ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, record_type);
173 return TRUE;
176 static void check_metafile(GpMetafile *metafile, const emfplus_record *expected, const char *desc,
177 const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
179 GpStatus stat;
180 HDC hdc;
181 GpGraphics *graphics;
182 emfplus_check_state state;
184 state.desc = desc;
185 state.count = 0;
186 state.expected = expected;
187 state.metafile = metafile;
189 hdc = CreateCompatibleDC(0);
191 stat = GdipCreateFromHDC(hdc, &graphics);
192 expect(Ok, stat);
194 stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
195 3, src_rect, src_unit, enum_metafile_proc, &state, NULL);
196 expect(Ok, stat);
198 if (expected[state.count].todo)
199 todo_wine ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
200 else
201 ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
203 GdipDeleteGraphics(graphics);
205 DeleteDC(hdc);
208 static BOOL CALLBACK play_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
209 unsigned int dataSize, const unsigned char *pStr, void *userdata)
211 emfplus_check_state *state = (emfplus_check_state*)userdata;
212 GpStatus stat;
214 stat = GdipPlayMetafileRecord(state->metafile, record_type, flags, dataSize, pStr);
216 if (state->expected[state->count].record_type)
218 if (state->expected[state->count].playback_todo)
219 todo_wine ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat);
220 else
221 ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat);
222 state->count++;
224 else
226 if (state->expected[state->count].playback_todo)
227 todo_wine ok(0, "%s: too many records\n", state->desc);
228 else
229 ok(0, "%s: too many records\n", state->desc);
231 return FALSE;
234 return TRUE;
237 static void play_metafile(GpMetafile *metafile, GpGraphics *graphics, const emfplus_record *expected,
238 const char *desc, const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
240 GpStatus stat;
241 emfplus_check_state state;
243 state.desc = desc;
244 state.count = 0;
245 state.expected = expected;
246 state.metafile = metafile;
248 stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
249 3, src_rect, src_unit, play_metafile_proc, &state, NULL);
250 expect(Ok, stat);
253 static void save_metafile(GpMetafile *metafile, const char *filename)
255 if (save_metafiles)
257 GpMetafile *clone;
258 HENHMETAFILE hemf;
259 GpStatus stat;
261 stat = GdipCloneImage((GpImage*)metafile, (GpImage**)&clone);
262 expect(Ok, stat);
264 stat = GdipGetHemfFromMetafile(clone, &hemf);
265 expect(Ok, stat);
267 DeleteEnhMetaFile(CopyEnhMetaFileA(hemf, filename));
269 DeleteEnhMetaFile(hemf);
271 stat = GdipDisposeImage((GpImage*)clone);
272 expect(Ok, stat);
276 static const emfplus_record empty_records[] = {
277 {0, EMR_HEADER},
278 {0, EmfPlusRecordTypeHeader},
279 {0, EmfPlusRecordTypeEndOfFile},
280 {0, EMR_EOF},
284 static void test_empty(void)
286 GpStatus stat;
287 GpMetafile *metafile;
288 GpGraphics *graphics;
289 HDC hdc;
290 HENHMETAFILE hemf, dummy;
291 BOOL ret;
292 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
293 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
294 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
296 hdc = CreateCompatibleDC(0);
298 stat = GdipRecordMetafile(NULL, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
299 expect(InvalidParameter, stat);
301 stat = GdipRecordMetafile(hdc, MetafileTypeInvalid, &frame, MetafileFrameUnitPixel, description, &metafile);
302 expect(InvalidParameter, stat);
304 stat = GdipRecordMetafile(hdc, MetafileTypeWmf, &frame, MetafileFrameUnitPixel, description, &metafile);
305 expect(InvalidParameter, stat);
307 stat = GdipRecordMetafile(hdc, MetafileTypeWmfPlaceable, &frame, MetafileFrameUnitPixel, description, &metafile);
308 expect(InvalidParameter, stat);
310 stat = GdipRecordMetafile(hdc, MetafileTypeEmfPlusDual+1, &frame, MetafileFrameUnitPixel, description, &metafile);
311 expect(InvalidParameter, stat);
313 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, NULL);
314 expect(InvalidParameter, stat);
316 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
317 expect(Ok, stat);
319 DeleteDC(hdc);
321 if (stat != Ok)
322 return;
324 stat = GdipGetHemfFromMetafile(metafile, &hemf);
325 expect(InvalidParameter, stat);
327 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
328 expect(Ok, stat);
330 stat = GdipGetHemfFromMetafile(metafile, &hemf);
331 expect(InvalidParameter, stat);
333 stat = GdipDeleteGraphics(graphics);
334 expect(Ok, stat);
336 check_metafile(metafile, empty_records, "empty metafile", dst_points, &frame, UnitPixel);
338 save_metafile(metafile, "empty.emf");
340 stat = GdipGetHemfFromMetafile(metafile, &hemf);
341 expect(Ok, stat);
343 stat = GdipGetHemfFromMetafile(metafile, &dummy);
344 expect(InvalidParameter, stat);
346 stat = GdipDisposeImage((GpImage*)metafile);
347 expect(Ok, stat);
349 check_emfplus(hemf, empty_records, "empty emf");
351 ret = DeleteEnhMetaFile(hemf);
352 ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
355 static const emfplus_record getdc_records[] = {
356 {0, EMR_HEADER},
357 {0, EmfPlusRecordTypeHeader},
358 {0, EmfPlusRecordTypeGetDC},
359 {0, EMR_CREATEBRUSHINDIRECT},
360 {0, EMR_SELECTOBJECT},
361 {0, EMR_RECTANGLE},
362 {0, EMR_SELECTOBJECT},
363 {0, EMR_DELETEOBJECT},
364 {0, EmfPlusRecordTypeEndOfFile},
365 {0, EMR_EOF},
369 static void test_getdc(void)
371 GpStatus stat;
372 GpMetafile *metafile;
373 GpGraphics *graphics;
374 HDC hdc, metafile_dc;
375 HENHMETAFILE hemf;
376 BOOL ret;
377 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
378 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
379 static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
380 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
381 HBRUSH hbrush, holdbrush;
382 GpBitmap *bitmap;
383 ARGB color;
385 hdc = CreateCompatibleDC(0);
387 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
388 expect(Ok, stat);
390 DeleteDC(hdc);
392 if (stat != Ok)
393 return;
395 stat = GdipGetHemfFromMetafile(metafile, &hemf);
396 expect(InvalidParameter, stat);
398 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
399 expect(Ok, stat);
401 stat = GdipGetDC(graphics, &metafile_dc);
402 expect(Ok, stat);
404 if (stat != Ok)
406 GdipDeleteGraphics(graphics);
407 GdipDisposeImage((GpImage*)metafile);
408 return;
411 hbrush = CreateSolidBrush(0xff0000);
413 holdbrush = SelectObject(metafile_dc, hbrush);
415 Rectangle(metafile_dc, 25, 25, 75, 75);
417 SelectObject(metafile_dc, holdbrush);
419 DeleteObject(hbrush);
421 stat = GdipReleaseDC(graphics, metafile_dc);
422 expect(Ok, stat);
424 stat = GdipDeleteGraphics(graphics);
425 expect(Ok, stat);
427 check_metafile(metafile, getdc_records, "getdc metafile", dst_points, &frame, UnitPixel);
429 save_metafile(metafile, "getdc.emf");
431 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
432 expect(Ok, stat);
434 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
435 expect(Ok, stat);
437 play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points, &frame, UnitPixel);
439 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
440 expect(Ok, stat);
441 expect(0, color);
443 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
444 expect(Ok, stat);
445 expect(0xff0000ff, color);
447 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
448 expect(Ok, stat);
450 play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points_half, &frame, UnitPixel);
452 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
453 expect(Ok, stat);
454 expect(0xff0000ff, color);
456 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
457 expect(Ok, stat);
458 expect(0, color);
460 stat = GdipBitmapSetPixel(bitmap, 15, 15, 0);
461 expect(Ok, stat);
463 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
464 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
465 expect(Ok, stat);
467 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
468 expect(Ok, stat);
469 expect(0, color);
471 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
472 expect(Ok, stat);
473 expect(0xff0000ff, color);
475 stat = GdipDeleteGraphics(graphics);
476 expect(Ok, stat);
478 stat = GdipDisposeImage((GpImage*)bitmap);
479 expect(Ok, stat);
481 stat = GdipGetHemfFromMetafile(metafile, &hemf);
482 expect(Ok, stat);
484 stat = GdipDisposeImage((GpImage*)metafile);
485 expect(Ok, stat);
487 check_emfplus(hemf, getdc_records, "getdc emf");
489 ret = DeleteEnhMetaFile(hemf);
490 ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
493 static const emfplus_record emfonly_records[] = {
494 {0, EMR_HEADER},
495 {0, EMR_CREATEBRUSHINDIRECT},
496 {0, EMR_SELECTOBJECT},
497 {0, EMR_RECTANGLE},
498 {0, EMR_SELECTOBJECT},
499 {0, EMR_DELETEOBJECT},
500 {0, EMR_EOF},
504 static void test_emfonly(void)
506 GpStatus stat;
507 GpMetafile *metafile;
508 GpImage *clone;
509 GpGraphics *graphics;
510 HDC hdc, metafile_dc;
511 HENHMETAFILE hemf;
512 BOOL ret;
513 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
514 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
515 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
516 HBRUSH hbrush, holdbrush;
517 GpBitmap *bitmap;
518 ARGB color;
520 hdc = CreateCompatibleDC(0);
522 stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
523 expect(Ok, stat);
525 DeleteDC(hdc);
527 if (stat != Ok)
528 return;
530 stat = GdipGetHemfFromMetafile(metafile, &hemf);
531 expect(InvalidParameter, stat);
533 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
534 expect(Ok, stat);
536 stat = GdipGetDC(graphics, &metafile_dc);
537 expect(Ok, stat);
539 if (stat != Ok)
541 GdipDeleteGraphics(graphics);
542 GdipDisposeImage((GpImage*)metafile);
543 return;
546 hbrush = CreateSolidBrush(0xff0000);
548 holdbrush = SelectObject(metafile_dc, hbrush);
550 Rectangle(metafile_dc, 25, 25, 75, 75);
552 SelectObject(metafile_dc, holdbrush);
554 DeleteObject(hbrush);
556 stat = GdipReleaseDC(graphics, metafile_dc);
557 expect(Ok, stat);
559 stat = GdipDeleteGraphics(graphics);
560 expect(Ok, stat);
562 check_metafile(metafile, emfonly_records, "emfonly metafile", dst_points, &frame, UnitPixel);
564 save_metafile(metafile, "emfonly.emf");
566 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
567 expect(Ok, stat);
569 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
570 expect(Ok, stat);
572 play_metafile(metafile, graphics, emfonly_records, "emfonly playback", dst_points, &frame, UnitPixel);
574 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
575 expect(Ok, stat);
576 expect(0, color);
578 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
579 expect(Ok, stat);
580 expect(0xff0000ff, color);
582 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
583 expect(Ok, stat);
585 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
586 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
587 expect(Ok, stat);
589 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
590 expect(Ok, stat);
591 expect(0, color);
593 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
594 expect(Ok, stat);
595 expect(0xff0000ff, color);
597 stat = GdipCloneImage((GpImage*)metafile, &clone);
598 expect(Ok, stat);
600 if (stat == Ok)
602 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
603 expect(Ok, stat);
605 stat = GdipDrawImagePointsRect(graphics, clone, dst_points, 3,
606 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
607 expect(Ok, stat);
609 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
610 expect(Ok, stat);
611 expect(0, color);
613 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
614 expect(Ok, stat);
615 expect(0xff0000ff, color);
617 GdipDisposeImage(clone);
620 stat = GdipDeleteGraphics(graphics);
621 expect(Ok, stat);
623 stat = GdipDisposeImage((GpImage*)bitmap);
624 expect(Ok, stat);
626 stat = GdipGetHemfFromMetafile(metafile, &hemf);
627 expect(Ok, stat);
629 stat = GdipDisposeImage((GpImage*)metafile);
630 expect(Ok, stat);
632 check_emfplus(hemf, emfonly_records, "emfonly emf");
634 ret = DeleteEnhMetaFile(hemf);
635 ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
638 static const emfplus_record fillrect_records[] = {
639 {0, EMR_HEADER},
640 {0, EmfPlusRecordTypeHeader},
641 {0, EmfPlusRecordTypeFillRects},
642 {0, EmfPlusRecordTypeEndOfFile},
643 {0, EMR_EOF},
647 static void test_fillrect(void)
649 GpStatus stat;
650 GpMetafile *metafile;
651 GpGraphics *graphics;
652 HDC hdc;
653 HENHMETAFILE hemf;
654 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
655 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
656 static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
657 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
658 GpBitmap *bitmap;
659 ARGB color;
660 GpBrush *brush;
662 hdc = CreateCompatibleDC(0);
664 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
665 expect(Ok, stat);
667 DeleteDC(hdc);
669 if (stat != Ok)
670 return;
672 stat = GdipGetHemfFromMetafile(metafile, &hemf);
673 expect(InvalidParameter, stat);
675 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
676 expect(Ok, stat);
678 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
679 expect(Ok, stat);
681 stat = GdipFillRectangleI(graphics, brush, 25, 25, 75, 75);
682 expect(Ok, stat);
684 stat = GdipDeleteBrush(brush);
685 expect(Ok, stat);
687 stat = GdipDeleteGraphics(graphics);
688 expect(Ok, stat);
690 check_metafile(metafile, fillrect_records, "fillrect metafile", dst_points, &frame, UnitPixel);
692 save_metafile(metafile, "fillrect.emf");
694 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
695 expect(Ok, stat);
697 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
698 expect(Ok, stat);
700 play_metafile(metafile, graphics, fillrect_records, "fillrect playback", dst_points, &frame, UnitPixel);
702 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
703 expect(Ok, stat);
704 expect(0, color);
706 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
707 expect(Ok, stat);
708 expect(0xff0000ff, color);
710 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
711 expect(Ok, stat);
713 play_metafile(metafile, graphics, fillrect_records, "fillrect playback", dst_points_half, &frame, UnitPixel);
715 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
716 expect(Ok, stat);
717 expect(0xff0000ff, color);
719 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
720 expect(Ok, stat);
721 expect(0, color);
723 stat = GdipBitmapSetPixel(bitmap, 15, 15, 0);
724 expect(Ok, stat);
726 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
727 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
728 expect(Ok, stat);
730 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
731 expect(Ok, stat);
732 expect(0, color);
734 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
735 expect(Ok, stat);
736 expect(0xff0000ff, color);
738 stat = GdipDeleteGraphics(graphics);
739 expect(Ok, stat);
741 stat = GdipDisposeImage((GpImage*)bitmap);
742 expect(Ok, stat);
744 stat = GdipDisposeImage((GpImage*)metafile);
745 expect(Ok, stat);
748 static const emfplus_record pagetransform_records[] = {
749 {0, EMR_HEADER},
750 {0, EmfPlusRecordTypeHeader},
751 {0, EmfPlusRecordTypeFillRects},
752 {0, EmfPlusRecordTypeSetPageTransform},
753 {0, EmfPlusRecordTypeFillRects},
754 {0, EmfPlusRecordTypeSetPageTransform},
755 {0, EmfPlusRecordTypeFillRects},
756 {0, EmfPlusRecordTypeSetPageTransform},
757 {0, EmfPlusRecordTypeFillRects},
758 {0, EmfPlusRecordTypeSetPageTransform},
759 {0, EmfPlusRecordTypeFillRects},
760 {0, EmfPlusRecordTypeEndOfFile},
761 {0, EMR_EOF},
765 static void test_pagetransform(void)
767 GpStatus stat;
768 GpMetafile *metafile;
769 GpGraphics *graphics;
770 HDC hdc;
771 static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
772 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
773 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
774 GpBitmap *bitmap;
775 ARGB color;
776 GpBrush *brush;
777 GpUnit unit;
778 REAL scale, dpix, dpiy;
779 UINT width, height;
781 hdc = CreateCompatibleDC(0);
783 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitInch, description, &metafile);
784 expect(Ok, stat);
786 DeleteDC(hdc);
788 if (stat != Ok)
789 return;
791 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &dpix);
792 todo_wine expect(InvalidParameter, stat);
794 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &dpiy);
795 todo_wine expect(InvalidParameter, stat);
797 stat = GdipGetImageWidth((GpImage*)metafile, &width);
798 todo_wine expect(InvalidParameter, stat);
800 stat = GdipGetImageHeight((GpImage*)metafile, &height);
801 todo_wine expect(InvalidParameter, stat);
803 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
804 expect(Ok, stat);
806 /* initial scale */
807 stat = GdipGetPageUnit(graphics, &unit);
808 expect(Ok, stat);
809 expect(UnitDisplay, unit);
811 stat = GdipGetPageScale(graphics, &scale);
812 expect(Ok, stat);
813 expectf(1.0, scale);
815 stat = GdipGetDpiX(graphics, &dpix);
816 expect(Ok, stat);
817 expectf(96.0, dpix);
819 stat = GdipGetDpiY(graphics, &dpiy);
820 expect(Ok, stat);
821 expectf(96.0, dpiy);
823 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
824 expect(Ok, stat);
826 stat = GdipFillRectangleI(graphics, brush, 1, 2, 1, 1);
827 expect(Ok, stat);
829 stat = GdipDeleteBrush(brush);
830 expect(Ok, stat);
832 /* page unit = pixels */
833 stat = GdipSetPageUnit(graphics, UnitPixel);
834 expect(Ok, stat);
836 stat = GdipGetPageUnit(graphics, &unit);
837 expect(Ok, stat);
838 expect(UnitPixel, unit);
840 stat = GdipCreateSolidFill((ARGB)0xff00ff00, (GpSolidFill**)&brush);
841 expect(Ok, stat);
843 stat = GdipFillRectangleI(graphics, brush, 0, 1, 1, 1);
844 expect(Ok, stat);
846 stat = GdipDeleteBrush(brush);
847 expect(Ok, stat);
849 /* page scale = 3, unit = pixels */
850 stat = GdipSetPageScale(graphics, 3.0);
851 expect(Ok, stat);
853 stat = GdipGetPageScale(graphics, &scale);
854 expect(Ok, stat);
855 expectf(3.0, scale);
857 stat = GdipCreateSolidFill((ARGB)0xff00ffff, (GpSolidFill**)&brush);
858 expect(Ok, stat);
860 stat = GdipFillRectangleI(graphics, brush, 0, 1, 2, 2);
861 expect(Ok, stat);
863 stat = GdipDeleteBrush(brush);
864 expect(Ok, stat);
866 /* page scale = 3, unit = inches */
867 stat = GdipSetPageUnit(graphics, UnitInch);
868 expect(Ok, stat);
870 stat = GdipGetPageUnit(graphics, &unit);
871 expect(Ok, stat);
872 expect(UnitInch, unit);
874 stat = GdipCreateSolidFill((ARGB)0xffff0000, (GpSolidFill**)&brush);
875 expect(Ok, stat);
877 stat = GdipFillRectangle(graphics, brush, 1.0/96.0, 0, 1, 1);
878 expect(Ok, stat);
880 stat = GdipDeleteBrush(brush);
881 expect(Ok, stat);
883 /* page scale = 3, unit = display */
884 stat = GdipSetPageUnit(graphics, UnitDisplay);
885 expect(Ok, stat);
887 stat = GdipGetPageUnit(graphics, &unit);
888 expect(Ok, stat);
889 expect(UnitDisplay, unit);
891 stat = GdipCreateSolidFill((ARGB)0xffff00ff, (GpSolidFill**)&brush);
892 expect(Ok, stat);
894 stat = GdipFillRectangle(graphics, brush, 3, 3, 2, 2);
895 expect(Ok, stat);
897 stat = GdipDeleteBrush(brush);
898 expect(Ok, stat);
900 stat = GdipDeleteGraphics(graphics);
901 expect(Ok, stat);
903 check_metafile(metafile, pagetransform_records, "pagetransform metafile", dst_points, &frame, UnitPixel);
905 save_metafile(metafile, "pagetransform.emf");
907 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
908 expect(Ok, stat);
910 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
911 expect(Ok, stat);
913 play_metafile(metafile, graphics, pagetransform_records, "pagetransform playback", dst_points, &frame, UnitPixel);
915 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
916 expect(Ok, stat);
917 expect(0, color);
919 stat = GdipBitmapGetPixel(bitmap, 30, 50, &color);
920 expect(Ok, stat);
921 expect(0xff0000ff, color);
923 stat = GdipBitmapGetPixel(bitmap, 10, 30, &color);
924 expect(Ok, stat);
925 expect(0xff00ff00, color);
927 stat = GdipBitmapGetPixel(bitmap, 20, 80, &color);
928 expect(Ok, stat);
929 expect(0xff00ffff, color);
931 stat = GdipBitmapGetPixel(bitmap, 80, 20, &color);
932 expect(Ok, stat);
933 expect(0xffff0000, color);
935 stat = GdipBitmapGetPixel(bitmap, 80, 80, &color);
936 expect(Ok, stat);
937 expect(0xffff00ff, color);
939 stat = GdipDeleteGraphics(graphics);
940 expect(Ok, stat);
942 stat = GdipDisposeImage((GpImage*)bitmap);
943 expect(Ok, stat);
945 stat = GdipDisposeImage((GpImage*)metafile);
946 expect(Ok, stat);
949 START_TEST(metafile)
951 struct GdiplusStartupInput gdiplusStartupInput;
952 ULONG_PTR gdiplusToken;
953 int myARGC;
954 char **myARGV;
956 gdiplusStartupInput.GdiplusVersion = 1;
957 gdiplusStartupInput.DebugEventCallback = NULL;
958 gdiplusStartupInput.SuppressBackgroundThread = 0;
959 gdiplusStartupInput.SuppressExternalCodecs = 0;
961 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
963 myARGC = winetest_get_mainargs( &myARGV );
965 if (myARGC >= 3 && !strcmp(myARGV[2], "save"))
966 save_metafiles = TRUE;
968 test_empty();
969 test_getdc();
970 test_emfonly();
971 test_fillrect();
972 test_pagetransform();
974 GdiplusShutdown(gdiplusToken);