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
23 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
24 #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
25 #define expectf(expected, got) expectf_((expected), (got), 0.001)
27 static BOOL save_metafiles
;
28 static BOOL load_metafiles
;
30 typedef struct emfplus_record
35 void (*playback_fn
)(GpMetafile
* metafile
, EmfPlusRecordType record_type
,
36 unsigned int flags
, unsigned int dataSize
, const unsigned char *pStr
);
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
)
49 todo_wine_if (expected
->todo
)
50 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
);
55 typedef struct EmfPlusRecordHeader
61 } EmfPlusRecordHeader
;
72 ObjectTypeStringFormat
,
73 ObjectTypeImageAttributes
,
74 ObjectTypeCustomLineCap
,
81 ImageDataTypeMetafile
,
86 EmfPlusRecordHeader Header
;
92 DWORD MetafileDataSize
;
94 } MetafileImageObject
;
96 static int CALLBACK
enum_emf_proc(HDC hDC
, HANDLETABLE
*lpHTable
, const ENHMETARECORD
*lpEMFR
,
97 int nObj
, LPARAM lpData
)
99 emfplus_check_state
*state
= (emfplus_check_state
*)lpData
;
100 emfplus_record actual
;
102 if (lpEMFR
->iType
== EMR_GDICOMMENT
)
104 const EMRGDICOMMENT
*comment
= (const EMRGDICOMMENT
*)lpEMFR
;
106 if (comment
->cbData
>= 4 && memcmp(comment
->Data
, "EMF+", 4) == 0)
110 while (offset
+ sizeof(EmfPlusRecordHeader
) <= comment
->cbData
)
112 const EmfPlusRecordHeader
*record
= (const EmfPlusRecordHeader
*)&comment
->Data
[offset
];
114 ok(record
->Size
== record
->DataSize
+ sizeof(EmfPlusRecordHeader
),
115 "%s: EMF+ record datasize %u and size %u mismatch\n", state
->desc
, record
->DataSize
, record
->Size
);
117 ok(offset
+ record
->DataSize
<= comment
->cbData
,
118 "%s: EMF+ record truncated\n", state
->desc
);
120 if (offset
+ record
->DataSize
> comment
->cbData
)
123 if (state
->expected
[state
->count
].record_type
)
126 actual
.record_type
= record
->Type
;
128 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
131 if (state
->expected
[state
->count
-1].todo
&& state
->expected
[state
->count
-1].record_type
!= actual
.record_type
)
136 ok(0, "%s: Unexpected EMF+ 0x%x record\n", state
->desc
, record
->Type
);
139 if ((record
->Flags
>> 8) == ObjectTypeImage
&& record
->Type
== EmfPlusRecordTypeObject
)
141 const MetafileImageObject
*image
= (const MetafileImageObject
*)record
;
143 if (image
->Type
== ImageDataTypeMetafile
)
145 HENHMETAFILE hemf
= SetEnhMetaFileBits(image
->MetafileDataSize
, image
->MetafileData
);
146 ok(hemf
!= NULL
, "%s: SetEnhMetaFileBits failed\n", state
->desc
);
148 EnumEnhMetaFile(0, hemf
, enum_emf_proc
, state
, NULL
);
149 DeleteEnhMetaFile(hemf
);
153 offset
+= record
->Size
;
156 ok(offset
== comment
->cbData
, "%s: truncated EMF+ record data?\n", state
->desc
);
162 if (state
->expected
[state
->count
].record_type
)
165 actual
.record_type
= lpEMFR
->iType
;
167 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
173 ok(0, "%s: Unexpected EMF 0x%x record\n", state
->desc
, lpEMFR
->iType
);
179 static void check_emfplus(HENHMETAFILE hemf
, const emfplus_record
*expected
, const char *desc
)
181 emfplus_check_state state
;
185 state
.expected
= expected
;
187 EnumEnhMetaFile(0, hemf
, enum_emf_proc
, &state
, NULL
);
189 todo_wine_if (expected
[state
.count
].todo
)
190 ok(expected
[state
.count
].record_type
== 0, "%s: Got %i records, expecting more\n", desc
, state
.count
);
193 static BOOL CALLBACK
enum_metafile_proc(EmfPlusRecordType record_type
, unsigned int flags
,
194 unsigned int dataSize
, const unsigned char *pStr
, void *userdata
)
196 emfplus_check_state
*state
= (emfplus_check_state
*)userdata
;
197 emfplus_record actual
;
200 actual
.record_type
= record_type
;
203 ok(pStr
== NULL
, "non-NULL pStr\n");
205 if (state
->expected
[state
->count
].record_type
)
207 check_record(state
->count
, state
->desc
, &state
->expected
[state
->count
], &actual
);
213 ok(0, "%s: Unexpected EMF 0x%x record\n", state
->desc
, record_type
);
219 static void check_metafile(GpMetafile
*metafile
, const emfplus_record
*expected
, const char *desc
,
220 const GpPointF
*dst_points
, const GpRectF
*src_rect
, Unit src_unit
)
224 GpGraphics
*graphics
;
225 emfplus_check_state state
;
229 state
.expected
= expected
;
230 state
.metafile
= metafile
;
232 hdc
= CreateCompatibleDC(0);
234 stat
= GdipCreateFromHDC(hdc
, &graphics
);
237 stat
= GdipEnumerateMetafileSrcRectDestPoints(graphics
, metafile
, dst_points
,
238 3, src_rect
, src_unit
, enum_metafile_proc
, &state
, NULL
);
241 todo_wine_if (expected
[state
.count
].todo
)
242 ok(expected
[state
.count
].record_type
== 0, "%s: Got %i records, expecting more\n", desc
, state
.count
);
244 GdipDeleteGraphics(graphics
);
249 static BOOL CALLBACK
play_metafile_proc(EmfPlusRecordType record_type
, unsigned int flags
,
250 unsigned int dataSize
, const unsigned char *pStr
, void *userdata
)
252 emfplus_check_state
*state
= (emfplus_check_state
*)userdata
;
255 if (state
->expected
[state
->count
].record_type
)
257 BOOL match
= (state
->expected
[state
->count
].record_type
== record_type
);
259 if (match
&& state
->expected
[state
->count
].playback_fn
)
260 state
->expected
[state
->count
].playback_fn(state
->metafile
, record_type
, flags
, dataSize
, pStr
);
263 stat
= GdipPlayMetafileRecord(state
->metafile
, record_type
, flags
, dataSize
, pStr
);
264 todo_wine_if (state
->expected
[state
->count
].playback_todo
)
265 ok(stat
== Ok
, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state
->desc
, state
->count
, stat
);
268 todo_wine_if (state
->expected
[state
->count
].todo
)
269 ok(state
->expected
[state
->count
].record_type
== record_type
,
270 "%s.%i: expected record type 0x%x, got 0x%x\n", state
->desc
, state
->count
,
271 state
->expected
[state
->count
].record_type
, record_type
);
276 todo_wine_if (state
->expected
[state
->count
].playback_todo
)
277 ok(0, "%s: unexpected record 0x%x\n", state
->desc
, record_type
);
285 static void play_metafile(GpMetafile
*metafile
, GpGraphics
*graphics
, const emfplus_record
*expected
,
286 const char *desc
, const GpPointF
*dst_points
, const GpRectF
*src_rect
, Unit src_unit
)
289 emfplus_check_state state
;
293 state
.expected
= expected
;
294 state
.metafile
= metafile
;
296 stat
= GdipEnumerateMetafileSrcRectDestPoints(graphics
, metafile
, dst_points
,
297 3, src_rect
, src_unit
, play_metafile_proc
, &state
, NULL
);
301 /* When 'save' or 'load' is specified on the command line, save or
302 * load the specified filename. */
303 static void sync_metafile(GpMetafile
**metafile
, const char *filename
)
311 stat
= GdipCloneImage((GpImage
*)*metafile
, (GpImage
**)&clone
);
314 stat
= GdipGetHemfFromMetafile(clone
, &hemf
);
317 DeleteEnhMetaFile(CopyEnhMetaFileA(hemf
, filename
));
319 DeleteEnhMetaFile(hemf
);
321 stat
= GdipDisposeImage((GpImage
*)clone
);
324 else if (load_metafiles
)
328 stat
= GdipDisposeImage((GpImage
*)*metafile
);
332 hemf
= GetEnhMetaFileA(filename
);
333 ok(hemf
!= NULL
, "%s could not be opened\n", filename
);
335 stat
= GdipCreateMetafileFromEmf(hemf
, TRUE
, metafile
);
340 static const emfplus_record empty_records
[] = {
342 {0, EmfPlusRecordTypeHeader
},
343 {0, EmfPlusRecordTypeEndOfFile
},
348 static void test_empty(void)
351 GpMetafile
*metafile
;
352 GpGraphics
*graphics
;
357 HENHMETAFILE hemf
, dummy
;
358 MetafileHeader header
;
359 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
360 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
361 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
363 hdc
= CreateCompatibleDC(0);
365 stat
= GdipRecordMetafile(NULL
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
366 expect(InvalidParameter
, stat
);
368 stat
= GdipRecordMetafile(hdc
, MetafileTypeInvalid
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
369 expect(InvalidParameter
, stat
);
371 stat
= GdipRecordMetafile(hdc
, MetafileTypeWmf
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
372 expect(InvalidParameter
, stat
);
374 stat
= GdipRecordMetafile(hdc
, MetafileTypeWmfPlaceable
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
375 expect(InvalidParameter
, stat
);
377 stat
= GdipRecordMetafile(hdc
, MetafileTypeEmfPlusDual
+1, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
378 expect(InvalidParameter
, stat
);
380 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, NULL
);
381 expect(InvalidParameter
, stat
);
383 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
391 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
392 expect(InvalidParameter
, stat
);
394 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
397 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
398 expect(InvalidParameter
, stat
);
400 stat
= GdipDeleteGraphics(graphics
);
403 check_metafile(metafile
, empty_records
, "empty metafile", dst_points
, &frame
, UnitPixel
);
405 sync_metafile(&metafile
, "empty.emf");
407 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
409 expectf(0.0, bounds
.X
);
410 expectf(0.0, bounds
.Y
);
411 expectf_(100.0, bounds
.Width
, 0.05);
412 expectf_(100.0, bounds
.Height
, 0.05);
413 expect(UnitPixel
, unit
);
415 stat
= GdipGetImageHorizontalResolution((GpImage
*)metafile
, &xres
);
418 stat
= GdipGetImageVerticalResolution((GpImage
*)metafile
, &yres
);
421 memset(&header
, 0xaa, sizeof(header
));
422 stat
= GdipGetMetafileHeaderFromMetafile(metafile
, &header
);
424 expect(MetafileTypeEmfPlusOnly
, header
.Type
);
425 expect(U(header
).EmfHeader
.nBytes
, header
.Size
);
426 ok(header
.Version
== 0xdbc01001 || header
.Version
== 0xdbc01002, "Unexpected version %x\n", header
.Version
);
427 expect(1, header
.EmfPlusFlags
); /* reference device was display, not printer */
428 expectf(xres
, header
.DpiX
);
429 expectf(xres
, U(header
).EmfHeader
.szlDevice
.cx
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cx
* 25.4);
430 expectf(yres
, header
.DpiY
);
431 expectf(yres
, U(header
).EmfHeader
.szlDevice
.cy
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cy
* 25.4);
434 expect(100, header
.Width
);
435 expect(100, header
.Height
);
436 expect(28, header
.EmfPlusHeaderSize
);
437 expect(96, header
.LogicalDpiX
);
438 expect(96, header
.LogicalDpiX
);
439 expect(EMR_HEADER
, U(header
).EmfHeader
.iType
);
440 expect(0, U(header
).EmfHeader
.rclBounds
.left
);
441 expect(0, U(header
).EmfHeader
.rclBounds
.top
);
442 expect(-1, U(header
).EmfHeader
.rclBounds
.right
);
443 expect(-1, U(header
).EmfHeader
.rclBounds
.bottom
);
444 expect(0, U(header
).EmfHeader
.rclFrame
.left
);
445 expect(0, U(header
).EmfHeader
.rclFrame
.top
);
446 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.right
* xres
/ 2540.0, 2.0);
447 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.bottom
* yres
/ 2540.0, 2.0);
449 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
452 stat
= GdipGetHemfFromMetafile(metafile
, &dummy
);
453 expect(InvalidParameter
, stat
);
455 stat
= GdipDisposeImage((GpImage
*)metafile
);
458 check_emfplus(hemf
, empty_records
, "empty emf");
460 memset(&header
, 0xaa, sizeof(header
));
461 stat
= GdipGetMetafileHeaderFromEmf(hemf
, &header
);
463 expect(MetafileTypeEmfPlusOnly
, header
.Type
);
464 expect(U(header
).EmfHeader
.nBytes
, header
.Size
);
465 ok(header
.Version
== 0xdbc01001 || header
.Version
== 0xdbc01002, "Unexpected version %x\n", header
.Version
);
466 expect(1, header
.EmfPlusFlags
); /* reference device was display, not printer */
467 expectf(xres
, header
.DpiX
);
468 expectf(xres
, U(header
).EmfHeader
.szlDevice
.cx
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cx
* 25.4);
469 expectf(yres
, header
.DpiY
);
470 expectf(yres
, U(header
).EmfHeader
.szlDevice
.cy
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cy
* 25.4);
473 expect(100, header
.Width
);
474 expect(100, header
.Height
);
475 expect(28, header
.EmfPlusHeaderSize
);
476 expect(96, header
.LogicalDpiX
);
477 expect(96, header
.LogicalDpiX
);
478 expect(EMR_HEADER
, U(header
).EmfHeader
.iType
);
479 expect(0, U(header
).EmfHeader
.rclBounds
.left
);
480 expect(0, U(header
).EmfHeader
.rclBounds
.top
);
481 expect(-1, U(header
).EmfHeader
.rclBounds
.right
);
482 expect(-1, U(header
).EmfHeader
.rclBounds
.bottom
);
483 expect(0, U(header
).EmfHeader
.rclFrame
.left
);
484 expect(0, U(header
).EmfHeader
.rclFrame
.top
);
485 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.right
* xres
/ 2540.0, 2.0);
486 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.bottom
* yres
/ 2540.0, 2.0);
488 stat
= GdipCreateMetafileFromEmf(hemf
, TRUE
, &metafile
);
491 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
493 expectf(0.0, bounds
.X
);
494 expectf(0.0, bounds
.Y
);
495 expectf_(100.0, bounds
.Width
, 0.05);
496 expectf_(100.0, bounds
.Height
, 0.05);
497 expect(UnitPixel
, unit
);
499 stat
= GdipGetImageHorizontalResolution((GpImage
*)metafile
, &xres
);
501 expectf(header
.DpiX
, xres
);
503 stat
= GdipGetImageVerticalResolution((GpImage
*)metafile
, &yres
);
505 expectf(header
.DpiY
, yres
);
507 memset(&header
, 0xaa, sizeof(header
));
508 stat
= GdipGetMetafileHeaderFromMetafile(metafile
, &header
);
510 expect(MetafileTypeEmfPlusOnly
, header
.Type
);
511 expect(U(header
).EmfHeader
.nBytes
, header
.Size
);
512 ok(header
.Version
== 0xdbc01001 || header
.Version
== 0xdbc01002, "Unexpected version %x\n", header
.Version
);
513 expect(1, header
.EmfPlusFlags
); /* reference device was display, not printer */
514 expectf(xres
, header
.DpiX
);
515 expectf(xres
, U(header
).EmfHeader
.szlDevice
.cx
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cx
* 25.4);
516 expectf(yres
, header
.DpiY
);
517 expectf(yres
, U(header
).EmfHeader
.szlDevice
.cy
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cy
* 25.4);
520 expect(100, header
.Width
);
521 expect(100, header
.Height
);
522 expect(28, header
.EmfPlusHeaderSize
);
523 expect(96, header
.LogicalDpiX
);
524 expect(96, header
.LogicalDpiX
);
525 expect(EMR_HEADER
, U(header
).EmfHeader
.iType
);
526 expect(0, U(header
).EmfHeader
.rclBounds
.left
);
527 expect(0, U(header
).EmfHeader
.rclBounds
.top
);
528 expect(-1, U(header
).EmfHeader
.rclBounds
.right
);
529 expect(-1, U(header
).EmfHeader
.rclBounds
.bottom
);
530 expect(0, U(header
).EmfHeader
.rclFrame
.left
);
531 expect(0, U(header
).EmfHeader
.rclFrame
.top
);
532 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.right
* xres
/ 2540.0, 2.0);
533 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.bottom
* yres
/ 2540.0, 2.0);
535 stat
= GdipDisposeImage((GpImage
*)metafile
);
539 static const emfplus_record getdc_records
[] = {
541 {0, EmfPlusRecordTypeHeader
},
542 {0, EmfPlusRecordTypeGetDC
},
543 {0, EMR_CREATEBRUSHINDIRECT
},
544 {0, EMR_SELECTOBJECT
},
546 {0, EMR_SELECTOBJECT
},
547 {0, EMR_DELETEOBJECT
},
548 {0, EmfPlusRecordTypeEndOfFile
},
553 static void test_getdc(void)
556 GpMetafile
*metafile
;
557 GpGraphics
*graphics
;
558 HDC hdc
, metafile_dc
;
561 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
562 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
563 static const GpPointF dst_points_half
[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
564 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
565 HBRUSH hbrush
, holdbrush
;
569 hdc
= CreateCompatibleDC(0);
571 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
579 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
580 expect(InvalidParameter
, stat
);
582 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
585 stat
= GdipGetDC(graphics
, &metafile_dc
);
590 GdipDeleteGraphics(graphics
);
591 GdipDisposeImage((GpImage
*)metafile
);
595 hbrush
= CreateSolidBrush(0xff0000);
597 holdbrush
= SelectObject(metafile_dc
, hbrush
);
599 Rectangle(metafile_dc
, 25, 25, 75, 75);
601 SelectObject(metafile_dc
, holdbrush
);
603 DeleteObject(hbrush
);
605 stat
= GdipReleaseDC(graphics
, metafile_dc
);
608 stat
= GdipDeleteGraphics(graphics
);
611 check_metafile(metafile
, getdc_records
, "getdc metafile", dst_points
, &frame
, UnitPixel
);
613 sync_metafile(&metafile
, "getdc.emf");
615 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
618 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
621 play_metafile(metafile
, graphics
, getdc_records
, "getdc playback", dst_points
, &frame
, UnitPixel
);
623 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
627 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
629 expect(0xff0000ff, color
);
631 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
634 play_metafile(metafile
, graphics
, getdc_records
, "getdc playback", dst_points_half
, &frame
, UnitPixel
);
636 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
638 expect(0xff0000ff, color
);
640 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
644 stat
= GdipBitmapSetPixel(bitmap
, 15, 15, 0);
647 stat
= GdipDrawImagePointsRect(graphics
, (GpImage
*)metafile
, dst_points
, 3,
648 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
651 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
655 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
657 expect(0xff0000ff, color
);
659 stat
= GdipDeleteGraphics(graphics
);
662 stat
= GdipDisposeImage((GpImage
*)bitmap
);
665 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
668 stat
= GdipDisposeImage((GpImage
*)metafile
);
671 check_emfplus(hemf
, getdc_records
, "getdc emf");
673 ret
= DeleteEnhMetaFile(hemf
);
674 ok(ret
!= 0, "Failed to delete enhmetafile %p\n", hemf
);
677 static const emfplus_record emfonly_records
[] = {
679 {0, EMR_CREATEBRUSHINDIRECT
},
680 {0, EMR_SELECTOBJECT
},
682 {0, EMR_SELECTOBJECT
},
683 {0, EMR_DELETEOBJECT
},
688 static const emfplus_record emfonly_draw_records
[] = {
692 {1, EMR_SETMITERLIMIT
},
693 {1, EMR_MODIFYWORLDTRANSFORM
},
694 {1, EMR_EXTCREATEPEN
},
695 {1, EMR_SELECTOBJECT
},
696 {1, EMR_SELECTOBJECT
},
698 {1, EMR_SELECTOBJECT
},
699 {1, EMR_SELECTOBJECT
},
700 {1, EMR_MODIFYWORLDTRANSFORM
},
701 {1, EMR_DELETEOBJECT
},
702 {1, EMR_SETMITERLIMIT
},
708 static void test_emfonly(void)
711 GpMetafile
*metafile
;
713 GpGraphics
*graphics
;
714 HDC hdc
, metafile_dc
;
719 MetafileHeader header
;
720 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
721 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
722 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
723 HBRUSH hbrush
, holdbrush
;
728 hdc
= CreateCompatibleDC(0);
730 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
738 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
739 expect(InvalidParameter
, stat
);
741 memset(&header
, 0xaa, sizeof(header
));
742 stat
= GdipGetMetafileHeaderFromMetafile(metafile
, &header
);
744 expect(MetafileTypeEmf
, header
.Type
);
745 ok(header
.Version
== 0xdbc01001 || header
.Version
== 0xdbc01002, "Unexpected version %x\n", header
.Version
);
746 /* The rest is zeroed or seemingly random/uninitialized garbage. */
748 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
751 stat
= GdipGetDC(graphics
, &metafile_dc
);
756 GdipDeleteGraphics(graphics
);
757 GdipDisposeImage((GpImage
*)metafile
);
761 hbrush
= CreateSolidBrush(0xff0000);
763 holdbrush
= SelectObject(metafile_dc
, hbrush
);
765 Rectangle(metafile_dc
, 25, 25, 75, 75);
767 SelectObject(metafile_dc
, holdbrush
);
769 DeleteObject(hbrush
);
771 stat
= GdipReleaseDC(graphics
, metafile_dc
);
774 stat
= GdipDeleteGraphics(graphics
);
777 check_metafile(metafile
, emfonly_records
, "emfonly metafile", dst_points
, &frame
, UnitPixel
);
779 sync_metafile(&metafile
, "emfonly.emf");
781 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
783 expectf(0.0, bounds
.X
);
784 expectf(0.0, bounds
.Y
);
785 expectf_(100.0, bounds
.Width
, 0.05);
786 expectf_(100.0, bounds
.Height
, 0.05);
787 expect(UnitPixel
, unit
);
789 stat
= GdipGetImageHorizontalResolution((GpImage
*)metafile
, &xres
);
792 stat
= GdipGetImageVerticalResolution((GpImage
*)metafile
, &yres
);
795 memset(&header
, 0xaa, sizeof(header
));
796 stat
= GdipGetMetafileHeaderFromMetafile(metafile
, &header
);
798 expect(MetafileTypeEmf
, header
.Type
);
799 expect(U(header
).EmfHeader
.nBytes
, header
.Size
);
800 /* For some reason a recoreded EMF Metafile has an EMF+ version. */
801 todo_wine
ok(header
.Version
== 0xdbc01001 || header
.Version
== 0xdbc01002, "Unexpected version %x\n", header
.Version
);
802 expect(0, header
.EmfPlusFlags
);
803 expectf(xres
, header
.DpiX
);
804 expectf(xres
, U(header
).EmfHeader
.szlDevice
.cx
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cx
* 25.4);
805 expectf(yres
, header
.DpiY
);
806 expectf(yres
, U(header
).EmfHeader
.szlDevice
.cy
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cy
* 25.4);
809 expect(100, header
.Width
);
810 expect(100, header
.Height
);
811 expect(0, header
.EmfPlusHeaderSize
);
812 expect(0, header
.LogicalDpiX
);
813 expect(0, header
.LogicalDpiX
);
814 expect(EMR_HEADER
, U(header
).EmfHeader
.iType
);
815 expect(25, U(header
).EmfHeader
.rclBounds
.left
);
816 expect(25, U(header
).EmfHeader
.rclBounds
.top
);
817 expect(74, U(header
).EmfHeader
.rclBounds
.right
);
818 expect(74, U(header
).EmfHeader
.rclBounds
.bottom
);
819 expect(0, U(header
).EmfHeader
.rclFrame
.left
);
820 expect(0, U(header
).EmfHeader
.rclFrame
.top
);
821 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.right
* xres
/ 2540.0, 2.0);
822 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.bottom
* yres
/ 2540.0, 2.0);
824 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
827 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
830 play_metafile(metafile
, graphics
, emfonly_records
, "emfonly playback", dst_points
, &frame
, UnitPixel
);
832 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
836 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
838 expect(0xff0000ff, color
);
840 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
843 stat
= GdipDrawImagePointsRect(graphics
, (GpImage
*)metafile
, dst_points
, 3,
844 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
847 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
851 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
853 expect(0xff0000ff, color
);
855 stat
= GdipCloneImage((GpImage
*)metafile
, &clone
);
860 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
863 stat
= GdipDrawImagePointsRect(graphics
, clone
, dst_points
, 3,
864 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
867 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
871 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
873 expect(0xff0000ff, color
);
875 GdipDisposeImage(clone
);
878 stat
= GdipDeleteGraphics(graphics
);
881 stat
= GdipDisposeImage((GpImage
*)bitmap
);
884 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
887 stat
= GdipDisposeImage((GpImage
*)metafile
);
890 check_emfplus(hemf
, emfonly_records
, "emfonly emf");
892 memset(&header
, 0xaa, sizeof(header
));
893 stat
= GdipGetMetafileHeaderFromEmf(hemf
, &header
);
895 expect(MetafileTypeEmf
, header
.Type
);
896 expect(U(header
).EmfHeader
.nBytes
, header
.Size
);
897 expect(0x10000, header
.Version
);
898 expect(0, header
.EmfPlusFlags
);
899 expectf(xres
, header
.DpiX
);
900 expectf(xres
, U(header
).EmfHeader
.szlDevice
.cx
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cx
* 25.4);
901 expectf(yres
, header
.DpiY
);
902 expectf(yres
, U(header
).EmfHeader
.szlDevice
.cy
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cy
* 25.4);
905 expect(100, header
.Width
);
906 expect(100, header
.Height
);
907 expect(0, header
.EmfPlusHeaderSize
);
908 expect(0, header
.LogicalDpiX
);
909 expect(0, header
.LogicalDpiX
);
910 expect(EMR_HEADER
, U(header
).EmfHeader
.iType
);
911 expect(25, U(header
).EmfHeader
.rclBounds
.left
);
912 expect(25, U(header
).EmfHeader
.rclBounds
.top
);
913 expect(74, U(header
).EmfHeader
.rclBounds
.right
);
914 expect(74, U(header
).EmfHeader
.rclBounds
.bottom
);
915 expect(0, U(header
).EmfHeader
.rclFrame
.left
);
916 expect(0, U(header
).EmfHeader
.rclFrame
.top
);
917 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.right
* xres
/ 2540.0, 2.0);
918 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.bottom
* yres
/ 2540.0, 2.0);
920 stat
= GdipCreateMetafileFromEmf(hemf
, TRUE
, &metafile
);
923 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
925 expectf(0.0, bounds
.X
);
926 expectf(0.0, bounds
.Y
);
927 expectf_(100.0, bounds
.Width
, 0.05);
928 expectf_(100.0, bounds
.Height
, 0.05);
929 expect(UnitPixel
, unit
);
931 stat
= GdipGetImageHorizontalResolution((GpImage
*)metafile
, &xres
);
933 expectf(header
.DpiX
, xres
);
935 stat
= GdipGetImageVerticalResolution((GpImage
*)metafile
, &yres
);
937 expectf(header
.DpiY
, yres
);
939 memset(&header
, 0xaa, sizeof(header
));
940 stat
= GdipGetMetafileHeaderFromMetafile(metafile
, &header
);
942 expect(MetafileTypeEmf
, header
.Type
);
943 expect(U(header
).EmfHeader
.nBytes
, header
.Size
);
944 expect(0x10000, header
.Version
);
945 expect(0, header
.EmfPlusFlags
);
946 expectf(xres
, header
.DpiX
);
947 expectf(xres
, U(header
).EmfHeader
.szlDevice
.cx
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cx
* 25.4);
948 expectf(yres
, header
.DpiY
);
949 expectf(yres
, U(header
).EmfHeader
.szlDevice
.cy
/ (REAL
)U(header
).EmfHeader
.szlMillimeters
.cy
* 25.4);
952 expect(100, header
.Width
);
953 expect(100, header
.Height
);
954 expect(0, header
.EmfPlusHeaderSize
);
955 expect(0, header
.LogicalDpiX
);
956 expect(0, header
.LogicalDpiX
);
957 expect(EMR_HEADER
, U(header
).EmfHeader
.iType
);
958 expect(25, U(header
).EmfHeader
.rclBounds
.left
);
959 expect(25, U(header
).EmfHeader
.rclBounds
.top
);
960 expect(74, U(header
).EmfHeader
.rclBounds
.right
);
961 expect(74, U(header
).EmfHeader
.rclBounds
.bottom
);
962 expect(0, U(header
).EmfHeader
.rclFrame
.left
);
963 expect(0, U(header
).EmfHeader
.rclFrame
.top
);
964 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.right
* xres
/ 2540.0, 2.0);
965 expectf_(100.0, U(header
).EmfHeader
.rclFrame
.bottom
* yres
/ 2540.0, 2.0);
967 stat
= GdipDisposeImage((GpImage
*)metafile
);
970 /* test drawing to metafile with gdi+ functions */
971 hdc
= CreateCompatibleDC(0);
973 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
981 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
984 stat
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
986 stat
= GdipDrawLineI(graphics
, pen
, 0, 0, 10, 10);
987 todo_wine
expect(Ok
, stat
);
990 stat
= GdipDeleteGraphics(graphics
);
993 check_metafile(metafile
, emfonly_draw_records
, "emfonly draw metafile", dst_points
, &frame
, UnitPixel
);
994 sync_metafile(&metafile
, "emfonly_draw.emf");
996 stat
= GdipDisposeImage((GpImage
*)metafile
);
1000 static const emfplus_record fillrect_records
[] = {
1002 {0, EmfPlusRecordTypeHeader
},
1003 {0, EmfPlusRecordTypeFillRects
},
1004 {0, EmfPlusRecordTypeEndOfFile
},
1009 static void test_fillrect(void)
1012 GpMetafile
*metafile
;
1013 GpGraphics
*graphics
;
1016 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
1017 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1018 static const GpPointF dst_points_half
[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
1019 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1024 hdc
= CreateCompatibleDC(0);
1026 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
1034 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
1035 expect(InvalidParameter
, stat
);
1037 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1040 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
1043 stat
= GdipFillRectangleI(graphics
, brush
, 25, 25, 75, 75);
1046 stat
= GdipDeleteBrush(brush
);
1049 stat
= GdipDeleteGraphics(graphics
);
1052 check_metafile(metafile
, fillrect_records
, "fillrect metafile", dst_points
, &frame
, UnitPixel
);
1054 sync_metafile(&metafile
, "fillrect.emf");
1056 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
1059 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1062 play_metafile(metafile
, graphics
, fillrect_records
, "fillrect playback", dst_points
, &frame
, UnitPixel
);
1064 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
1068 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
1070 expect(0xff0000ff, color
);
1072 stat
= GdipBitmapSetPixel(bitmap
, 50, 50, 0);
1075 play_metafile(metafile
, graphics
, fillrect_records
, "fillrect playback", dst_points_half
, &frame
, UnitPixel
);
1077 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
1079 expect(0xff0000ff, color
);
1081 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
1085 stat
= GdipBitmapSetPixel(bitmap
, 15, 15, 0);
1088 stat
= GdipDrawImagePointsRect(graphics
, (GpImage
*)metafile
, dst_points
, 3,
1089 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
1092 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
1096 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
1098 expect(0xff0000ff, color
);
1100 stat
= GdipDeleteGraphics(graphics
);
1103 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1106 stat
= GdipDisposeImage((GpImage
*)metafile
);
1110 static const emfplus_record clear_emf_records
[] = {
1112 {0, EmfPlusRecordTypeHeader
},
1113 {0, EmfPlusRecordTypeClear
},
1115 {1, EMR_SETICMMODE
},
1118 {0, EmfPlusRecordTypeEndOfFile
},
1123 static void test_clear(void)
1126 GpMetafile
*metafile
;
1127 GpGraphics
*graphics
;
1130 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
1131 static const GpPointF dst_points
[3] = {{10.0,10.0},{20.0,10.0},{10.0,20.0}};
1132 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1136 hdc
= CreateCompatibleDC(0);
1138 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
1146 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
1147 expect(InvalidParameter
, stat
);
1149 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1152 stat
= GdipGraphicsClear(graphics
, 0xffffff00);
1155 stat
= GdipDeleteGraphics(graphics
);
1158 sync_metafile(&metafile
, "clear.emf");
1160 stat
= GdipCreateBitmapFromScan0(30, 30, 0, PixelFormat32bppRGB
, NULL
, &bitmap
);
1163 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1166 stat
= GdipDrawImagePointsRect(graphics
, (GpImage
*)metafile
, dst_points
, 3,
1167 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
1170 stat
= GdipBitmapGetPixel(bitmap
, 5, 5, &color
);
1172 expect(0xff000000, color
);
1174 stat
= GdipBitmapGetPixel(bitmap
, 15, 15, &color
);
1176 expect(0xffffff00, color
);
1178 stat
= GdipBitmapGetPixel(bitmap
, 25, 25, &color
);
1180 expect(0xff000000, color
);
1182 stat
= GdipDeleteGraphics(graphics
);
1185 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1188 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
1191 stat
= GdipDisposeImage((GpImage
*)metafile
);
1194 check_emfplus(hemf
, clear_emf_records
, "clear emf");
1196 DeleteEnhMetaFile(hemf
);
1199 static void test_nullframerect(void) {
1201 GpMetafile
*metafile
;
1202 GpGraphics
*graphics
;
1203 HDC hdc
, metafile_dc
;
1204 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1206 HBRUSH hbrush
, holdbrush
;
1210 hdc
= CreateCompatibleDC(0);
1212 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, NULL
, MetafileFrameUnitPixel
, description
, &metafile
);
1220 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
1222 expect(UnitPixel
, unit
);
1223 expectf(0.0, bounds
.X
);
1224 expectf(0.0, bounds
.Y
);
1225 ok(bounds
.Width
== 1.0 || broken(bounds
.Width
== 0.0) /* xp sp1 */,
1226 "expected 1.0, got %f\n", bounds
.Width
);
1227 ok(bounds
.Height
== 1.0 || broken(bounds
.Height
== 0.0) /* xp sp1 */,
1228 "expected 1.0, got %f\n", bounds
.Height
);
1230 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1233 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
1236 stat
= GdipFillRectangleI(graphics
, brush
, 25, 25, 75, 75);
1239 stat
= GdipDeleteBrush(brush
);
1242 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
1244 expect(UnitPixel
, unit
);
1245 expectf(0.0, bounds
.X
);
1246 expectf(0.0, bounds
.Y
);
1247 ok(bounds
.Width
== 1.0 || broken(bounds
.Width
== 0.0) /* xp sp1 */,
1248 "expected 1.0, got %f\n", bounds
.Width
);
1249 ok(bounds
.Height
== 1.0 || broken(bounds
.Height
== 0.0) /* xp sp1 */,
1250 "expected 1.0, got %f\n", bounds
.Height
);
1252 stat
= GdipDeleteGraphics(graphics
);
1255 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
1257 expect(UnitPixel
, unit
);
1258 expectf_(25.0, bounds
.X
, 0.05);
1259 expectf_(25.0, bounds
.Y
, 0.05);
1260 expectf_(75.0, bounds
.Width
, 0.05);
1261 expectf_(75.0, bounds
.Height
, 0.05);
1263 stat
= GdipDisposeImage((GpImage
*)metafile
);
1266 hdc
= CreateCompatibleDC(0);
1268 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, NULL
, MetafileFrameUnitMillimeter
, description
, &metafile
);
1273 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1276 stat
= GdipGetDC(graphics
, &metafile_dc
);
1281 GdipDeleteGraphics(graphics
);
1282 GdipDisposeImage((GpImage
*)metafile
);
1286 hbrush
= CreateSolidBrush(0xff0000);
1288 holdbrush
= SelectObject(metafile_dc
, hbrush
);
1290 Rectangle(metafile_dc
, 25, 25, 75, 75);
1292 SelectObject(metafile_dc
, holdbrush
);
1294 DeleteObject(hbrush
);
1296 stat
= GdipReleaseDC(graphics
, metafile_dc
);
1299 stat
= GdipDeleteGraphics(graphics
);
1302 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
1304 expect(UnitPixel
, unit
);
1305 expectf_(25.0, bounds
.X
, 0.05);
1306 expectf_(25.0, bounds
.Y
, 0.05);
1307 todo_wine
expectf_(50.0, bounds
.Width
, 0.05);
1308 todo_wine
expectf_(50.0, bounds
.Height
, 0.05);
1310 stat
= GdipDisposeImage((GpImage
*)metafile
);
1314 static const emfplus_record pagetransform_records
[] = {
1316 {0, EmfPlusRecordTypeHeader
},
1317 {0, EmfPlusRecordTypeFillRects
},
1318 {0, EmfPlusRecordTypeSetPageTransform
},
1319 {0, EmfPlusRecordTypeFillRects
},
1320 {0, EmfPlusRecordTypeSetPageTransform
},
1321 {0, EmfPlusRecordTypeFillRects
},
1322 {0, EmfPlusRecordTypeSetPageTransform
},
1323 {0, EmfPlusRecordTypeFillRects
},
1324 {0, EmfPlusRecordTypeSetPageTransform
},
1325 {0, EmfPlusRecordTypeFillRects
},
1326 {0, EmfPlusRecordTypeEndOfFile
},
1331 static void test_pagetransform(void)
1334 GpMetafile
*metafile
;
1335 GpGraphics
*graphics
;
1337 static const GpRectF frame
= {0.0, 0.0, 5.0, 5.0};
1338 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1339 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1344 REAL scale
, dpix
, dpiy
;
1347 hdc
= CreateCompatibleDC(0);
1349 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitInch
, description
, &metafile
);
1357 stat
= GdipGetImageHorizontalResolution((GpImage
*)metafile
, &dpix
);
1358 todo_wine
expect(InvalidParameter
, stat
);
1360 stat
= GdipGetImageVerticalResolution((GpImage
*)metafile
, &dpiy
);
1361 todo_wine
expect(InvalidParameter
, stat
);
1363 stat
= GdipGetImageWidth((GpImage
*)metafile
, &width
);
1364 todo_wine
expect(InvalidParameter
, stat
);
1366 stat
= GdipGetImageHeight((GpImage
*)metafile
, &height
);
1367 todo_wine
expect(InvalidParameter
, stat
);
1369 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1373 stat
= GdipGetPageUnit(graphics
, &unit
);
1375 expect(UnitDisplay
, unit
);
1377 stat
= GdipGetPageScale(graphics
, &scale
);
1379 expectf(1.0, scale
);
1381 stat
= GdipGetDpiX(graphics
, &dpix
);
1383 expectf(96.0, dpix
);
1385 stat
= GdipGetDpiY(graphics
, &dpiy
);
1387 expectf(96.0, dpiy
);
1389 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
1392 stat
= GdipFillRectangleI(graphics
, brush
, 1, 2, 1, 1);
1395 stat
= GdipDeleteBrush(brush
);
1398 /* page unit = pixels */
1399 stat
= GdipSetPageUnit(graphics
, UnitPixel
);
1402 stat
= GdipGetPageUnit(graphics
, &unit
);
1404 expect(UnitPixel
, unit
);
1406 stat
= GdipCreateSolidFill((ARGB
)0xff00ff00, (GpSolidFill
**)&brush
);
1409 stat
= GdipFillRectangleI(graphics
, brush
, 0, 1, 1, 1);
1412 stat
= GdipDeleteBrush(brush
);
1415 /* page scale = 3, unit = pixels */
1416 stat
= GdipSetPageScale(graphics
, 3.0);
1419 stat
= GdipGetPageScale(graphics
, &scale
);
1421 expectf(3.0, scale
);
1423 stat
= GdipCreateSolidFill((ARGB
)0xff00ffff, (GpSolidFill
**)&brush
);
1426 stat
= GdipFillRectangleI(graphics
, brush
, 0, 1, 2, 2);
1429 stat
= GdipDeleteBrush(brush
);
1432 /* page scale = 3, unit = inches */
1433 stat
= GdipSetPageUnit(graphics
, UnitInch
);
1436 stat
= GdipGetPageUnit(graphics
, &unit
);
1438 expect(UnitInch
, unit
);
1440 stat
= GdipCreateSolidFill((ARGB
)0xffff0000, (GpSolidFill
**)&brush
);
1443 stat
= GdipFillRectangle(graphics
, brush
, 1.0/96.0, 0, 1, 1);
1446 stat
= GdipDeleteBrush(brush
);
1449 /* page scale = 3, unit = display */
1450 stat
= GdipSetPageUnit(graphics
, UnitDisplay
);
1453 stat
= GdipGetPageUnit(graphics
, &unit
);
1455 expect(UnitDisplay
, unit
);
1457 stat
= GdipCreateSolidFill((ARGB
)0xffff00ff, (GpSolidFill
**)&brush
);
1460 stat
= GdipFillRectangle(graphics
, brush
, 3, 3, 2, 2);
1463 stat
= GdipDeleteBrush(brush
);
1466 stat
= GdipDeleteGraphics(graphics
);
1469 check_metafile(metafile
, pagetransform_records
, "pagetransform metafile", dst_points
, &frame
, UnitPixel
);
1471 sync_metafile(&metafile
, "pagetransform.emf");
1473 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
1476 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1479 play_metafile(metafile
, graphics
, pagetransform_records
, "pagetransform playback", dst_points
, &frame
, UnitPixel
);
1481 stat
= GdipBitmapGetPixel(bitmap
, 50, 50, &color
);
1485 stat
= GdipBitmapGetPixel(bitmap
, 30, 50, &color
);
1487 expect(0xff0000ff, color
);
1489 stat
= GdipBitmapGetPixel(bitmap
, 10, 30, &color
);
1491 expect(0xff00ff00, color
);
1493 stat
= GdipBitmapGetPixel(bitmap
, 20, 80, &color
);
1495 expect(0xff00ffff, color
);
1497 stat
= GdipBitmapGetPixel(bitmap
, 80, 20, &color
);
1499 expect(0xffff0000, color
);
1501 stat
= GdipBitmapGetPixel(bitmap
, 80, 80, &color
);
1503 expect(0xffff00ff, color
);
1505 stat
= GdipDeleteGraphics(graphics
);
1508 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1511 stat
= GdipDisposeImage((GpImage
*)metafile
);
1515 static const emfplus_record worldtransform_records
[] = {
1517 {0, EmfPlusRecordTypeHeader
},
1518 {0, EmfPlusRecordTypeFillRects
},
1519 {0, EmfPlusRecordTypeScaleWorldTransform
},
1520 {0, EmfPlusRecordTypeFillRects
},
1521 {0, EmfPlusRecordTypeResetWorldTransform
},
1522 {0, EmfPlusRecordTypeFillRects
},
1523 {0, EmfPlusRecordTypeMultiplyWorldTransform
},
1524 {0, EmfPlusRecordTypeFillRects
},
1525 {0, EmfPlusRecordTypeRotateWorldTransform
},
1526 {0, EmfPlusRecordTypeFillRects
},
1527 {0, EmfPlusRecordTypeSetWorldTransform
},
1528 {0, EmfPlusRecordTypeFillRects
},
1529 {0, EmfPlusRecordTypeTranslateWorldTransform
},
1530 {0, EmfPlusRecordTypeFillRects
},
1531 {0, EmfPlusRecordTypeEndOfFile
},
1536 static void test_worldtransform(void)
1539 GpMetafile
*metafile
;
1540 GpGraphics
*graphics
;
1542 static const GpRectF frame
= {0.0, 0.0, 5.0, 5.0};
1543 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1544 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1548 GpMatrix
*transform
;
1552 hdc
= CreateCompatibleDC(0);
1554 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
1562 stat
= GdipCreateMatrix(&transform
);
1565 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1568 /* initial transform */
1569 stat
= GdipGetWorldTransform(graphics
, transform
);
1572 stat
= GdipIsMatrixIdentity(transform
, &identity
);
1574 expect(TRUE
, identity
);
1576 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
1579 stat
= GdipFillRectangleI(graphics
, brush
, 0, 0, 1, 1);
1582 stat
= GdipDeleteBrush(brush
);
1585 /* scale transform */
1586 stat
= GdipScaleWorldTransform(graphics
, 2.0, 4.0, MatrixOrderPrepend
);
1589 stat
= GdipGetWorldTransform(graphics
, transform
);
1592 stat
= GdipGetMatrixElements(transform
, elements
);
1594 expectf(2.0, elements
[0]);
1595 expectf(0.0, elements
[1]);
1596 expectf(0.0, elements
[2]);
1597 expectf(4.0, elements
[3]);
1598 expectf(0.0, elements
[4]);
1599 expectf(0.0, elements
[5]);
1601 stat
= GdipCreateSolidFill((ARGB
)0xff00ff00, (GpSolidFill
**)&brush
);
1604 stat
= GdipFillRectangle(graphics
, brush
, 0.5, 0.5, 0.5, 0.25);
1607 stat
= GdipDeleteBrush(brush
);
1610 /* reset transform */
1611 stat
= GdipResetWorldTransform(graphics
);
1614 stat
= GdipGetWorldTransform(graphics
, transform
);
1617 stat
= GdipIsMatrixIdentity(transform
, &identity
);
1619 expect(TRUE
, identity
);
1621 stat
= GdipCreateSolidFill((ARGB
)0xff00ffff, (GpSolidFill
**)&brush
);
1624 stat
= GdipFillRectangle(graphics
, brush
, 1.0, 0.0, 1.0, 1.0);
1627 stat
= GdipDeleteBrush(brush
);
1630 /* multiply transform */
1631 stat
= GdipSetMatrixElements(transform
, 2.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1634 stat
= GdipMultiplyWorldTransform(graphics
, transform
, MatrixOrderPrepend
);
1637 stat
= GdipGetWorldTransform(graphics
, transform
);
1640 stat
= GdipGetMatrixElements(transform
, elements
);
1642 expectf(2.0, elements
[0]);
1643 expectf(0.0, elements
[1]);
1644 expectf(0.0, elements
[2]);
1645 expectf(1.0, elements
[3]);
1646 expectf(0.0, elements
[4]);
1647 expectf(0.0, elements
[5]);
1649 stat
= GdipCreateSolidFill((ARGB
)0xffff0000, (GpSolidFill
**)&brush
);
1652 stat
= GdipFillRectangle(graphics
, brush
, 1.0, 1.0, 0.5, 1.0);
1655 stat
= GdipDeleteBrush(brush
);
1658 /* rotate transform */
1659 stat
= GdipRotateWorldTransform(graphics
, 90.0, MatrixOrderAppend
);
1662 stat
= GdipGetWorldTransform(graphics
, transform
);
1665 stat
= GdipGetMatrixElements(transform
, elements
);
1667 expectf(0.0, elements
[0]);
1668 expectf(2.0, elements
[1]);
1669 expectf(-1.0, elements
[2]);
1670 expectf(0.0, elements
[3]);
1671 expectf(0.0, elements
[4]);
1672 expectf(0.0, elements
[5]);
1674 stat
= GdipCreateSolidFill((ARGB
)0xffff00ff, (GpSolidFill
**)&brush
);
1677 stat
= GdipFillRectangle(graphics
, brush
, 1.0, -1.0, 0.5, 1.0);
1680 stat
= GdipDeleteBrush(brush
);
1684 stat
= GdipSetMatrixElements(transform
, 1.0, 0.0, 0.0, 3.0, 0.0, 0.0);
1687 stat
= GdipSetWorldTransform(graphics
, transform
);
1690 stat
= GdipGetWorldTransform(graphics
, transform
);
1693 stat
= GdipGetMatrixElements(transform
, elements
);
1695 expectf(1.0, elements
[0]);
1696 expectf(0.0, elements
[1]);
1697 expectf(0.0, elements
[2]);
1698 expectf(3.0, elements
[3]);
1699 expectf(0.0, elements
[4]);
1700 expectf(0.0, elements
[5]);
1702 stat
= GdipCreateSolidFill((ARGB
)0xffffff00, (GpSolidFill
**)&brush
);
1705 stat
= GdipFillRectangle(graphics
, brush
, 1.0, 1.0, 1.0, 1.0);
1708 stat
= GdipDeleteBrush(brush
);
1711 /* translate transform */
1712 stat
= GdipTranslateWorldTransform(graphics
, -1.0, 0.0, MatrixOrderAppend
);
1715 stat
= GdipGetWorldTransform(graphics
, transform
);
1718 stat
= GdipGetMatrixElements(transform
, elements
);
1720 expectf(1.0, elements
[0]);
1721 expectf(0.0, elements
[1]);
1722 expectf(0.0, elements
[2]);
1723 expectf(3.0, elements
[3]);
1724 expectf(-1.0, elements
[4]);
1725 expectf(0.0, elements
[5]);
1727 stat
= GdipCreateSolidFill((ARGB
)0xffffffff, (GpSolidFill
**)&brush
);
1730 stat
= GdipFillRectangle(graphics
, brush
, 1.0, 1.0, 1.0, 1.0);
1733 stat
= GdipDeleteBrush(brush
);
1736 stat
= GdipDeleteMatrix(transform
);
1739 stat
= GdipDeleteGraphics(graphics
);
1742 check_metafile(metafile
, worldtransform_records
, "worldtransform metafile", dst_points
, &frame
, UnitPixel
);
1744 sync_metafile(&metafile
, "worldtransform.emf");
1746 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
1749 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1752 play_metafile(metafile
, graphics
, worldtransform_records
, "worldtransform playback", dst_points
, &frame
, UnitPixel
);
1754 stat
= GdipBitmapGetPixel(bitmap
, 80, 80, &color
);
1758 stat
= GdipBitmapGetPixel(bitmap
, 10, 10, &color
);
1760 expect(0xff0000ff, color
);
1762 stat
= GdipBitmapGetPixel(bitmap
, 30, 50, &color
);
1764 expect(0xff00ff00, color
);
1766 stat
= GdipBitmapGetPixel(bitmap
, 30, 10, &color
);
1768 expect(0xff00ffff, color
);
1770 stat
= GdipBitmapGetPixel(bitmap
, 50, 30, &color
);
1772 expect(0xffff0000, color
);
1774 stat
= GdipBitmapGetPixel(bitmap
, 10, 50, &color
);
1776 expect(0xffff00ff, color
);
1778 stat
= GdipBitmapGetPixel(bitmap
, 30, 90, &color
);
1780 expect(0xffffff00, color
);
1782 stat
= GdipBitmapGetPixel(bitmap
, 10, 90, &color
);
1784 expect(0xffffffff, color
);
1786 stat
= GdipDeleteGraphics(graphics
);
1789 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1792 stat
= GdipDisposeImage((GpImage
*)metafile
);
1796 static void test_converttoemfplus(void)
1798 GpStatus (WINAPI
*pGdipConvertToEmfPlus
)( const GpGraphics
*graphics
, GpMetafile
*metafile
, BOOL
*succ
,
1799 EmfType emfType
, const WCHAR
*description
, GpMetafile
**outmetafile
);
1800 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
1801 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1803 GpMetafile
*metafile
, *metafile2
= NULL
, *emhmeta
;
1804 GpGraphics
*graphics
;
1807 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
1809 pGdipConvertToEmfPlus
= (void*)GetProcAddress( mod
, "GdipConvertToEmfPlus");
1810 if(!pGdipConvertToEmfPlus
)
1812 /* GdipConvertToEmfPlus was introduced in Windows Vista. */
1813 win_skip("GDIPlus version 1.1 not available\n");
1817 hdc
= CreateCompatibleDC(0);
1819 stat
= GdipRecordMetafile(hdc
, MetafileTypeEmf
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
1822 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &emhmeta
);
1830 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1833 /* Invalid Parameters */
1834 stat
= pGdipConvertToEmfPlus(NULL
, metafile
, &succ
, EmfTypeEmfPlusOnly
, description
, &metafile2
);
1835 expect(InvalidParameter
, stat
);
1837 stat
= pGdipConvertToEmfPlus(graphics
, NULL
, &succ
, EmfTypeEmfPlusOnly
, description
, &metafile2
);
1838 expect(InvalidParameter
, stat
);
1840 stat
= pGdipConvertToEmfPlus(graphics
, metafile
, &succ
, EmfTypeEmfPlusOnly
, description
, NULL
);
1841 expect(InvalidParameter
, stat
);
1843 stat
= pGdipConvertToEmfPlus(graphics
, metafile
, NULL
, MetafileTypeInvalid
, NULL
, &metafile2
);
1844 expect(InvalidParameter
, stat
);
1846 stat
= pGdipConvertToEmfPlus(graphics
, metafile
, NULL
, MetafileTypeEmfPlusDual
+1, NULL
, &metafile2
);
1847 expect(InvalidParameter
, stat
);
1849 /* If we are already an Enhanced Metafile then the conversion fails. */
1850 stat
= pGdipConvertToEmfPlus(graphics
, emhmeta
, NULL
, EmfTypeEmfPlusOnly
, NULL
, &metafile2
);
1851 todo_wine
expect(InvalidParameter
, stat
);
1853 stat
= pGdipConvertToEmfPlus(graphics
, metafile
, NULL
, EmfTypeEmfPlusOnly
, NULL
, &metafile2
);
1854 todo_wine
expect(Ok
, stat
);
1856 GdipDisposeImage((GpImage
*)metafile2
);
1859 stat
= pGdipConvertToEmfPlus(graphics
, metafile
, &succ
, EmfTypeEmfPlusOnly
, NULL
, &metafile2
);
1860 todo_wine
expect(Ok
, stat
);
1862 GdipDisposeImage((GpImage
*)metafile2
);
1864 stat
= GdipDeleteGraphics(graphics
);
1867 stat
= GdipDisposeImage((GpImage
*)metafile
);
1870 stat
= GdipDisposeImage((GpImage
*)emhmeta
);
1874 static void test_frameunit(void)
1877 GpMetafile
*metafile
;
1878 GpGraphics
*graphics
;
1880 static const GpRectF frame
= {0.0, 0.0, 5.0, 5.0};
1881 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1886 hdc
= CreateCompatibleDC(0);
1888 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitInch
, description
, &metafile
);
1896 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
1898 expect(UnitPixel
, unit
);
1899 expectf(0.0, bounds
.X
);
1900 expectf(0.0, bounds
.Y
);
1901 ok(bounds
.Width
== 1.0 || broken(bounds
.Width
== 0.0) /* xp sp1 */,
1902 "expected 1.0, got %f\n", bounds
.Width
);
1903 ok(bounds
.Height
== 1.0 || broken(bounds
.Height
== 0.0) /* xp sp1 */,
1904 "expected 1.0, got %f\n", bounds
.Height
);
1906 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1909 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
1911 expect(UnitPixel
, unit
);
1912 expectf(0.0, bounds
.X
);
1913 expectf(0.0, bounds
.Y
);
1914 ok(bounds
.Width
== 1.0 || broken(bounds
.Width
== 0.0) /* xp sp1 */,
1915 "expected 1.0, got %f\n", bounds
.Width
);
1916 ok(bounds
.Height
== 1.0 || broken(bounds
.Height
== 0.0) /* xp sp1 */,
1917 "expected 1.0, got %f\n", bounds
.Height
);
1919 stat
= GdipDeleteGraphics(graphics
);
1922 stat
= GdipGetImageHorizontalResolution((GpImage
*)metafile
, &dpix
);
1925 stat
= GdipGetImageVerticalResolution((GpImage
*)metafile
, &dpiy
);
1928 stat
= GdipGetImageBounds((GpImage
*)metafile
, &bounds
, &unit
);
1930 expect(UnitPixel
, unit
);
1931 expectf(0.0, bounds
.X
);
1932 expectf(0.0, bounds
.Y
);
1933 expectf_(5.0 * dpix
, bounds
.Width
, 1.0);
1934 expectf_(5.0 * dpiy
, bounds
.Height
, 1.0);
1936 stat
= GdipDisposeImage((GpImage
*)metafile
);
1940 static const emfplus_record container_records
[] = {
1942 {0, EmfPlusRecordTypeHeader
},
1943 {0, EmfPlusRecordTypeBeginContainerNoParams
},
1944 {0, EmfPlusRecordTypeScaleWorldTransform
},
1945 {0, EmfPlusRecordTypeFillRects
},
1946 {0, EmfPlusRecordTypeEndContainer
},
1947 {0, EmfPlusRecordTypeScaleWorldTransform
},
1948 {0, EmfPlusRecordTypeFillRects
},
1949 {0, EmfPlusRecordTypeSave
},
1950 {0, EmfPlusRecordTypeRestore
},
1951 {0, EmfPlusRecordTypeScaleWorldTransform
},
1952 {0, EmfPlusRecordTypeBeginContainerNoParams
},
1953 {0, EmfPlusRecordTypeScaleWorldTransform
},
1954 {0, EmfPlusRecordTypeBeginContainerNoParams
},
1955 {0, EmfPlusRecordTypeEndContainer
},
1956 {0, EmfPlusRecordTypeFillRects
},
1957 {0, EmfPlusRecordTypeBeginContainer
},
1958 {0, EmfPlusRecordTypeFillRects
},
1959 {0, EmfPlusRecordTypeEndContainer
},
1960 {0, EmfPlusRecordTypeBeginContainerNoParams
},
1961 {0, EmfPlusRecordTypeEndOfFile
},
1966 static void test_containers(void)
1969 GpMetafile
*metafile
;
1970 GpGraphics
*graphics
;
1975 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
1976 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1977 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
1978 GraphicsContainer state1
, state2
;
1979 GpRectF srcrect
, dstrect
;
1982 hdc
= CreateCompatibleDC(0);
1984 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
1992 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
1996 stat
= GdipBeginContainer2(graphics
, &state1
);
1999 stat
= GdipScaleWorldTransform(graphics
, 2.0, 2.0, MatrixOrderPrepend
);
2002 stat
= GdipCreateSolidFill((ARGB
)0xff000000, (GpSolidFill
**)&brush
);
2005 stat
= GdipFillRectangle(graphics
, brush
, 5.0, 5.0, 5.0, 5.0);
2008 stat
= GdipDeleteBrush(brush
);
2011 stat
= GdipEndContainer(graphics
, state1
);
2014 stat
= GdipScaleWorldTransform(graphics
, 1.0, 1.0, MatrixOrderPrepend
);
2017 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
2020 stat
= GdipFillRectangle(graphics
, brush
, 5.0, 5.0, 5.0, 5.0);
2023 stat
= GdipDeleteBrush(brush
);
2026 stat
= GdipSaveGraphics(graphics
, &state1
);
2029 stat
= GdipRestoreGraphics(graphics
, state1
);
2032 /* Popping two states at once */
2033 stat
= GdipScaleWorldTransform(graphics
, 2.0, 2.0, MatrixOrderPrepend
);
2036 stat
= GdipBeginContainer2(graphics
, &state1
);
2039 stat
= GdipScaleWorldTransform(graphics
, 4.0, 4.0, MatrixOrderPrepend
);
2042 stat
= GdipBeginContainer2(graphics
, &state2
);
2045 stat
= GdipEndContainer(graphics
, state1
);
2048 stat
= GdipCreateSolidFill((ARGB
)0xff00ff00, (GpSolidFill
**)&brush
);
2051 stat
= GdipFillRectangle(graphics
, brush
, 20.0, 20.0, 5.0, 5.0);
2054 stat
= GdipDeleteBrush(brush
);
2057 /* With transform applied */
2058 stat
= GdipGetDpiX(graphics
, &dpix
);
2061 stat
= GdipGetDpiY(graphics
, &dpiy
);
2066 srcrect
.Width
= 1.0;
2067 srcrect
.Height
= 1.0;
2071 dstrect
.Width
= 5.0;
2072 dstrect
.Height
= 5.0;
2074 stat
= GdipBeginContainer(graphics
, &dstrect
, &srcrect
, UnitInch
, &state1
);
2077 stat
= GdipCreateSolidFill((ARGB
)0xff00ffff, (GpSolidFill
**)&brush
);
2080 stat
= GdipFillRectangle(graphics
, brush
, 0.0, 0.0, dpix
, dpiy
);
2083 stat
= GdipDeleteBrush(brush
);
2086 stat
= GdipEndContainer(graphics
, state1
);
2089 /* Restoring an invalid state seems to break the graphics object? */
2091 stat
= GdipEndContainer(graphics
, state1
);
2095 /* Ending metafile with a state open */
2096 stat
= GdipBeginContainer2(graphics
, &state1
);
2099 stat
= GdipDeleteGraphics(graphics
);
2102 check_metafile(metafile
, container_records
, "container metafile", dst_points
, &frame
, UnitPixel
);
2104 sync_metafile(&metafile
, "container.emf");
2106 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
2109 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
2112 play_metafile(metafile
, graphics
, container_records
, "container playback", dst_points
, &frame
, UnitPixel
);
2114 stat
= GdipBitmapGetPixel(bitmap
, 80, 80, &color
);
2118 stat
= GdipBitmapGetPixel(bitmap
, 12, 12, &color
);
2120 expect(0xff000000, color
);
2122 stat
= GdipBitmapGetPixel(bitmap
, 8, 8, &color
);
2124 expect(0xff0000ff, color
);
2126 stat
= GdipBitmapGetPixel(bitmap
, 42, 42, &color
);
2128 expect(0xff00ff00, color
);
2130 stat
= GdipBitmapGetPixel(bitmap
, 55, 5, &color
);
2132 expect(0xff00ffff, color
);
2134 stat
= GdipDeleteGraphics(graphics
);
2137 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2140 stat
= GdipDisposeImage((GpImage
*)metafile
);
2144 static const emfplus_record clipping_records
[] = {
2146 {0, EmfPlusRecordTypeHeader
},
2147 {0, EmfPlusRecordTypeSave
},
2148 {0, EmfPlusRecordTypeSetClipRect
},
2149 {0, EmfPlusRecordTypeFillRects
},
2150 {0, EmfPlusRecordTypeRestore
},
2151 {0, EmfPlusRecordTypeSetClipRect
},
2152 {0, EmfPlusRecordTypeFillRects
},
2153 {0, EmfPlusRecordTypeObject
, 1},
2154 {0, EmfPlusRecordTypeSetClipRegion
, 1},
2155 {0, EmfPlusRecordTypeEndOfFile
},
2160 static void test_clipping(void)
2163 GpMetafile
*metafile
;
2164 GpGraphics
*graphics
;
2171 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
2172 static const GpPointF dst_points
[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
2173 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
2174 GraphicsState state
;
2176 hdc
= CreateCompatibleDC(0);
2178 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
2186 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
2189 stat
= GdipSaveGraphics(graphics
, &state
);
2192 stat
= GdipGetVisibleClipBounds(graphics
, &rect
);
2194 ok(rect
.X
== -0x400000, "rect.X = %f\n", rect
.X
);
2195 ok(rect
.Y
== -0x400000, "rect.Y = %f\n", rect
.Y
);
2196 ok(rect
.Width
== 0x800000, "rect.Width = %f\n", rect
.Width
);
2197 ok(rect
.Height
== 0x800000, "rect.Height = %f\n", rect
.Height
);
2199 stat
= GdipSetClipRect(graphics
, 30, 30, 10, 10, CombineModeReplace
);
2202 stat
= GdipGetVisibleClipBounds(graphics
, &rect
);
2204 ok(rect
.X
== 30, "rect.X = %f\n", rect
.X
);
2205 ok(rect
.Y
== 30, "rect.Y = %f\n", rect
.Y
);
2206 ok(rect
.Width
== 10, "rect.Width = %f\n", rect
.Width
);
2207 ok(rect
.Height
== 10, "rect.Height = %f\n", rect
.Height
);
2209 stat
= GdipCreateSolidFill((ARGB
)0xff000000, (GpSolidFill
**)&brush
);
2212 stat
= GdipFillRectangle(graphics
, brush
, 0, 0, 100, 100);
2215 stat
= GdipDeleteBrush(brush
);
2218 stat
= GdipRestoreGraphics(graphics
, state
);
2221 stat
= GdipSetClipRect(graphics
, 30, 30, 10, 10, CombineModeXor
);
2224 stat
= GdipCreateSolidFill((ARGB
)0xff0000ff, (GpSolidFill
**)&brush
);
2227 stat
= GdipFillRectangle(graphics
, brush
, 30, 30, 20, 10);
2230 stat
= GdipDeleteBrush(brush
);
2233 stat
= GdipCreateRegionRect(&rect
, ®ion
);
2236 stat
= GdipSetClipRegion(graphics
, region
, CombineModeIntersect
);
2239 stat
= GdipDeleteRegion(region
);
2242 stat
= GdipDeleteGraphics(graphics
);
2245 check_metafile(metafile
, clipping_records
, "clipping metafile", dst_points
, &frame
, UnitPixel
);
2247 sync_metafile(&metafile
, "clipping.emf");
2249 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
2252 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
2255 play_metafile(metafile
, graphics
, clipping_records
, "clipping playback", dst_points
, &frame
, UnitPixel
);
2257 stat
= GdipBitmapGetPixel(bitmap
, 80, 80, &color
);
2261 stat
= GdipBitmapGetPixel(bitmap
, 35, 35, &color
);
2263 expect(0xff000000, color
);
2265 stat
= GdipBitmapGetPixel(bitmap
, 45, 35, &color
);
2267 expect(0xff0000ff, color
);
2269 stat
= GdipDeleteGraphics(graphics
);
2272 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2275 stat
= GdipDisposeImage((GpImage
*)metafile
);
2279 static void test_gditransform_cb(GpMetafile
* metafile
, EmfPlusRecordType record_type
,
2280 unsigned int flags
, unsigned int dataSize
, const unsigned char *pStr
)
2282 static const XFORM xform
= {0.5, 0, 0, 0.5, 0, 0};
2283 static const RECTL rectangle
= {0,0,100,100};
2286 stat
= GdipPlayMetafileRecord(metafile
, EMR_SETWORLDTRANSFORM
, 0, sizeof(xform
), (void*)&xform
);
2289 stat
= GdipPlayMetafileRecord(metafile
, EMR_RECTANGLE
, 0, sizeof(rectangle
), (void*)&rectangle
);
2293 static const emfplus_record gditransform_records
[] = {
2295 {0, EMR_CREATEBRUSHINDIRECT
},
2296 {0, EMR_SELECTOBJECT
},
2297 {0, EMR_GDICOMMENT
, 0, test_gditransform_cb
},
2298 {0, EMR_SELECTOBJECT
},
2299 {0, EMR_DELETEOBJECT
},
2304 static void test_gditransform(void)
2307 GpMetafile
*metafile
;
2308 GpGraphics
*graphics
;
2309 HDC hdc
, metafile_dc
;
2311 MetafileHeader header
;
2312 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
2313 static const GpPointF dst_points
[3] = {{0.0,0.0},{40.0,0.0},{0.0,40.0}};
2314 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
2315 HBRUSH hbrush
, holdbrush
;
2319 hdc
= CreateCompatibleDC(0);
2321 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
2329 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
2330 expect(InvalidParameter
, stat
);
2332 memset(&header
, 0xaa, sizeof(header
));
2333 stat
= GdipGetMetafileHeaderFromMetafile(metafile
, &header
);
2335 expect(MetafileTypeEmf
, header
.Type
);
2336 ok(header
.Version
== 0xdbc01001 || header
.Version
== 0xdbc01002, "Unexpected version %x\n", header
.Version
);
2338 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
2341 stat
= GdipGetDC(graphics
, &metafile_dc
);
2346 GdipDeleteGraphics(graphics
);
2347 GdipDisposeImage((GpImage
*)metafile
);
2351 hbrush
= CreateSolidBrush(0xff);
2353 holdbrush
= SelectObject(metafile_dc
, hbrush
);
2355 GdiComment(metafile_dc
, 8, (const BYTE
*)"winetest");
2357 SelectObject(metafile_dc
, holdbrush
);
2359 DeleteObject(hbrush
);
2361 stat
= GdipReleaseDC(graphics
, metafile_dc
);
2364 stat
= GdipDeleteGraphics(graphics
);
2367 check_metafile(metafile
, gditransform_records
, "gditransform metafile", dst_points
, &frame
, UnitPixel
);
2369 sync_metafile(&metafile
, "gditransform.emf");
2371 stat
= GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB
, NULL
, &bitmap
);
2374 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
2377 play_metafile(metafile
, graphics
, gditransform_records
, "gditransform playback", dst_points
, &frame
, UnitPixel
);
2379 stat
= GdipBitmapGetPixel(bitmap
, 10, 10, &color
);
2381 expect(0xffff0000, color
);
2383 stat
= GdipBitmapGetPixel(bitmap
, 30, 30, &color
);
2385 expect(0x00000000, color
);
2387 stat
= GdipDeleteGraphics(graphics
);
2390 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2393 stat
= GdipDisposeImage((GpImage
*)metafile
);
2397 static const emfplus_record draw_image_bitmap_records
[] = {
2399 {0, EmfPlusRecordTypeHeader
},
2400 {0, EmfPlusRecordTypeObject
},
2401 {0, EmfPlusRecordTypeObject
},
2402 {0, EmfPlusRecordTypeDrawImagePoints
},
2404 {1, EMR_SETICMMODE
},
2407 {0, EmfPlusRecordTypeEndOfFile
},
2412 static const emfplus_record draw_image_metafile_records
[] = {
2414 {0, EmfPlusRecordTypeHeader
},
2415 {0, EmfPlusRecordTypeObject
},
2416 /* metafile object */
2418 {0, EmfPlusRecordTypeHeader
},
2419 {0, EmfPlusRecordTypeObject
},
2420 {0, EmfPlusRecordTypeObject
},
2421 {0, EmfPlusRecordTypeDrawImagePoints
},
2423 {1, EMR_SETICMMODE
},
2426 {0, EmfPlusRecordTypeEndOfFile
},
2428 /* end of metafile object */
2429 {0, EmfPlusRecordTypeDrawImagePoints
},
2431 {1, EMR_SETICMMODE
},
2434 {0, EmfPlusRecordTypeEndOfFile
},
2439 static void test_drawimage(void)
2441 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
2442 static const GpPointF dst_points
[3] = {{10.0,10.0},{85.0,15.0},{10.0,80.0}};
2443 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
2444 const ColorMatrix double_red
= {{
2445 {2.0,0.0,0.0,0.0,0.0},
2446 {0.0,1.0,0.0,0.0,0.0},
2447 {0.0,0.0,1.0,0.0,0.0},
2448 {0.0,0.0,0.0,1.0,0.0},
2449 {0.0,0.0,0.0,0.0,1.0}}};
2451 GpImageAttributes
*imageattr
;
2452 GpMetafile
*metafile
;
2453 GpGraphics
*graphics
;
2461 hdc
= CreateCompatibleDC(0);
2462 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
2465 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
2468 memset(&info
, 0, sizeof(info
));
2469 info
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
2470 info
.bmiHeader
.biWidth
= 10;
2471 info
.bmiHeader
.biHeight
= 10;
2472 info
.bmiHeader
.biPlanes
= 1;
2473 info
.bmiHeader
.biBitCount
= 32;
2474 info
.bmiHeader
.biCompression
= BI_RGB
;
2475 memset(buff
, 0x80, sizeof(buff
));
2476 stat
= GdipCreateBitmapFromGdiDib(&info
, buff
, (GpBitmap
**)&image
);
2479 stat
= GdipCreateImageAttributes(&imageattr
);
2482 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2483 TRUE
, &double_red
, NULL
, ColorMatrixFlagsDefault
);
2486 stat
= GdipDrawImagePointsRect(graphics
, image
, dst_points
, 3,
2487 0.0, 0.0, 10.0, 10.0, UnitPixel
, imageattr
, NULL
, NULL
);
2488 GdipDisposeImageAttributes(imageattr
);
2491 GdipDisposeImage(image
);
2493 stat
= GdipDeleteGraphics(graphics
);
2495 sync_metafile(&metafile
, "draw_image_bitmap.emf");
2497 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
2500 check_emfplus(hemf
, draw_image_bitmap_records
, "draw image bitmap");
2502 /* test drawing metafile */
2503 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
2506 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
2509 stat
= GdipCreateMetafileFromEmf(hemf
, TRUE
, (GpMetafile
**)&image
);
2512 stat
= GdipDrawImagePointsRect(graphics
, image
, dst_points
, 3,
2513 0.0, 0.0, 100.0, 100.0, UnitPixel
, NULL
, NULL
, NULL
);
2516 GdipDisposeImage(image
);
2518 stat
= GdipDeleteGraphics(graphics
);
2520 sync_metafile(&metafile
, "draw_image_metafile.emf");
2522 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
2525 if (GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipConvertToEmfPlus"))
2527 check_emfplus(hemf
, draw_image_metafile_records
, "draw image metafile");
2531 win_skip("draw image metafile records tests skipped\n");
2533 DeleteEnhMetaFile(hemf
);
2536 stat
= GdipDisposeImage((GpImage
*)metafile
);
2540 static const emfplus_record properties_records
[] = {
2542 {0, EmfPlusRecordTypeHeader
},
2543 {0, EmfPlusRecordTypeSetTextRenderingHint
},
2544 {0, EmfPlusRecordTypeSetPixelOffsetMode
},
2545 {0, EmfPlusRecordTypeSetAntiAliasMode
},
2546 {0, EmfPlusRecordTypeSetCompositingMode
},
2547 {0, EmfPlusRecordTypeSetCompositingQuality
},
2548 {0, EmfPlusRecordTypeSetInterpolationMode
},
2549 {0, EmfPlusRecordTypeEndOfFile
},
2554 static void test_properties(void)
2556 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
2557 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
2559 GpMetafile
*metafile
;
2560 GpGraphics
*graphics
;
2565 hdc
= CreateCompatibleDC(0);
2566 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
2570 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
2573 stat
= GdipSetTextRenderingHint(graphics
, TextRenderingHintSystemDefault
);
2575 stat
= GdipSetTextRenderingHint(graphics
, TextRenderingHintAntiAlias
);
2578 stat
= GdipSetPixelOffsetMode(graphics
, PixelOffsetModeHighQuality
);
2580 stat
= GdipSetPixelOffsetMode(graphics
, PixelOffsetModeHighQuality
);
2583 stat
= GdipSetSmoothingMode(graphics
, SmoothingModeAntiAlias
);
2585 stat
= GdipSetSmoothingMode(graphics
, SmoothingModeAntiAlias
);
2588 stat
= GdipSetCompositingMode(graphics
, CompositingModeSourceOver
);
2590 stat
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
2593 stat
= GdipSetCompositingQuality(graphics
, CompositingQualityHighQuality
);
2595 stat
= GdipSetCompositingQuality(graphics
, CompositingQualityHighQuality
);
2598 stat
= GdipSetInterpolationMode(graphics
, InterpolationModeDefault
);
2600 stat
= GdipSetInterpolationMode(graphics
, InterpolationModeHighQuality
);
2603 stat
= GdipDeleteGraphics(graphics
);
2605 sync_metafile(&metafile
, "properties.emf");
2607 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
2610 check_emfplus(hemf
, properties_records
, "properties");
2611 DeleteEnhMetaFile(hemf
);
2613 stat
= GdipDisposeImage((GpImage
*)metafile
);
2617 static const emfplus_record draw_path_records
[] = {
2619 {0, EmfPlusRecordTypeHeader
},
2620 {0, EmfPlusRecordTypeObject
},
2621 {0, EmfPlusRecordTypeObject
},
2622 {0, EmfPlusRecordTypeDrawPath
},
2624 {1, EMR_SETICMMODE
},
2627 {0, EmfPlusRecordTypeEndOfFile
},
2632 static void test_drawpath(void)
2634 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
2635 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
2637 GpMetafile
*metafile
;
2638 GpGraphics
*graphics
;
2645 hdc
= CreateCompatibleDC(0);
2646 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
2650 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
2653 stat
= GdipCreatePath(FillModeAlternate
, &path
);
2655 stat
= GdipAddPathLine(path
, 5, 5, 30, 30);
2658 stat
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
2661 stat
= GdipDrawPath(graphics
, pen
, path
);
2664 stat
= GdipDeletePen(pen
);
2666 stat
= GdipDeletePath(path
);
2669 stat
= GdipDeleteGraphics(graphics
);
2671 sync_metafile(&metafile
, "draw_path.emf");
2673 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
2676 check_emfplus(hemf
, draw_path_records
, "draw path");
2677 DeleteEnhMetaFile(hemf
);
2679 stat
= GdipDisposeImage((GpImage
*)metafile
);
2683 static const emfplus_record fill_path_records
[] = {
2685 {0, EmfPlusRecordTypeHeader
},
2686 {0, EmfPlusRecordTypeObject
},
2687 {0, EmfPlusRecordTypeFillPath
},
2689 {1, EMR_SETICMMODE
},
2692 {0, EmfPlusRecordTypeEndOfFile
},
2697 static void test_fillpath(void)
2699 static const WCHAR description
[] = {'w','i','n','e','t','e','s','t',0};
2700 static const GpRectF frame
= {0.0, 0.0, 100.0, 100.0};
2701 static const WCHAR winetestemfW
[] = {'w','i','n','e','t','e','s','t','.','e','m','f',0};
2703 GpMetafile
*metafile
;
2704 GpGraphics
*graphics
;
2711 hdc
= CreateCompatibleDC(0);
2712 stat
= GdipRecordMetafile(hdc
, EmfTypeEmfPlusOnly
, &frame
, MetafileFrameUnitPixel
, description
, &metafile
);
2716 stat
= GdipGetImageGraphicsContext((GpImage
*)metafile
, &graphics
);
2719 stat
= GdipCreatePath(FillModeAlternate
, &path
);
2721 stat
= GdipAddPathLine(path
, 5, 5, 30, 30);
2723 stat
= GdipAddPathLine(path
, 30, 30, 5, 30);
2726 stat
= GdipCreateSolidFill(0xffaabbcc, &brush
);
2729 stat
= GdipFillPath(graphics
, (GpBrush
*)brush
, path
);
2732 stat
= GdipDeleteBrush((GpBrush
*)brush
);
2734 stat
= GdipDeletePath(path
);
2737 stat
= GdipDeleteGraphics(graphics
);
2739 sync_metafile(&metafile
, "fill_path.emf");
2741 stat
= GdipGetHemfFromMetafile(metafile
, &hemf
);
2744 check_emfplus(hemf
, fill_path_records
, "fill path");
2747 DeleteEnhMetaFile(CopyEnhMetaFileW(hemf
, winetestemfW
));
2749 DeleteEnhMetaFile(hemf
);
2751 stat
= GdipDisposeImage((GpImage
*)metafile
);
2754 /* should succeed when given path to an EMF */
2755 stat
= GdipCreateMetafileFromWmfFile(winetestemfW
, NULL
, &metafile
);
2758 stat
= GdipDisposeImage((GpImage
*)metafile
);
2761 DeleteFileW(winetestemfW
);
2763 stat
= GdipCreateMetafileFromWmfFile(winetestemfW
, NULL
, &metafile
);
2764 expect(GenericError
, stat
);
2767 START_TEST(metafile
)
2769 struct GdiplusStartupInput gdiplusStartupInput
;
2770 ULONG_PTR gdiplusToken
;
2774 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
2776 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
2777 hmsvcrt
= LoadLibraryA("msvcrt");
2778 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
2779 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
2781 gdiplusStartupInput
.GdiplusVersion
= 1;
2782 gdiplusStartupInput
.DebugEventCallback
= NULL
;
2783 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
2784 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
2786 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
2788 myARGC
= winetest_get_mainargs( &myARGV
);
2792 if (!strcmp(myARGV
[2], "save"))
2793 save_metafiles
= TRUE
;
2794 else if (!strcmp(myARGV
[2], "load"))
2795 load_metafiles
= TRUE
;
2803 test_nullframerect();
2804 test_pagetransform();
2805 test_worldtransform();
2806 test_converttoemfplus();
2810 test_gditransform();
2816 GdiplusShutdown(gdiplusToken
);