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
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
39 typedef struct emfplus_check_state
43 const struct emfplus_record
*expected
;
45 } emfplus_check_state
;
47 static void check_record(int count
, const char *desc
, const struct emfplus_record
*expected
, const struct emfplus_record
*actual
)
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
);
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
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)
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
)
94 if (state
->expected
[state
->count
].record_type
)
97 actual
.record_type
= record
->Type
;
99 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
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
);
117 if (state
->expected
[state
->count
].record_type
)
120 actual
.record_type
= lpEMFR
->iType
;
122 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
128 ok(0, "%s: Unexpected EMF 0x%x record\n", state
->desc
, lpEMFR
->iType
);
134 static void check_emfplus(HENHMETAFILE hemf
, const emfplus_record
*expected
, const char *desc
)
136 emfplus_check_state state
;
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
);
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
;
157 actual
.record_type
= record_type
;
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
);
170 ok(0, "%s: Unexpected EMF 0x%x record\n", state
->desc
, record_type
);
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
)
181 GpGraphics
*graphics
;
182 emfplus_check_state state
;
186 state
.expected
= expected
;
187 state
.metafile
= metafile
;
189 hdc
= CreateCompatibleDC(0);
191 stat
= GdipCreateFromHDC(hdc
, &graphics
);
194 stat
= GdipEnumerateMetafileSrcRectDestPoints(graphics
, metafile
, dst_points
,
195 3, src_rect
, src_unit
, enum_metafile_proc
, &state
, NULL
);
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
);
201 ok(expected
[state
.count
].record_type
== 0, "%s: Got %i records, expecting more\n", desc
, state
.count
);
203 GdipDeleteGraphics(graphics
);
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
;
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
);
221 ok(stat
== Ok
, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state
->desc
, state
->count
, stat
);
226 if (state
->expected
[state
->count
].playback_todo
)
227 todo_wine
ok(0, "%s: too many records\n", state
->desc
);
229 ok(0, "%s: too many records\n", state
->desc
);
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
)
241 emfplus_check_state state
;
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
);
253 static void save_metafile(GpMetafile
*metafile
, const char *filename
)
261 stat
= GdipCloneImage((GpImage
*)metafile
, (GpImage
**)&clone
);
264 stat
= GdipGetHemfFromMetafile(clone
, &hemf
);
267 DeleteEnhMetaFile(CopyEnhMetaFileA(hemf
, filename
));
269 DeleteEnhMetaFile(hemf
);
271 stat
= GdipDisposeImage((GpImage
*)clone
);
276 static const emfplus_record empty_records
[] = {
278 {0, EmfPlusRecordTypeHeader
},
279 {0, EmfPlusRecordTypeEndOfFile
},
284 static void test_empty(void)
287 GpMetafile
*metafile
;
288 GpGraphics
*graphics
;
290 HENHMETAFILE hemf
, dummy
;
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
);
324 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
325 expect(InvalidParameter
, stat
);
327 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
330 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
331 expect(InvalidParameter
, stat
);
333 stat
= GdipDeleteGraphics(graphics
);
336 check_metafile(metafile
, empty_records
, "empty metafile", dst_points
, &frame
, UnitPixel
);
338 save_metafile(metafile
, "empty.emf");
340 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
343 stat
= GdipGetHemfFromMetafile(metafile
, &dummy
);
344 expect(InvalidParameter
, stat
);
346 stat
= GdipDisposeImage((GpImage
*)metafile
);
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
[] = {
357 {0, EmfPlusRecordTypeHeader
},
358 {0, EmfPlusRecordTypeGetDC
},
359 {0, EMR_CREATEBRUSHINDIRECT
},
360 {0, EMR_SELECTOBJECT
},
362 {0, EMR_SELECTOBJECT
},
363 {0, EMR_DELETEOBJECT
},
364 {0, EmfPlusRecordTypeEndOfFile
},
369 static void test_getdc(void)
372 GpMetafile
*metafile
;
373 GpGraphics
*graphics
;
374 HDC hdc
, metafile_dc
;
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
;
385 hdc
= CreateCompatibleDC(0);
387 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
395 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
396 expect(InvalidParameter
, stat
);
398 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
401 stat
= GdipGetDC(graphics
, &metafile_dc
);
406 GdipDeleteGraphics(graphics
);
407 GdipDisposeImage((GpImage
*)metafile
);
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
);
424 stat
= GdipDeleteGraphics(graphics
);
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
);
434 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
437 play_metafile(metafile
, graphics
, getdc_records
, "getdc playback", dst_points
, &frame
, UnitPixel
);
439 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
443 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
445 expect(0xff0000ff, color
);
447 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
450 play_metafile(metafile
, graphics
, getdc_records
, "getdc playback", dst_points_half
, &frame
, UnitPixel
);
452 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
454 expect(0xff0000ff, color
);
456 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
460 stat
= GdipBitmapSetPixel(bitmap
, 15, 15, 0);
463 stat
= GdipDrawImagePointsRect(graphics
, (GpImage
*)metafile
, dst_points
, 3,
464 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
467 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
471 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
473 expect(0xff0000ff, color
);
475 stat
= GdipDeleteGraphics(graphics
);
478 stat
= GdipDisposeImage((GpImage
*)bitmap
);
481 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
484 stat
= GdipDisposeImage((GpImage
*)metafile
);
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
[] = {
495 {0, EMR_CREATEBRUSHINDIRECT
},
496 {0, EMR_SELECTOBJECT
},
498 {0, EMR_SELECTOBJECT
},
499 {0, EMR_DELETEOBJECT
},
504 static void test_emfonly(void)
507 GpMetafile
*metafile
;
509 GpGraphics
*graphics
;
510 HDC hdc
, metafile_dc
;
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
;
520 hdc
= CreateCompatibleDC(0);
522 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
530 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
531 expect(InvalidParameter
, stat
);
533 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
536 stat
= GdipGetDC(graphics
, &metafile_dc
);
541 GdipDeleteGraphics(graphics
);
542 GdipDisposeImage((GpImage
*)metafile
);
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
);
559 stat
= GdipDeleteGraphics(graphics
);
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
);
569 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
572 play_metafile(metafile
, graphics
, emfonly_records
, "emfonly playback", dst_points
, &frame
, UnitPixel
);
574 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
578 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
580 expect(0xff0000ff, color
);
582 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
585 stat
= GdipDrawImagePointsRect(graphics
, (GpImage
*)metafile
, dst_points
, 3,
586 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
589 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
593 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
595 expect(0xff0000ff, color
);
597 stat
= GdipCloneImage((GpImage
*)metafile
, &clone
);
602 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
605 stat
= GdipDrawImagePointsRect(graphics
, clone
, dst_points
, 3,
606 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
609 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
613 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
615 expect(0xff0000ff, color
);
617 GdipDisposeImage(clone
);
620 stat
= GdipDeleteGraphics(graphics
);
623 stat
= GdipDisposeImage((GpImage
*)bitmap
);
626 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
629 stat
= GdipDisposeImage((GpImage
*)metafile
);
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
[] = {
640 {0, EmfPlusRecordTypeHeader
},
641 {0, EmfPlusRecordTypeFillRects
},
642 {0, EmfPlusRecordTypeEndOfFile
},
647 static void test_fillrect(void)
650 GpMetafile
*metafile
;
651 GpGraphics
*graphics
;
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};
662 hdc
= CreateCompatibleDC(0);
664 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
672 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
673 expect(InvalidParameter
, stat
);
675 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
678 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
681 stat
= GdipFillRectangleI(graphics
, brush
, 25, 25, 75, 75);
684 stat
= GdipDeleteBrush(brush
);
687 stat
= GdipDeleteGraphics(graphics
);
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
);
697 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
700 play_metafile(metafile
, graphics
, fillrect_records
, "fillrect playback", dst_points
, &frame
, UnitPixel
);
702 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
706 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
708 expect(0xff0000ff, color
);
710 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
713 play_metafile(metafile
, graphics
, fillrect_records
, "fillrect playback", dst_points_half
, &frame
, UnitPixel
);
715 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
717 expect(0xff0000ff, color
);
719 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
723 stat
= GdipBitmapSetPixel(bitmap
, 15, 15, 0);
726 stat
= GdipDrawImagePointsRect(graphics
, (GpImage
*)metafile
, dst_points
, 3,
727 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
730 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
734 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
736 expect(0xff0000ff, color
);
738 stat
= GdipDeleteGraphics(graphics
);
741 stat
= GdipDisposeImage((GpImage
*)bitmap
);
744 stat
= GdipDisposeImage((GpImage
*)metafile
);
748 static const emfplus_record pagetransform_records
[] = {
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
},
765 static void test_pagetransform(void)
768 GpMetafile
*metafile
;
769 GpGraphics
*graphics
;
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};
778 REAL scale
, dpix
, dpiy
;
781 hdc
= CreateCompatibleDC(0);
783 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitInch
, description
, &metafile
);
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
);
807 stat
= GdipGetPageUnit(graphics
, &unit
);
809 expect(UnitDisplay
, unit
);
811 stat
= GdipGetPageScale(graphics
, &scale
);
815 stat
= GdipGetDpiX(graphics
, &dpix
);
819 stat
= GdipGetDpiY(graphics
, &dpiy
);
823 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
826 stat
= GdipFillRectangleI(graphics
, brush
, 1, 2, 1, 1);
829 stat
= GdipDeleteBrush(brush
);
832 /* page unit = pixels */
833 stat
= GdipSetPageUnit(graphics
, UnitPixel
);
836 stat
= GdipGetPageUnit(graphics
, &unit
);
838 expect(UnitPixel
, unit
);
840 stat
= GdipCreateSolidFill((ARGB
)0xff00ff00, (GpSolidFill
**)&brush
);
843 stat
= GdipFillRectangleI(graphics
, brush
, 0, 1, 1, 1);
846 stat
= GdipDeleteBrush(brush
);
849 /* page scale = 3, unit = pixels */
850 stat
= GdipSetPageScale(graphics
, 3.0);
853 stat
= GdipGetPageScale(graphics
, &scale
);
857 stat
= GdipCreateSolidFill((ARGB
)0xff00ffff, (GpSolidFill
**)&brush
);
860 stat
= GdipFillRectangleI(graphics
, brush
, 0, 1, 2, 2);
863 stat
= GdipDeleteBrush(brush
);
866 /* page scale = 3, unit = inches */
867 stat
= GdipSetPageUnit(graphics
, UnitInch
);
870 stat
= GdipGetPageUnit(graphics
, &unit
);
872 expect(UnitInch
, unit
);
874 stat
= GdipCreateSolidFill((ARGB
)0xffff0000, (GpSolidFill
**)&brush
);
877 stat
= GdipFillRectangle(graphics
, brush
, 1.0/96.0, 0, 1, 1);
880 stat
= GdipDeleteBrush(brush
);
883 /* page scale = 3, unit = display */
884 stat
= GdipSetPageUnit(graphics
, UnitDisplay
);
887 stat
= GdipGetPageUnit(graphics
, &unit
);
889 expect(UnitDisplay
, unit
);
891 stat
= GdipCreateSolidFill((ARGB
)0xffff00ff, (GpSolidFill
**)&brush
);
894 stat
= GdipFillRectangle(graphics
, brush
, 3, 3, 2, 2);
897 stat
= GdipDeleteBrush(brush
);
900 stat
= GdipDeleteGraphics(graphics
);
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
);
910 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
913 play_metafile(metafile
, graphics
, pagetransform_records
, "pagetransform playback", dst_points
, &frame
, UnitPixel
);
915 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
919 stat
= GdipBitmapGetPixel(bitmap
, 30, 50, &color
);
921 expect(0xff0000ff, color
);
923 stat
= GdipBitmapGetPixel(bitmap
, 10, 30, &color
);
925 expect(0xff00ff00, color
);
927 stat
= GdipBitmapGetPixel(bitmap
, 20, 80, &color
);
929 expect(0xff00ffff, color
);
931 stat
= GdipBitmapGetPixel(bitmap
, 80, 20, &color
);
933 expect(0xffff0000, color
);
935 stat
= GdipBitmapGetPixel(bitmap
, 80, 80, &color
);
937 expect(0xffff00ff, color
);
939 stat
= GdipDeleteGraphics(graphics
);
942 stat
= GdipDisposeImage((GpImage
*)bitmap
);
945 stat
= GdipDisposeImage((GpImage
*)metafile
);
951 struct GdiplusStartupInput gdiplusStartupInput
;
952 ULONG_PTR gdiplusToken
;
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
;
972 test_pagetransform();
974 GdiplusShutdown(gdiplusToken
);