[GDIPLUS_WINETEST] Sync with Wine 3.0. CORE-14225
[reactos.git] / modules / rostests / winetests / gdiplus / metafile.c
1 /*
2 * Unit test suite for metafiles
3 *
4 * Copyright (C) 2011 Vincent Povirk for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "precomp.h"
22
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)
26
27 static BOOL save_metafiles;
28 static BOOL load_metafiles;
29
30 typedef struct emfplus_record
31 {
32 DWORD record_type;
33 DWORD flags; /* Used for EMF+ records only. */
34 BOOL todo;
35 BOOL playback_todo;
36 void (*playback_fn)(GpMetafile* metafile, EmfPlusRecordType record_type,
37 unsigned int flags, unsigned int dataSize, const unsigned char *pStr);
38 DWORD broken_flags;
39 } emfplus_record;
40
41 typedef struct emfplus_check_state
42 {
43 const char *desc;
44 int count;
45 const struct emfplus_record *expected;
46 GpMetafile *metafile;
47 } emfplus_check_state;
48
49 static void check_record(int count, const char *desc, const struct emfplus_record *expected, const struct emfplus_record *actual)
50 {
51 if (actual->record_type > GDIP_EMFPLUS_RECORD_BASE)
52 {
53 todo_wine_if (expected->todo)
54 ok(expected->record_type == actual->record_type && (expected->flags == actual->flags ||
55 broken(expected->broken_flags == actual->flags)),
56 "%s.%i: Expected record type 0x%x, got 0x%x. Expected flags %#x, got %#x.\n", desc, count,
57 expected->record_type, actual->record_type, expected->flags, actual->flags);
58 }
59 else
60 {
61 todo_wine_if (expected->todo)
62 ok(expected->record_type == actual->record_type,
63 "%s.%i: Expected record type 0x%x, got 0x%x.\n", desc, count,
64 expected->record_type, actual->record_type);
65 }
66 }
67
68 typedef struct EmfPlusRecordHeader
69 {
70 WORD Type;
71 WORD Flags;
72 DWORD Size;
73 DWORD DataSize;
74 } EmfPlusRecordHeader;
75
76 typedef enum
77 {
78 ObjectTypeInvalid,
79 ObjectTypeBrush,
80 ObjectTypePen,
81 ObjectTypePath,
82 ObjectTypeRegion,
83 ObjectTypeImage,
84 ObjectTypeFont,
85 ObjectTypeStringFormat,
86 ObjectTypeImageAttributes,
87 ObjectTypeCustomLineCap,
88 } ObjectType;
89
90 typedef enum
91 {
92 ImageDataTypeUnknown,
93 ImageDataTypeBitmap,
94 ImageDataTypeMetafile,
95 } ImageDataType;
96
97 typedef struct
98 {
99 EmfPlusRecordHeader Header;
100 /* EmfPlusImage */
101 DWORD Version;
102 ImageDataType Type;
103 /* EmfPlusMetafile */
104 DWORD MetafileType;
105 DWORD MetafileDataSize;
106 BYTE MetafileData[1];
107 } MetafileImageObject;
108
109 static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
110 int nObj, LPARAM lpData)
111 {
112 emfplus_check_state *state = (emfplus_check_state*)lpData;
113 emfplus_record actual;
114
115 if (lpEMFR->iType == EMR_GDICOMMENT)
116 {
117 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
118
119 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
120 {
121 int offset = 4;
122
123 while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
124 {
125 const EmfPlusRecordHeader *record = (const EmfPlusRecordHeader*)&comment->Data[offset];
126
127 ok(record->Size == record->DataSize + sizeof(EmfPlusRecordHeader),
128 "%s: EMF+ record datasize %u and size %u mismatch\n", state->desc, record->DataSize, record->Size);
129
130 ok(offset + record->DataSize <= comment->cbData,
131 "%s: EMF+ record truncated\n", state->desc);
132
133 if (offset + record->DataSize > comment->cbData)
134 return 0;
135
136 if (state->expected[state->count].record_type)
137 {
138 actual.todo = FALSE;
139 actual.record_type = record->Type;
140 actual.flags = record->Flags;
141
142 check_record(state->count, state->desc, &state->expected[state->count], &actual);
143 state->count++;
144
145 if (state->expected[state->count-1].todo && state->expected[state->count-1].record_type != actual.record_type)
146 continue;
147 }
148 else
149 {
150 ok(0, "%s: Unexpected EMF+ 0x%x record\n", state->desc, record->Type);
151 }
152
153 if ((record->Flags >> 8) == ObjectTypeImage && record->Type == EmfPlusRecordTypeObject)
154 {
155 const MetafileImageObject *image = (const MetafileImageObject*)record;
156
157 if (image->Type == ImageDataTypeMetafile)
158 {
159 HENHMETAFILE hemf = SetEnhMetaFileBits(image->MetafileDataSize, image->MetafileData);
160 ok(hemf != NULL, "%s: SetEnhMetaFileBits failed\n", state->desc);
161
162 EnumEnhMetaFile(0, hemf, enum_emf_proc, state, NULL);
163 DeleteEnhMetaFile(hemf);
164 }
165 }
166
167 offset += record->Size;
168 }
169
170 ok(offset == comment->cbData, "%s: truncated EMF+ record data?\n", state->desc);
171
172 return 1;
173 }
174 }
175
176 if (state->expected[state->count].record_type)
177 {
178 actual.todo = FALSE;
179 actual.record_type = lpEMFR->iType;
180 actual.flags = 0;
181
182 check_record(state->count, state->desc, &state->expected[state->count], &actual);
183
184 state->count++;
185 }
186 else
187 {
188 ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, lpEMFR->iType);
189 }
190
191 return 1;
192 }
193
194 static void check_emfplus(HENHMETAFILE hemf, const emfplus_record *expected, const char *desc)
195 {
196 emfplus_check_state state;
197
198 state.desc = desc;
199 state.count = 0;
200 state.expected = expected;
201
202 EnumEnhMetaFile(0, hemf, enum_emf_proc, &state, NULL);
203
204 todo_wine_if (expected[state.count].todo)
205 ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
206 }
207
208 static BOOL CALLBACK enum_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
209 unsigned int dataSize, const unsigned char *pStr, void *userdata)
210 {
211 emfplus_check_state *state = (emfplus_check_state*)userdata;
212 emfplus_record actual;
213
214 actual.todo = FALSE;
215 actual.record_type = record_type;
216 actual.flags = flags;
217
218 if (dataSize == 0)
219 ok(pStr == NULL, "non-NULL pStr\n");
220
221 if (state->expected[state->count].record_type)
222 {
223 check_record(state->count, state->desc, &state->expected[state->count], &actual);
224
225 state->count++;
226 }
227 else
228 {
229 ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, record_type);
230 }
231
232 return TRUE;
233 }
234
235 static void check_metafile(GpMetafile *metafile, const emfplus_record *expected, const char *desc,
236 const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
237 {
238 GpStatus stat;
239 HDC hdc;
240 GpGraphics *graphics;
241 emfplus_check_state state;
242
243 state.desc = desc;
244 state.count = 0;
245 state.expected = expected;
246 state.metafile = metafile;
247
248 hdc = CreateCompatibleDC(0);
249
250 stat = GdipCreateFromHDC(hdc, &graphics);
251 expect(Ok, stat);
252
253 stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
254 3, src_rect, src_unit, enum_metafile_proc, &state, NULL);
255 expect(Ok, stat);
256
257 todo_wine_if (expected[state.count].todo)
258 ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
259
260 GdipDeleteGraphics(graphics);
261
262 DeleteDC(hdc);
263 }
264
265 static BOOL CALLBACK play_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
266 unsigned int dataSize, const unsigned char *pStr, void *userdata)
267 {
268 emfplus_check_state *state = (emfplus_check_state*)userdata;
269 GpStatus stat;
270
271 if (state->expected[state->count].record_type)
272 {
273 BOOL match = (state->expected[state->count].record_type == record_type);
274
275 if (match && state->expected[state->count].playback_fn)
276 state->expected[state->count].playback_fn(state->metafile, record_type, flags, dataSize, pStr);
277 else
278 {
279 stat = GdipPlayMetafileRecord(state->metafile, record_type, flags, dataSize, pStr);
280 todo_wine_if (state->expected[state->count].playback_todo)
281 ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat);
282 }
283
284 todo_wine_if (state->expected[state->count].todo)
285 ok(state->expected[state->count].record_type == record_type,
286 "%s.%i: expected record type 0x%x, got 0x%x\n", state->desc, state->count,
287 state->expected[state->count].record_type, record_type);
288 state->count++;
289 }
290 else
291 {
292 todo_wine_if (state->expected[state->count].playback_todo)
293 ok(0, "%s: unexpected record 0x%x\n", state->desc, record_type);
294
295 return FALSE;
296 }
297
298 return TRUE;
299 }
300
301 static void play_metafile(GpMetafile *metafile, GpGraphics *graphics, const emfplus_record *expected,
302 const char *desc, const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
303 {
304 GpStatus stat;
305 emfplus_check_state state;
306
307 state.desc = desc;
308 state.count = 0;
309 state.expected = expected;
310 state.metafile = metafile;
311
312 stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
313 3, src_rect, src_unit, play_metafile_proc, &state, NULL);
314 expect(Ok, stat);
315 }
316
317 /* When 'save' or 'load' is specified on the command line, save or
318 * load the specified filename. */
319 static void sync_metafile(GpMetafile **metafile, const char *filename)
320 {
321 GpStatus stat;
322 if (save_metafiles)
323 {
324 GpMetafile *clone;
325 HENHMETAFILE hemf;
326
327 stat = GdipCloneImage((GpImage*)*metafile, (GpImage**)&clone);
328 expect(Ok, stat);
329
330 stat = GdipGetHemfFromMetafile(clone, &hemf);
331 expect(Ok, stat);
332
333 DeleteEnhMetaFile(CopyEnhMetaFileA(hemf, filename));
334
335 DeleteEnhMetaFile(hemf);
336
337 stat = GdipDisposeImage((GpImage*)clone);
338 expect(Ok, stat);
339 }
340 else if (load_metafiles)
341 {
342 HENHMETAFILE hemf;
343
344 stat = GdipDisposeImage((GpImage*)*metafile);
345 expect(Ok, stat);
346 *metafile = NULL;
347
348 hemf = GetEnhMetaFileA(filename);
349 ok(hemf != NULL, "%s could not be opened\n", filename);
350
351 stat = GdipCreateMetafileFromEmf(hemf, TRUE, metafile);
352 expect(Ok, stat);
353 }
354 }
355
356 static const emfplus_record empty_records[] = {
357 { EMR_HEADER },
358 { EmfPlusRecordTypeHeader },
359 { EmfPlusRecordTypeEndOfFile },
360 { EMR_EOF },
361 { 0 }
362 };
363
364 static void test_empty(void)
365 {
366 GpStatus stat;
367 GpMetafile *metafile;
368 GpGraphics *graphics;
369 HDC hdc;
370 GpRectF bounds;
371 GpUnit unit;
372 REAL xres, yres;
373 HENHMETAFILE hemf, dummy;
374 MetafileHeader header;
375 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
376 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
377 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
378
379 hdc = CreateCompatibleDC(0);
380
381 stat = GdipRecordMetafile(NULL, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
382 expect(InvalidParameter, stat);
383
384 stat = GdipRecordMetafile(hdc, MetafileTypeInvalid, &frame, MetafileFrameUnitPixel, description, &metafile);
385 expect(InvalidParameter, stat);
386
387 stat = GdipRecordMetafile(hdc, MetafileTypeWmf, &frame, MetafileFrameUnitPixel, description, &metafile);
388 expect(InvalidParameter, stat);
389
390 stat = GdipRecordMetafile(hdc, MetafileTypeWmfPlaceable, &frame, MetafileFrameUnitPixel, description, &metafile);
391 expect(InvalidParameter, stat);
392
393 stat = GdipRecordMetafile(hdc, MetafileTypeEmfPlusDual+1, &frame, MetafileFrameUnitPixel, description, &metafile);
394 expect(InvalidParameter, stat);
395
396 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, NULL);
397 expect(InvalidParameter, stat);
398
399 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
400 expect(Ok, stat);
401
402 DeleteDC(hdc);
403
404 if (stat != Ok)
405 return;
406
407 stat = GdipGetHemfFromMetafile(metafile, &hemf);
408 expect(InvalidParameter, stat);
409
410 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
411 expect(Ok, stat);
412
413 stat = GdipGetHemfFromMetafile(metafile, &hemf);
414 expect(InvalidParameter, stat);
415
416 stat = GdipDeleteGraphics(graphics);
417 expect(Ok, stat);
418
419 check_metafile(metafile, empty_records, "empty metafile", dst_points, &frame, UnitPixel);
420
421 sync_metafile(&metafile, "empty.emf");
422
423 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
424 expect(Ok, stat);
425 expectf(0.0, bounds.X);
426 expectf(0.0, bounds.Y);
427 expectf_(100.0, bounds.Width, 0.05);
428 expectf_(100.0, bounds.Height, 0.05);
429 expect(UnitPixel, unit);
430
431 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
432 expect(Ok, stat);
433
434 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
435 expect(Ok, stat);
436
437 memset(&header, 0xaa, sizeof(header));
438 stat = GdipGetMetafileHeaderFromMetafile(metafile, &header);
439 expect(Ok, stat);
440 expect(MetafileTypeEmfPlusOnly, header.Type);
441 expect(U(header).EmfHeader.nBytes, header.Size);
442 ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
443 expect(1, header.EmfPlusFlags); /* reference device was display, not printer */
444 expectf(xres, header.DpiX);
445 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
446 expectf(yres, header.DpiY);
447 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
448 expect(0, header.X);
449 expect(0, header.Y);
450 expect(100, header.Width);
451 expect(100, header.Height);
452 expect(28, header.EmfPlusHeaderSize);
453 expect(96, header.LogicalDpiX);
454 expect(96, header.LogicalDpiX);
455 expect(EMR_HEADER, U(header).EmfHeader.iType);
456 expect(0, U(header).EmfHeader.rclBounds.left);
457 expect(0, U(header).EmfHeader.rclBounds.top);
458 expect(-1, U(header).EmfHeader.rclBounds.right);
459 expect(-1, U(header).EmfHeader.rclBounds.bottom);
460 expect(0, U(header).EmfHeader.rclFrame.left);
461 expect(0, U(header).EmfHeader.rclFrame.top);
462 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
463 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
464
465 stat = GdipGetHemfFromMetafile(metafile, &hemf);
466 expect(Ok, stat);
467
468 stat = GdipGetHemfFromMetafile(metafile, &dummy);
469 expect(InvalidParameter, stat);
470
471 stat = GdipDisposeImage((GpImage*)metafile);
472 expect(Ok, stat);
473
474 check_emfplus(hemf, empty_records, "empty emf");
475
476 memset(&header, 0xaa, sizeof(header));
477 stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
478 expect(Ok, stat);
479 expect(MetafileTypeEmfPlusOnly, header.Type);
480 expect(U(header).EmfHeader.nBytes, header.Size);
481 ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
482 expect(1, header.EmfPlusFlags); /* reference device was display, not printer */
483 expectf(xres, header.DpiX);
484 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
485 expectf(yres, header.DpiY);
486 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
487 expect(0, header.X);
488 expect(0, header.Y);
489 expect(100, header.Width);
490 expect(100, header.Height);
491 expect(28, header.EmfPlusHeaderSize);
492 expect(96, header.LogicalDpiX);
493 expect(96, header.LogicalDpiX);
494 expect(EMR_HEADER, U(header).EmfHeader.iType);
495 expect(0, U(header).EmfHeader.rclBounds.left);
496 expect(0, U(header).EmfHeader.rclBounds.top);
497 expect(-1, U(header).EmfHeader.rclBounds.right);
498 expect(-1, U(header).EmfHeader.rclBounds.bottom);
499 expect(0, U(header).EmfHeader.rclFrame.left);
500 expect(0, U(header).EmfHeader.rclFrame.top);
501 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
502 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
503
504 stat = GdipCreateMetafileFromEmf(hemf, TRUE, &metafile);
505 expect(Ok, stat);
506
507 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
508 expect(Ok, stat);
509 expectf(0.0, bounds.X);
510 expectf(0.0, bounds.Y);
511 expectf_(100.0, bounds.Width, 0.05);
512 expectf_(100.0, bounds.Height, 0.05);
513 expect(UnitPixel, unit);
514
515 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
516 expect(Ok, stat);
517 expectf(header.DpiX, xres);
518
519 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
520 expect(Ok, stat);
521 expectf(header.DpiY, yres);
522
523 memset(&header, 0xaa, sizeof(header));
524 stat = GdipGetMetafileHeaderFromMetafile(metafile, &header);
525 expect(Ok, stat);
526 expect(MetafileTypeEmfPlusOnly, header.Type);
527 expect(U(header).EmfHeader.nBytes, header.Size);
528 ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
529 expect(1, header.EmfPlusFlags); /* reference device was display, not printer */
530 expectf(xres, header.DpiX);
531 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
532 expectf(yres, header.DpiY);
533 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
534 expect(0, header.X);
535 expect(0, header.Y);
536 expect(100, header.Width);
537 expect(100, header.Height);
538 expect(28, header.EmfPlusHeaderSize);
539 expect(96, header.LogicalDpiX);
540 expect(96, header.LogicalDpiX);
541 expect(EMR_HEADER, U(header).EmfHeader.iType);
542 expect(0, U(header).EmfHeader.rclBounds.left);
543 expect(0, U(header).EmfHeader.rclBounds.top);
544 expect(-1, U(header).EmfHeader.rclBounds.right);
545 expect(-1, U(header).EmfHeader.rclBounds.bottom);
546 expect(0, U(header).EmfHeader.rclFrame.left);
547 expect(0, U(header).EmfHeader.rclFrame.top);
548 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
549 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
550
551 stat = GdipDisposeImage((GpImage*)metafile);
552 expect(Ok, stat);
553 }
554
555 static const emfplus_record getdc_records[] = {
556 { EMR_HEADER },
557 { EmfPlusRecordTypeHeader },
558 { EmfPlusRecordTypeGetDC },
559 { EMR_CREATEBRUSHINDIRECT },
560 { EMR_SELECTOBJECT },
561 { EMR_RECTANGLE },
562 { EMR_SELECTOBJECT },
563 { EMR_DELETEOBJECT },
564 { EmfPlusRecordTypeEndOfFile },
565 { EMR_EOF },
566 { 0 }
567 };
568
569 static void test_getdc(void)
570 {
571 GpStatus stat;
572 GpMetafile *metafile;
573 GpGraphics *graphics;
574 HDC hdc, metafile_dc;
575 HENHMETAFILE hemf;
576 BOOL ret;
577 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
578 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
579 static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
580 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
581 HBRUSH hbrush, holdbrush;
582 GpBitmap *bitmap;
583 ARGB color;
584
585 hdc = CreateCompatibleDC(0);
586
587 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
588 expect(Ok, stat);
589
590 DeleteDC(hdc);
591
592 if (stat != Ok)
593 return;
594
595 stat = GdipGetHemfFromMetafile(metafile, &hemf);
596 expect(InvalidParameter, stat);
597
598 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
599 expect(Ok, stat);
600
601 stat = GdipGetDC(graphics, &metafile_dc);
602 expect(Ok, stat);
603
604 if (stat != Ok)
605 {
606 GdipDeleteGraphics(graphics);
607 GdipDisposeImage((GpImage*)metafile);
608 return;
609 }
610
611 hbrush = CreateSolidBrush(0xff0000);
612
613 holdbrush = SelectObject(metafile_dc, hbrush);
614
615 Rectangle(metafile_dc, 25, 25, 75, 75);
616
617 SelectObject(metafile_dc, holdbrush);
618
619 DeleteObject(hbrush);
620
621 stat = GdipReleaseDC(graphics, metafile_dc);
622 expect(Ok, stat);
623
624 stat = GdipDeleteGraphics(graphics);
625 expect(Ok, stat);
626
627 check_metafile(metafile, getdc_records, "getdc metafile", dst_points, &frame, UnitPixel);
628
629 sync_metafile(&metafile, "getdc.emf");
630
631 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
632 expect(Ok, stat);
633
634 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
635 expect(Ok, stat);
636
637 play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points, &frame, UnitPixel);
638
639 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
640 expect(Ok, stat);
641 expect(0, color);
642
643 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
644 expect(Ok, stat);
645 expect(0xff0000ff, color);
646
647 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
648 expect(Ok, stat);
649
650 play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points_half, &frame, UnitPixel);
651
652 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
653 expect(Ok, stat);
654 expect(0xff0000ff, color);
655
656 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
657 expect(Ok, stat);
658 expect(0, color);
659
660 stat = GdipBitmapSetPixel(bitmap, 15, 15, 0);
661 expect(Ok, stat);
662
663 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
664 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
665 expect(Ok, stat);
666
667 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
668 expect(Ok, stat);
669 expect(0, color);
670
671 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
672 expect(Ok, stat);
673 expect(0xff0000ff, color);
674
675 stat = GdipDeleteGraphics(graphics);
676 expect(Ok, stat);
677
678 stat = GdipDisposeImage((GpImage*)bitmap);
679 expect(Ok, stat);
680
681 stat = GdipGetHemfFromMetafile(metafile, &hemf);
682 expect(Ok, stat);
683
684 stat = GdipDisposeImage((GpImage*)metafile);
685 expect(Ok, stat);
686
687 check_emfplus(hemf, getdc_records, "getdc emf");
688
689 ret = DeleteEnhMetaFile(hemf);
690 ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
691 }
692
693 static const emfplus_record emfonly_records[] = {
694 { EMR_HEADER },
695 { EMR_CREATEBRUSHINDIRECT },
696 { EMR_SELECTOBJECT },
697 { EMR_RECTANGLE },
698 { EMR_SELECTOBJECT },
699 { EMR_DELETEOBJECT },
700 { EMR_EOF },
701 { 0 }
702 };
703
704 static const emfplus_record emfonly_draw_records[] = {
705 { EMR_HEADER },
706 { EMR_SAVEDC, 0, 1 },
707 { EMR_SETICMMODE, 0, 1 },
708 { EMR_SETMITERLIMIT, 0, 1 },
709 { EMR_MODIFYWORLDTRANSFORM, 0, 1 },
710 { EMR_EXTCREATEPEN, 0, 1 },
711 { EMR_SELECTOBJECT, 0, 1 },
712 { EMR_SELECTOBJECT, 0, 1 },
713 { EMR_POLYLINE16, 0, 1 },
714 { EMR_SELECTOBJECT, 0, 1 },
715 { EMR_SELECTOBJECT, 0, 1 },
716 { EMR_MODIFYWORLDTRANSFORM, 0, 1 },
717 { EMR_DELETEOBJECT, 0, 1 },
718 { EMR_SETMITERLIMIT, 0, 1 },
719 { EMR_RESTOREDC, 0, 1 },
720 { EMR_EOF },
721 { 0, 0, 1 }
722 };
723
724 static void test_emfonly(void)
725 {
726 GpStatus stat;
727 GpMetafile *metafile;
728 GpImage *clone;
729 GpGraphics *graphics;
730 HDC hdc, metafile_dc;
731 GpRectF bounds;
732 GpUnit unit;
733 REAL xres, yres;
734 HENHMETAFILE hemf;
735 MetafileHeader header;
736 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
737 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
738 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
739 HBRUSH hbrush, holdbrush;
740 GpBitmap *bitmap;
741 ARGB color;
742 GpPen *pen;
743
744 hdc = CreateCompatibleDC(0);
745
746 stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
747 expect(Ok, stat);
748
749 DeleteDC(hdc);
750
751 if (stat != Ok)
752 return;
753
754 stat = GdipGetHemfFromMetafile(metafile, &hemf);
755 expect(InvalidParameter, stat);
756
757 memset(&header, 0xaa, sizeof(header));
758 stat = GdipGetMetafileHeaderFromMetafile(metafile, &header);
759 expect(Ok, stat);
760 expect(MetafileTypeEmf, header.Type);
761 ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
762 /* The rest is zeroed or seemingly random/uninitialized garbage. */
763
764 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
765 expect(Ok, stat);
766
767 stat = GdipGetDC(graphics, &metafile_dc);
768 expect(Ok, stat);
769
770 if (stat != Ok)
771 {
772 GdipDeleteGraphics(graphics);
773 GdipDisposeImage((GpImage*)metafile);
774 return;
775 }
776
777 hbrush = CreateSolidBrush(0xff0000);
778
779 holdbrush = SelectObject(metafile_dc, hbrush);
780
781 Rectangle(metafile_dc, 25, 25, 75, 75);
782
783 SelectObject(metafile_dc, holdbrush);
784
785 DeleteObject(hbrush);
786
787 stat = GdipReleaseDC(graphics, metafile_dc);
788 expect(Ok, stat);
789
790 stat = GdipDeleteGraphics(graphics);
791 expect(Ok, stat);
792
793 check_metafile(metafile, emfonly_records, "emfonly metafile", dst_points, &frame, UnitPixel);
794
795 sync_metafile(&metafile, "emfonly.emf");
796
797 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
798 expect(Ok, stat);
799 expectf(0.0, bounds.X);
800 expectf(0.0, bounds.Y);
801 expectf_(100.0, bounds.Width, 0.05);
802 expectf_(100.0, bounds.Height, 0.05);
803 expect(UnitPixel, unit);
804
805 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
806 expect(Ok, stat);
807
808 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
809 expect(Ok, stat);
810
811 memset(&header, 0xaa, sizeof(header));
812 stat = GdipGetMetafileHeaderFromMetafile(metafile, &header);
813 expect(Ok, stat);
814 expect(MetafileTypeEmf, header.Type);
815 expect(U(header).EmfHeader.nBytes, header.Size);
816 /* For some reason a recoreded EMF Metafile has an EMF+ version. */
817 todo_wine ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
818 expect(0, header.EmfPlusFlags);
819 expectf(xres, header.DpiX);
820 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
821 expectf(yres, header.DpiY);
822 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
823 expect(0, header.X);
824 expect(0, header.Y);
825 expect(100, header.Width);
826 expect(100, header.Height);
827 expect(0, header.EmfPlusHeaderSize);
828 expect(0, header.LogicalDpiX);
829 expect(0, header.LogicalDpiX);
830 expect(EMR_HEADER, U(header).EmfHeader.iType);
831 expect(25, U(header).EmfHeader.rclBounds.left);
832 expect(25, U(header).EmfHeader.rclBounds.top);
833 expect(74, U(header).EmfHeader.rclBounds.right);
834 expect(74, U(header).EmfHeader.rclBounds.bottom);
835 expect(0, U(header).EmfHeader.rclFrame.left);
836 expect(0, U(header).EmfHeader.rclFrame.top);
837 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
838 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
839
840 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
841 expect(Ok, stat);
842
843 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
844 expect(Ok, stat);
845
846 play_metafile(metafile, graphics, emfonly_records, "emfonly playback", dst_points, &frame, UnitPixel);
847
848 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
849 expect(Ok, stat);
850 expect(0, color);
851
852 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
853 expect(Ok, stat);
854 expect(0xff0000ff, color);
855
856 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
857 expect(Ok, stat);
858
859 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
860 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
861 expect(Ok, stat);
862
863 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
864 expect(Ok, stat);
865 expect(0, color);
866
867 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
868 expect(Ok, stat);
869 expect(0xff0000ff, color);
870
871 stat = GdipCloneImage((GpImage*)metafile, &clone);
872 expect(Ok, stat);
873
874 if (stat == Ok)
875 {
876 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
877 expect(Ok, stat);
878
879 stat = GdipDrawImagePointsRect(graphics, clone, dst_points, 3,
880 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
881 expect(Ok, stat);
882
883 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
884 expect(Ok, stat);
885 expect(0, color);
886
887 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
888 expect(Ok, stat);
889 expect(0xff0000ff, color);
890
891 GdipDisposeImage(clone);
892 }
893
894 stat = GdipDeleteGraphics(graphics);
895 expect(Ok, stat);
896
897 stat = GdipDisposeImage((GpImage*)bitmap);
898 expect(Ok, stat);
899
900 stat = GdipGetHemfFromMetafile(metafile, &hemf);
901 expect(Ok, stat);
902
903 stat = GdipDisposeImage((GpImage*)metafile);
904 expect(Ok, stat);
905
906 check_emfplus(hemf, emfonly_records, "emfonly emf");
907
908 memset(&header, 0xaa, sizeof(header));
909 stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
910 expect(Ok, stat);
911 expect(MetafileTypeEmf, header.Type);
912 expect(U(header).EmfHeader.nBytes, header.Size);
913 expect(0x10000, header.Version);
914 expect(0, header.EmfPlusFlags);
915 expectf(xres, header.DpiX);
916 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
917 expectf(yres, header.DpiY);
918 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
919 expect(0, header.X);
920 expect(0, header.Y);
921 expect(100, header.Width);
922 expect(100, header.Height);
923 expect(0, header.EmfPlusHeaderSize);
924 expect(0, header.LogicalDpiX);
925 expect(0, header.LogicalDpiX);
926 expect(EMR_HEADER, U(header).EmfHeader.iType);
927 expect(25, U(header).EmfHeader.rclBounds.left);
928 expect(25, U(header).EmfHeader.rclBounds.top);
929 expect(74, U(header).EmfHeader.rclBounds.right);
930 expect(74, U(header).EmfHeader.rclBounds.bottom);
931 expect(0, U(header).EmfHeader.rclFrame.left);
932 expect(0, U(header).EmfHeader.rclFrame.top);
933 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
934 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
935
936 stat = GdipCreateMetafileFromEmf(hemf, TRUE, &metafile);
937 expect(Ok, stat);
938
939 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
940 expect(Ok, stat);
941 expectf(0.0, bounds.X);
942 expectf(0.0, bounds.Y);
943 expectf_(100.0, bounds.Width, 0.05);
944 expectf_(100.0, bounds.Height, 0.05);
945 expect(UnitPixel, unit);
946
947 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
948 expect(Ok, stat);
949 expectf(header.DpiX, xres);
950
951 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
952 expect(Ok, stat);
953 expectf(header.DpiY, yres);
954
955 memset(&header, 0xaa, sizeof(header));
956 stat = GdipGetMetafileHeaderFromMetafile(metafile, &header);
957 expect(Ok, stat);
958 expect(MetafileTypeEmf, header.Type);
959 expect(U(header).EmfHeader.nBytes, header.Size);
960 expect(0x10000, header.Version);
961 expect(0, header.EmfPlusFlags);
962 expectf(xres, header.DpiX);
963 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
964 expectf(yres, header.DpiY);
965 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
966 expect(0, header.X);
967 expect(0, header.Y);
968 expect(100, header.Width);
969 expect(100, header.Height);
970 expect(0, header.EmfPlusHeaderSize);
971 expect(0, header.LogicalDpiX);
972 expect(0, header.LogicalDpiX);
973 expect(EMR_HEADER, U(header).EmfHeader.iType);
974 expect(25, U(header).EmfHeader.rclBounds.left);
975 expect(25, U(header).EmfHeader.rclBounds.top);
976 expect(74, U(header).EmfHeader.rclBounds.right);
977 expect(74, U(header).EmfHeader.rclBounds.bottom);
978 expect(0, U(header).EmfHeader.rclFrame.left);
979 expect(0, U(header).EmfHeader.rclFrame.top);
980 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
981 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
982
983 stat = GdipDisposeImage((GpImage*)metafile);
984 expect(Ok, stat);
985
986 /* test drawing to metafile with gdi+ functions */
987 hdc = CreateCompatibleDC(0);
988
989 stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
990 expect(Ok, stat);
991
992 DeleteDC(hdc);
993
994 if (stat != Ok)
995 return;
996
997 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
998 expect(Ok, stat);
999
1000 stat = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1001 expect(Ok, stat);
1002 stat = GdipDrawLineI(graphics, pen, 0, 0, 10, 10);
1003 todo_wine expect(Ok, stat);
1004 GdipDeletePen(pen);
1005
1006 stat = GdipDeleteGraphics(graphics);
1007 expect(Ok, stat);
1008
1009 check_metafile(metafile, emfonly_draw_records, "emfonly draw metafile", dst_points, &frame, UnitPixel);
1010 sync_metafile(&metafile, "emfonly_draw.emf");
1011
1012 stat = GdipDisposeImage((GpImage*)metafile);
1013 expect(Ok, stat);
1014 }
1015
1016 static const emfplus_record fillrect_records[] = {
1017 { EMR_HEADER },
1018 { EmfPlusRecordTypeHeader },
1019 { EmfPlusRecordTypeFillRects, 0xc000 },
1020 { EmfPlusRecordTypeEndOfFile },
1021 { EMR_EOF },
1022 { 0 }
1023 };
1024
1025 static void test_fillrect(void)
1026 {
1027 GpStatus stat;
1028 GpMetafile *metafile;
1029 GpGraphics *graphics;
1030 HDC hdc;
1031 HENHMETAFILE hemf;
1032 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
1033 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1034 static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
1035 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1036 GpBitmap *bitmap;
1037 ARGB color;
1038 GpBrush *brush;
1039
1040 hdc = CreateCompatibleDC(0);
1041
1042 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
1043 expect(Ok, stat);
1044
1045 DeleteDC(hdc);
1046
1047 if (stat != Ok)
1048 return;
1049
1050 stat = GdipGetHemfFromMetafile(metafile, &hemf);
1051 expect(InvalidParameter, stat);
1052
1053 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1054 expect(Ok, stat);
1055
1056 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
1057 expect(Ok, stat);
1058
1059 stat = GdipFillRectangleI(graphics, brush, 25, 25, 75, 75);
1060 expect(Ok, stat);
1061
1062 stat = GdipDeleteBrush(brush);
1063 expect(Ok, stat);
1064
1065 stat = GdipDeleteGraphics(graphics);
1066 expect(Ok, stat);
1067
1068 check_metafile(metafile, fillrect_records, "fillrect metafile", dst_points, &frame, UnitPixel);
1069
1070 sync_metafile(&metafile, "fillrect.emf");
1071
1072 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
1073 expect(Ok, stat);
1074
1075 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1076 expect(Ok, stat);
1077
1078 play_metafile(metafile, graphics, fillrect_records, "fillrect playback", dst_points, &frame, UnitPixel);
1079
1080 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
1081 expect(Ok, stat);
1082 expect(0, color);
1083
1084 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
1085 expect(Ok, stat);
1086 expect(0xff0000ff, color);
1087
1088 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
1089 expect(Ok, stat);
1090
1091 play_metafile(metafile, graphics, fillrect_records, "fillrect playback", dst_points_half, &frame, UnitPixel);
1092
1093 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
1094 expect(Ok, stat);
1095 expect(0xff0000ff, color);
1096
1097 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
1098 expect(Ok, stat);
1099 expect(0, color);
1100
1101 stat = GdipBitmapSetPixel(bitmap, 15, 15, 0);
1102 expect(Ok, stat);
1103
1104 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
1105 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
1106 expect(Ok, stat);
1107
1108 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
1109 expect(Ok, stat);
1110 expect(0, color);
1111
1112 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
1113 expect(Ok, stat);
1114 expect(0xff0000ff, color);
1115
1116 stat = GdipDeleteGraphics(graphics);
1117 expect(Ok, stat);
1118
1119 stat = GdipDisposeImage((GpImage*)bitmap);
1120 expect(Ok, stat);
1121
1122 stat = GdipDisposeImage((GpImage*)metafile);
1123 expect(Ok, stat);
1124 }
1125
1126 static const emfplus_record clear_emf_records[] = {
1127 { EMR_HEADER },
1128 { EmfPlusRecordTypeHeader },
1129 { EmfPlusRecordTypeClear },
1130 { EMR_SAVEDC, 0, 1 },
1131 { EMR_SETICMMODE, 0, 1 },
1132 { EMR_BITBLT, 0, 1 },
1133 { EMR_RESTOREDC, 0, 1 },
1134 { EmfPlusRecordTypeEndOfFile },
1135 { EMR_EOF },
1136 { 0 }
1137 };
1138
1139 static void test_clear(void)
1140 {
1141 GpStatus stat;
1142 GpMetafile *metafile;
1143 GpGraphics *graphics;
1144 HDC hdc;
1145 HENHMETAFILE hemf;
1146 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
1147 static const GpPointF dst_points[3] = {{10.0,10.0},{20.0,10.0},{10.0,20.0}};
1148 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1149 GpBitmap *bitmap;
1150 ARGB color;
1151
1152 hdc = CreateCompatibleDC(0);
1153
1154 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
1155 expect(Ok, stat);
1156
1157 DeleteDC(hdc);
1158
1159 if (stat != Ok)
1160 return;
1161
1162 stat = GdipGetHemfFromMetafile(metafile, &hemf);
1163 expect(InvalidParameter, stat);
1164
1165 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1166 expect(Ok, stat);
1167
1168 stat = GdipGraphicsClear(graphics, 0xffffff00);
1169 expect(Ok, stat);
1170
1171 stat = GdipDeleteGraphics(graphics);
1172 expect(Ok, stat);
1173
1174 sync_metafile(&metafile, "clear.emf");
1175
1176 stat = GdipCreateBitmapFromScan0(30, 30, 0, PixelFormat32bppRGB, NULL, &bitmap);
1177 expect(Ok, stat);
1178
1179 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1180 expect(Ok, stat);
1181
1182 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
1183 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
1184 expect(Ok, stat);
1185
1186 stat = GdipBitmapGetPixel(bitmap, 5, 5, &color);
1187 expect(Ok, stat);
1188 expect(0xff000000, color);
1189
1190 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
1191 expect(Ok, stat);
1192 expect(0xffffff00, color);
1193
1194 stat = GdipBitmapGetPixel(bitmap, 25, 25, &color);
1195 expect(Ok, stat);
1196 expect(0xff000000, color);
1197
1198 stat = GdipDeleteGraphics(graphics);
1199 expect(Ok, stat);
1200
1201 stat = GdipDisposeImage((GpImage*)bitmap);
1202 expect(Ok, stat);
1203
1204 stat = GdipGetHemfFromMetafile(metafile, &hemf);
1205 expect(Ok, stat);
1206
1207 stat = GdipDisposeImage((GpImage*)metafile);
1208 expect(Ok, stat);
1209
1210 check_emfplus(hemf, clear_emf_records, "clear emf");
1211
1212 DeleteEnhMetaFile(hemf);
1213 }
1214
1215 static void test_nullframerect(void) {
1216 GpStatus stat;
1217 GpMetafile *metafile;
1218 GpGraphics *graphics;
1219 HDC hdc, metafile_dc;
1220 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1221 GpBrush *brush;
1222 HBRUSH hbrush, holdbrush;
1223 GpRectF bounds;
1224 GpUnit unit;
1225
1226 hdc = CreateCompatibleDC(0);
1227
1228 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, NULL, MetafileFrameUnitPixel, description, &metafile);
1229 expect(Ok, stat);
1230
1231 DeleteDC(hdc);
1232
1233 if (stat != Ok)
1234 return;
1235
1236 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1237 expect(Ok, stat);
1238 expect(UnitPixel, unit);
1239 expectf(0.0, bounds.X);
1240 expectf(0.0, bounds.Y);
1241 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
1242 "expected 1.0, got %f\n", bounds.Width);
1243 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
1244 "expected 1.0, got %f\n", bounds.Height);
1245
1246 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1247 expect(Ok, stat);
1248
1249 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
1250 expect(Ok, stat);
1251
1252 stat = GdipFillRectangleI(graphics, brush, 25, 25, 75, 75);
1253 expect(Ok, stat);
1254
1255 stat = GdipDeleteBrush(brush);
1256 expect(Ok, stat);
1257
1258 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1259 expect(Ok, stat);
1260 expect(UnitPixel, unit);
1261 expectf(0.0, bounds.X);
1262 expectf(0.0, bounds.Y);
1263 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
1264 "expected 1.0, got %f\n", bounds.Width);
1265 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
1266 "expected 1.0, got %f\n", bounds.Height);
1267
1268 stat = GdipDeleteGraphics(graphics);
1269 expect(Ok, stat);
1270
1271 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1272 expect(Ok, stat);
1273 expect(UnitPixel, unit);
1274 expectf_(25.0, bounds.X, 0.05);
1275 expectf_(25.0, bounds.Y, 0.05);
1276 expectf_(75.0, bounds.Width, 0.05);
1277 expectf_(75.0, bounds.Height, 0.05);
1278
1279 stat = GdipDisposeImage((GpImage*)metafile);
1280 expect(Ok, stat);
1281
1282 hdc = CreateCompatibleDC(0);
1283
1284 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, NULL, MetafileFrameUnitMillimeter, description, &metafile);
1285 expect(Ok, stat);
1286
1287 DeleteDC(hdc);
1288
1289 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1290 expect(Ok, stat);
1291
1292 stat = GdipGetDC(graphics, &metafile_dc);
1293 expect(Ok, stat);
1294
1295 if (stat != Ok)
1296 {
1297 GdipDeleteGraphics(graphics);
1298 GdipDisposeImage((GpImage*)metafile);
1299 return;
1300 }
1301
1302 hbrush = CreateSolidBrush(0xff0000);
1303
1304 holdbrush = SelectObject(metafile_dc, hbrush);
1305
1306 Rectangle(metafile_dc, 25, 25, 75, 75);
1307
1308 SelectObject(metafile_dc, holdbrush);
1309
1310 DeleteObject(hbrush);
1311
1312 stat = GdipReleaseDC(graphics, metafile_dc);
1313 expect(Ok, stat);
1314
1315 stat = GdipDeleteGraphics(graphics);
1316 expect(Ok, stat);
1317
1318 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1319 expect(Ok, stat);
1320 expect(UnitPixel, unit);
1321 expectf_(25.0, bounds.X, 0.05);
1322 expectf_(25.0, bounds.Y, 0.05);
1323 todo_wine expectf_(50.0, bounds.Width, 0.05);
1324 todo_wine expectf_(50.0, bounds.Height, 0.05);
1325
1326 stat = GdipDisposeImage((GpImage*)metafile);
1327 expect(Ok, stat);
1328 }
1329
1330 static const emfplus_record pagetransform_records[] = {
1331 { EMR_HEADER },
1332 { EmfPlusRecordTypeHeader },
1333 { EmfPlusRecordTypeFillRects, 0xc000 },
1334 { EmfPlusRecordTypeSetPageTransform, UnitPixel },
1335 { EmfPlusRecordTypeFillRects, 0xc000 },
1336 { EmfPlusRecordTypeSetPageTransform, UnitPixel },
1337 { EmfPlusRecordTypeFillRects, 0xc000 },
1338 { EmfPlusRecordTypeSetPageTransform, UnitInch },
1339 { EmfPlusRecordTypeFillRects, 0x8000 },
1340 { EmfPlusRecordTypeSetPageTransform, UnitDisplay },
1341 { EmfPlusRecordTypeFillRects, 0xc000 },
1342 { EmfPlusRecordTypeEndOfFile },
1343 { EMR_EOF },
1344 { 0 }
1345 };
1346
1347 static void test_pagetransform(void)
1348 {
1349 GpStatus stat;
1350 GpMetafile *metafile;
1351 GpGraphics *graphics;
1352 HDC hdc;
1353 static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
1354 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1355 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1356 GpBitmap *bitmap;
1357 ARGB color;
1358 GpBrush *brush;
1359 GpUnit unit;
1360 REAL scale, dpix, dpiy;
1361 UINT width, height;
1362
1363 hdc = CreateCompatibleDC(0);
1364
1365 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitInch, description, &metafile);
1366 expect(Ok, stat);
1367
1368 DeleteDC(hdc);
1369
1370 if (stat != Ok)
1371 return;
1372
1373 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &dpix);
1374 todo_wine expect(InvalidParameter, stat);
1375
1376 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &dpiy);
1377 todo_wine expect(InvalidParameter, stat);
1378
1379 stat = GdipGetImageWidth((GpImage*)metafile, &width);
1380 todo_wine expect(InvalidParameter, stat);
1381
1382 stat = GdipGetImageHeight((GpImage*)metafile, &height);
1383 todo_wine expect(InvalidParameter, stat);
1384
1385 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1386 expect(Ok, stat);
1387
1388 /* initial scale */
1389 stat = GdipGetPageUnit(graphics, &unit);
1390 expect(Ok, stat);
1391 expect(UnitDisplay, unit);
1392
1393 stat = GdipGetPageScale(graphics, &scale);
1394 expect(Ok, stat);
1395 expectf(1.0, scale);
1396
1397 stat = GdipGetDpiX(graphics, &dpix);
1398 expect(Ok, stat);
1399 expectf(96.0, dpix);
1400
1401 stat = GdipGetDpiY(graphics, &dpiy);
1402 expect(Ok, stat);
1403 expectf(96.0, dpiy);
1404
1405 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
1406 expect(Ok, stat);
1407
1408 stat = GdipFillRectangleI(graphics, brush, 1, 2, 1, 1);
1409 expect(Ok, stat);
1410
1411 stat = GdipDeleteBrush(brush);
1412 expect(Ok, stat);
1413
1414 /* page unit = pixels */
1415 stat = GdipSetPageUnit(graphics, UnitPixel);
1416 expect(Ok, stat);
1417
1418 stat = GdipGetPageUnit(graphics, &unit);
1419 expect(Ok, stat);
1420 expect(UnitPixel, unit);
1421
1422 stat = GdipCreateSolidFill((ARGB)0xff00ff00, (GpSolidFill**)&brush);
1423 expect(Ok, stat);
1424
1425 stat = GdipFillRectangleI(graphics, brush, 0, 1, 1, 1);
1426 expect(Ok, stat);
1427
1428 stat = GdipDeleteBrush(brush);
1429 expect(Ok, stat);
1430
1431 /* page scale = 3, unit = pixels */
1432 stat = GdipSetPageScale(graphics, 3.0);
1433 expect(Ok, stat);
1434
1435 stat = GdipGetPageScale(graphics, &scale);
1436 expect(Ok, stat);
1437 expectf(3.0, scale);
1438
1439 stat = GdipCreateSolidFill((ARGB)0xff00ffff, (GpSolidFill**)&brush);
1440 expect(Ok, stat);
1441
1442 stat = GdipFillRectangleI(graphics, brush, 0, 1, 2, 2);
1443 expect(Ok, stat);
1444
1445 stat = GdipDeleteBrush(brush);
1446 expect(Ok, stat);
1447
1448 /* page scale = 3, unit = inches */
1449 stat = GdipSetPageUnit(graphics, UnitInch);
1450 expect(Ok, stat);
1451
1452 stat = GdipGetPageUnit(graphics, &unit);
1453 expect(Ok, stat);
1454 expect(UnitInch, unit);
1455
1456 stat = GdipCreateSolidFill((ARGB)0xffff0000, (GpSolidFill**)&brush);
1457 expect(Ok, stat);
1458
1459 stat = GdipFillRectangle(graphics, brush, 1.0/96.0, 0, 1, 1);
1460 expect(Ok, stat);
1461
1462 stat = GdipDeleteBrush(brush);
1463 expect(Ok, stat);
1464
1465 /* page scale = 3, unit = display */
1466 stat = GdipSetPageUnit(graphics, UnitDisplay);
1467 expect(Ok, stat);
1468
1469 stat = GdipGetPageUnit(graphics, &unit);
1470 expect(Ok, stat);
1471 expect(UnitDisplay, unit);
1472
1473 stat = GdipCreateSolidFill((ARGB)0xffff00ff, (GpSolidFill**)&brush);
1474 expect(Ok, stat);
1475
1476 stat = GdipFillRectangle(graphics, brush, 3, 3, 2, 2);
1477 expect(Ok, stat);
1478
1479 stat = GdipDeleteBrush(brush);
1480 expect(Ok, stat);
1481
1482 stat = GdipDeleteGraphics(graphics);
1483 expect(Ok, stat);
1484
1485 check_metafile(metafile, pagetransform_records, "pagetransform metafile", dst_points, &frame, UnitPixel);
1486
1487 sync_metafile(&metafile, "pagetransform.emf");
1488
1489 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
1490 expect(Ok, stat);
1491
1492 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1493 expect(Ok, stat);
1494
1495 play_metafile(metafile, graphics, pagetransform_records, "pagetransform playback", dst_points, &frame, UnitPixel);
1496
1497 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
1498 expect(Ok, stat);
1499 expect(0, color);
1500
1501 stat = GdipBitmapGetPixel(bitmap, 30, 50, &color);
1502 expect(Ok, stat);
1503 expect(0xff0000ff, color);
1504
1505 stat = GdipBitmapGetPixel(bitmap, 10, 30, &color);
1506 expect(Ok, stat);
1507 expect(0xff00ff00, color);
1508
1509 stat = GdipBitmapGetPixel(bitmap, 20, 80, &color);
1510 expect(Ok, stat);
1511 expect(0xff00ffff, color);
1512
1513 stat = GdipBitmapGetPixel(bitmap, 80, 20, &color);
1514 expect(Ok, stat);
1515 expect(0xffff0000, color);
1516
1517 stat = GdipBitmapGetPixel(bitmap, 80, 80, &color);
1518 expect(Ok, stat);
1519 expect(0xffff00ff, color);
1520
1521 stat = GdipDeleteGraphics(graphics);
1522 expect(Ok, stat);
1523
1524 stat = GdipDisposeImage((GpImage*)bitmap);
1525 expect(Ok, stat);
1526
1527 stat = GdipDisposeImage((GpImage*)metafile);
1528 expect(Ok, stat);
1529 }
1530
1531 static const emfplus_record worldtransform_records[] = {
1532 { EMR_HEADER },
1533 { EmfPlusRecordTypeHeader },
1534 { EmfPlusRecordTypeFillRects, 0xc000 },
1535 { EmfPlusRecordTypeScaleWorldTransform },
1536 { EmfPlusRecordTypeFillRects, 0x8000 },
1537 { EmfPlusRecordTypeResetWorldTransform },
1538 { EmfPlusRecordTypeFillRects, 0xc000 },
1539 { EmfPlusRecordTypeMultiplyWorldTransform },
1540 { EmfPlusRecordTypeFillRects, 0x8000 },
1541 { EmfPlusRecordTypeRotateWorldTransform, 0x2000 },
1542 { EmfPlusRecordTypeFillRects, 0x8000 },
1543 { EmfPlusRecordTypeSetWorldTransform },
1544 { EmfPlusRecordTypeFillRects, 0xc000 },
1545 { EmfPlusRecordTypeTranslateWorldTransform, 0x2000 },
1546 { EmfPlusRecordTypeFillRects, 0xc000 },
1547 { EmfPlusRecordTypeEndOfFile },
1548 { EMR_EOF },
1549 { 0 }
1550 };
1551
1552 static void test_worldtransform(void)
1553 {
1554 GpStatus stat;
1555 GpMetafile *metafile;
1556 GpGraphics *graphics;
1557 HDC hdc;
1558 static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
1559 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1560 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1561 GpBitmap *bitmap;
1562 ARGB color;
1563 GpBrush *brush;
1564 GpMatrix *transform;
1565 BOOL identity;
1566 REAL elements[6];
1567
1568 hdc = CreateCompatibleDC(0);
1569
1570 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
1571 expect(Ok, stat);
1572
1573 DeleteDC(hdc);
1574
1575 if (stat != Ok)
1576 return;
1577
1578 stat = GdipCreateMatrix(&transform);
1579 expect(Ok, stat);
1580
1581 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1582 expect(Ok, stat);
1583
1584 /* initial transform */
1585 stat = GdipGetWorldTransform(graphics, transform);
1586 expect(Ok, stat);
1587
1588 stat = GdipIsMatrixIdentity(transform, &identity);
1589 expect(Ok, stat);
1590 expect(TRUE, identity);
1591
1592 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
1593 expect(Ok, stat);
1594
1595 stat = GdipFillRectangleI(graphics, brush, 0, 0, 1, 1);
1596 expect(Ok, stat);
1597
1598 stat = GdipDeleteBrush(brush);
1599 expect(Ok, stat);
1600
1601 /* scale transform */
1602 stat = GdipScaleWorldTransform(graphics, 2.0, 4.0, MatrixOrderPrepend);
1603 expect(Ok, stat);
1604
1605 stat = GdipGetWorldTransform(graphics, transform);
1606 expect(Ok, stat);
1607
1608 stat = GdipGetMatrixElements(transform, elements);
1609 expect(Ok, stat);
1610 expectf(2.0, elements[0]);
1611 expectf(0.0, elements[1]);
1612 expectf(0.0, elements[2]);
1613 expectf(4.0, elements[3]);
1614 expectf(0.0, elements[4]);
1615 expectf(0.0, elements[5]);
1616
1617 stat = GdipCreateSolidFill((ARGB)0xff00ff00, (GpSolidFill**)&brush);
1618 expect(Ok, stat);
1619
1620 stat = GdipFillRectangle(graphics, brush, 0.5, 0.5, 0.5, 0.25);
1621 expect(Ok, stat);
1622
1623 stat = GdipDeleteBrush(brush);
1624 expect(Ok, stat);
1625
1626 /* reset transform */
1627 stat = GdipResetWorldTransform(graphics);
1628 expect(Ok, stat);
1629
1630 stat = GdipGetWorldTransform(graphics, transform);
1631 expect(Ok, stat);
1632
1633 stat = GdipIsMatrixIdentity(transform, &identity);
1634 expect(Ok, stat);
1635 expect(TRUE, identity);
1636
1637 stat = GdipCreateSolidFill((ARGB)0xff00ffff, (GpSolidFill**)&brush);
1638 expect(Ok, stat);
1639
1640 stat = GdipFillRectangle(graphics, brush, 1.0, 0.0, 1.0, 1.0);
1641 expect(Ok, stat);
1642
1643 stat = GdipDeleteBrush(brush);
1644 expect(Ok, stat);
1645
1646 /* multiply transform */
1647 stat = GdipSetMatrixElements(transform, 2.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1648 expect(Ok, stat);
1649
1650 stat = GdipMultiplyWorldTransform(graphics, transform, MatrixOrderPrepend);
1651 expect(Ok, stat);
1652
1653 stat = GdipGetWorldTransform(graphics, transform);
1654 expect(Ok, stat);
1655
1656 stat = GdipGetMatrixElements(transform, elements);
1657 expect(Ok, stat);
1658 expectf(2.0, elements[0]);
1659 expectf(0.0, elements[1]);
1660 expectf(0.0, elements[2]);
1661 expectf(1.0, elements[3]);
1662 expectf(0.0, elements[4]);
1663 expectf(0.0, elements[5]);
1664
1665 stat = GdipCreateSolidFill((ARGB)0xffff0000, (GpSolidFill**)&brush);
1666 expect(Ok, stat);
1667
1668 stat = GdipFillRectangle(graphics, brush, 1.0, 1.0, 0.5, 1.0);
1669 expect(Ok, stat);
1670
1671 stat = GdipDeleteBrush(brush);
1672 expect(Ok, stat);
1673
1674 /* rotate transform */
1675 stat = GdipRotateWorldTransform(graphics, 90.0, MatrixOrderAppend);
1676 expect(Ok, stat);
1677
1678 stat = GdipGetWorldTransform(graphics, transform);
1679 expect(Ok, stat);
1680
1681 stat = GdipGetMatrixElements(transform, elements);
1682 expect(Ok, stat);
1683 expectf(0.0, elements[0]);
1684 expectf(2.0, elements[1]);
1685 expectf(-1.0, elements[2]);
1686 expectf(0.0, elements[3]);
1687 expectf(0.0, elements[4]);
1688 expectf(0.0, elements[5]);
1689
1690 stat = GdipCreateSolidFill((ARGB)0xffff00ff, (GpSolidFill**)&brush);
1691 expect(Ok, stat);
1692
1693 stat = GdipFillRectangle(graphics, brush, 1.0, -1.0, 0.5, 1.0);
1694 expect(Ok, stat);
1695
1696 stat = GdipDeleteBrush(brush);
1697 expect(Ok, stat);
1698
1699 /* set transform */
1700 stat = GdipSetMatrixElements(transform, 1.0, 0.0, 0.0, 3.0, 0.0, 0.0);
1701 expect(Ok, stat);
1702
1703 stat = GdipSetWorldTransform(graphics, transform);
1704 expect(Ok, stat);
1705
1706 stat = GdipGetWorldTransform(graphics, transform);
1707 expect(Ok, stat);
1708
1709 stat = GdipGetMatrixElements(transform, elements);
1710 expect(Ok, stat);
1711 expectf(1.0, elements[0]);
1712 expectf(0.0, elements[1]);
1713 expectf(0.0, elements[2]);
1714 expectf(3.0, elements[3]);
1715 expectf(0.0, elements[4]);
1716 expectf(0.0, elements[5]);
1717
1718 stat = GdipCreateSolidFill((ARGB)0xffffff00, (GpSolidFill**)&brush);
1719 expect(Ok, stat);
1720
1721 stat = GdipFillRectangle(graphics, brush, 1.0, 1.0, 1.0, 1.0);
1722 expect(Ok, stat);
1723
1724 stat = GdipDeleteBrush(brush);
1725 expect(Ok, stat);
1726
1727 /* translate transform */
1728 stat = GdipTranslateWorldTransform(graphics, -1.0, 0.0, MatrixOrderAppend);
1729 expect(Ok, stat);
1730
1731 stat = GdipGetWorldTransform(graphics, transform);
1732 expect(Ok, stat);
1733
1734 stat = GdipGetMatrixElements(transform, elements);
1735 expect(Ok, stat);
1736 expectf(1.0, elements[0]);
1737 expectf(0.0, elements[1]);
1738 expectf(0.0, elements[2]);
1739 expectf(3.0, elements[3]);
1740 expectf(-1.0, elements[4]);
1741 expectf(0.0, elements[5]);
1742
1743 stat = GdipCreateSolidFill((ARGB)0xffffffff, (GpSolidFill**)&brush);
1744 expect(Ok, stat);
1745
1746 stat = GdipFillRectangle(graphics, brush, 1.0, 1.0, 1.0, 1.0);
1747 expect(Ok, stat);
1748
1749 stat = GdipDeleteBrush(brush);
1750 expect(Ok, stat);
1751
1752 stat = GdipDeleteMatrix(transform);
1753 expect(Ok, stat);
1754
1755 stat = GdipDeleteGraphics(graphics);
1756 expect(Ok, stat);
1757
1758 check_metafile(metafile, worldtransform_records, "worldtransform metafile", dst_points, &frame, UnitPixel);
1759
1760 sync_metafile(&metafile, "worldtransform.emf");
1761
1762 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
1763 expect(Ok, stat);
1764
1765 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1766 expect(Ok, stat);
1767
1768 play_metafile(metafile, graphics, worldtransform_records, "worldtransform playback", dst_points, &frame, UnitPixel);
1769
1770 stat = GdipBitmapGetPixel(bitmap, 80, 80, &color);
1771 expect(Ok, stat);
1772 expect(0, color);
1773
1774 stat = GdipBitmapGetPixel(bitmap, 10, 10, &color);
1775 expect(Ok, stat);
1776 expect(0xff0000ff, color);
1777
1778 stat = GdipBitmapGetPixel(bitmap, 30, 50, &color);
1779 expect(Ok, stat);
1780 expect(0xff00ff00, color);
1781
1782 stat = GdipBitmapGetPixel(bitmap, 30, 10, &color);
1783 expect(Ok, stat);
1784 expect(0xff00ffff, color);
1785
1786 stat = GdipBitmapGetPixel(bitmap, 50, 30, &color);
1787 expect(Ok, stat);
1788 expect(0xffff0000, color);
1789
1790 stat = GdipBitmapGetPixel(bitmap, 10, 50, &color);
1791 expect(Ok, stat);
1792 expect(0xffff00ff, color);
1793
1794 stat = GdipBitmapGetPixel(bitmap, 30, 90, &color);
1795 expect(Ok, stat);
1796 expect(0xffffff00, color);
1797
1798 stat = GdipBitmapGetPixel(bitmap, 10, 90, &color);
1799 expect(Ok, stat);
1800 expect(0xffffffff, color);
1801
1802 stat = GdipDeleteGraphics(graphics);
1803 expect(Ok, stat);
1804
1805 stat = GdipDisposeImage((GpImage*)bitmap);
1806 expect(Ok, stat);
1807
1808 stat = GdipDisposeImage((GpImage*)metafile);
1809 expect(Ok, stat);
1810 }
1811
1812 static void test_converttoemfplus(void)
1813 {
1814 GpStatus (WINAPI *pGdipConvertToEmfPlus)( const GpGraphics *graphics, GpMetafile *metafile, BOOL *succ,
1815 EmfType emfType, const WCHAR *description, GpMetafile **outmetafile);
1816 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
1817 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1818 GpStatus stat;
1819 GpMetafile *metafile, *metafile2 = NULL, *emhmeta;
1820 GpGraphics *graphics;
1821 HDC hdc;
1822 BOOL succ;
1823 HMODULE mod = GetModuleHandleA("gdiplus.dll");
1824
1825 pGdipConvertToEmfPlus = (void*)GetProcAddress( mod, "GdipConvertToEmfPlus");
1826 if(!pGdipConvertToEmfPlus)
1827 {
1828 /* GdipConvertToEmfPlus was introduced in Windows Vista. */
1829 win_skip("GDIPlus version 1.1 not available\n");
1830 return;
1831 }
1832
1833 hdc = CreateCompatibleDC(0);
1834
1835 stat = GdipRecordMetafile(hdc, MetafileTypeEmf, &frame, MetafileFrameUnitPixel, description, &metafile);
1836 expect(Ok, stat);
1837
1838 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &emhmeta);
1839 expect(Ok, stat);
1840
1841 DeleteDC(hdc);
1842
1843 if (stat != Ok)
1844 return;
1845
1846 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1847 expect(Ok, stat);
1848
1849 /* Invalid Parameters */
1850 stat = pGdipConvertToEmfPlus(NULL, metafile, &succ, EmfTypeEmfPlusOnly, description, &metafile2);
1851 expect(InvalidParameter, stat);
1852
1853 stat = pGdipConvertToEmfPlus(graphics, NULL, &succ, EmfTypeEmfPlusOnly, description, &metafile2);
1854 expect(InvalidParameter, stat);
1855
1856 stat = pGdipConvertToEmfPlus(graphics, metafile, &succ, EmfTypeEmfPlusOnly, description, NULL);
1857 expect(InvalidParameter, stat);
1858
1859 stat = pGdipConvertToEmfPlus(graphics, metafile, NULL, MetafileTypeInvalid, NULL, &metafile2);
1860 expect(InvalidParameter, stat);
1861
1862 stat = pGdipConvertToEmfPlus(graphics, metafile, NULL, MetafileTypeEmfPlusDual+1, NULL, &metafile2);
1863 expect(InvalidParameter, stat);
1864
1865 /* If we are already an Enhanced Metafile then the conversion fails. */
1866 stat = pGdipConvertToEmfPlus(graphics, emhmeta, NULL, EmfTypeEmfPlusOnly, NULL, &metafile2);
1867 todo_wine expect(InvalidParameter, stat);
1868
1869 stat = pGdipConvertToEmfPlus(graphics, metafile, NULL, EmfTypeEmfPlusOnly, NULL, &metafile2);
1870 todo_wine expect(Ok, stat);
1871 if(metafile2)
1872 GdipDisposeImage((GpImage*)metafile2);
1873
1874 succ = FALSE;
1875 stat = pGdipConvertToEmfPlus(graphics, metafile, &succ, EmfTypeEmfPlusOnly, NULL, &metafile2);
1876 todo_wine expect(Ok, stat);
1877 if(metafile2)
1878 GdipDisposeImage((GpImage*)metafile2);
1879
1880 stat = GdipDeleteGraphics(graphics);
1881 expect(Ok, stat);
1882
1883 stat = GdipDisposeImage((GpImage*)metafile);
1884 expect(Ok, stat);
1885
1886 stat = GdipDisposeImage((GpImage*)emhmeta);
1887 expect(Ok, stat);
1888 }
1889
1890 static void test_frameunit(void)
1891 {
1892 GpStatus stat;
1893 GpMetafile *metafile;
1894 GpGraphics *graphics;
1895 HDC hdc;
1896 static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
1897 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1898 GpUnit unit;
1899 REAL dpix, dpiy;
1900 GpRectF bounds;
1901
1902 hdc = CreateCompatibleDC(0);
1903
1904 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitInch, description, &metafile);
1905 expect(Ok, stat);
1906
1907 DeleteDC(hdc);
1908
1909 if (stat != Ok)
1910 return;
1911
1912 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1913 expect(Ok, stat);
1914 expect(UnitPixel, unit);
1915 expectf(0.0, bounds.X);
1916 expectf(0.0, bounds.Y);
1917 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
1918 "expected 1.0, got %f\n", bounds.Width);
1919 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
1920 "expected 1.0, got %f\n", bounds.Height);
1921
1922 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1923 expect(Ok, stat);
1924
1925 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1926 expect(Ok, stat);
1927 expect(UnitPixel, unit);
1928 expectf(0.0, bounds.X);
1929 expectf(0.0, bounds.Y);
1930 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
1931 "expected 1.0, got %f\n", bounds.Width);
1932 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
1933 "expected 1.0, got %f\n", bounds.Height);
1934
1935 stat = GdipDeleteGraphics(graphics);
1936 expect(Ok, stat);
1937
1938 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &dpix);
1939 expect(Ok, stat);
1940
1941 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &dpiy);
1942 expect(Ok, stat);
1943
1944 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1945 expect(Ok, stat);
1946 expect(UnitPixel, unit);
1947 expectf(0.0, bounds.X);
1948 expectf(0.0, bounds.Y);
1949 expectf_(5.0 * dpix, bounds.Width, 1.0);
1950 expectf_(5.0 * dpiy, bounds.Height, 1.0);
1951
1952 stat = GdipDisposeImage((GpImage*)metafile);
1953 expect(Ok, stat);
1954 }
1955
1956 static const emfplus_record container_records[] = {
1957 { EMR_HEADER },
1958 { EmfPlusRecordTypeHeader },
1959 { EmfPlusRecordTypeBeginContainerNoParams },
1960 { EmfPlusRecordTypeScaleWorldTransform },
1961 { EmfPlusRecordTypeFillRects, 0xc000 },
1962 { EmfPlusRecordTypeEndContainer },
1963 { EmfPlusRecordTypeScaleWorldTransform },
1964 { EmfPlusRecordTypeFillRects, 0xc000 },
1965 { EmfPlusRecordTypeSave },
1966 { EmfPlusRecordTypeRestore },
1967 { EmfPlusRecordTypeScaleWorldTransform },
1968 { EmfPlusRecordTypeBeginContainerNoParams },
1969 { EmfPlusRecordTypeScaleWorldTransform },
1970 { EmfPlusRecordTypeBeginContainerNoParams },
1971 { EmfPlusRecordTypeEndContainer },
1972 { EmfPlusRecordTypeFillRects, 0xc000 },
1973 { EmfPlusRecordTypeBeginContainer, UnitInch },
1974 { EmfPlusRecordTypeFillRects, 0xc000 },
1975 { EmfPlusRecordTypeEndContainer },
1976 { EmfPlusRecordTypeBeginContainerNoParams },
1977 { EmfPlusRecordTypeEndOfFile },
1978 { EMR_EOF },
1979 { 0 }
1980 };
1981
1982 static void test_containers(void)
1983 {
1984 GpStatus stat;
1985 GpMetafile *metafile;
1986 GpGraphics *graphics;
1987 GpBitmap *bitmap;
1988 GpBrush *brush;
1989 ARGB color;
1990 HDC hdc;
1991 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
1992 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1993 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1994 GraphicsContainer state1, state2;
1995 GpRectF srcrect, dstrect;
1996 REAL dpix, dpiy;
1997
1998 hdc = CreateCompatibleDC(0);
1999
2000 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2001 expect(Ok, stat);
2002
2003 DeleteDC(hdc);
2004
2005 if (stat != Ok)
2006 return;
2007
2008 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2009 expect(Ok, stat);
2010
2011 /* Normal usage */
2012 stat = GdipBeginContainer2(graphics, &state1);
2013 expect(Ok, stat);
2014
2015 stat = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
2016 expect(Ok, stat);
2017
2018 stat = GdipCreateSolidFill((ARGB)0xff000000, (GpSolidFill**)&brush);
2019 expect(Ok, stat);
2020
2021 stat = GdipFillRectangle(graphics, brush, 5.0, 5.0, 5.0, 5.0);
2022 expect(Ok, stat);
2023
2024 stat = GdipDeleteBrush(brush);
2025 expect(Ok, stat);
2026
2027 stat = GdipEndContainer(graphics, state1);
2028 expect(Ok, stat);
2029
2030 stat = GdipScaleWorldTransform(graphics, 1.0, 1.0, MatrixOrderPrepend);
2031 expect(Ok, stat);
2032
2033 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
2034 expect(Ok, stat);
2035
2036 stat = GdipFillRectangle(graphics, brush, 5.0, 5.0, 5.0, 5.0);
2037 expect(Ok, stat);
2038
2039 stat = GdipDeleteBrush(brush);
2040 expect(Ok, stat);
2041
2042 stat = GdipSaveGraphics(graphics, &state1);
2043 expect(Ok, stat);
2044
2045 stat = GdipRestoreGraphics(graphics, state1);
2046 expect(Ok, stat);
2047
2048 /* Popping two states at once */
2049 stat = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
2050 expect(Ok, stat);
2051
2052 stat = GdipBeginContainer2(graphics, &state1);
2053 expect(Ok, stat);
2054
2055 stat = GdipScaleWorldTransform(graphics, 4.0, 4.0, MatrixOrderPrepend);
2056 expect(Ok, stat);
2057
2058 stat = GdipBeginContainer2(graphics, &state2);
2059 expect(Ok, stat);
2060
2061 stat = GdipEndContainer(graphics, state1);
2062 expect(Ok, stat);
2063
2064 stat = GdipCreateSolidFill((ARGB)0xff00ff00, (GpSolidFill**)&brush);
2065 expect(Ok, stat);
2066
2067 stat = GdipFillRectangle(graphics, brush, 20.0, 20.0, 5.0, 5.0);
2068 expect(Ok, stat);
2069
2070 stat = GdipDeleteBrush(brush);
2071 expect(Ok, stat);
2072
2073 /* With transform applied */
2074 stat = GdipGetDpiX(graphics, &dpix);
2075 expect(Ok, stat);
2076
2077 stat = GdipGetDpiY(graphics, &dpiy);
2078 expect(Ok, stat);
2079
2080 srcrect.X = 0.0;
2081 srcrect.Y = 0.0;
2082 srcrect.Width = 1.0;
2083 srcrect.Height = 1.0;
2084
2085 dstrect.X = 25.0;
2086 dstrect.Y = 0.0;
2087 dstrect.Width = 5.0;
2088 dstrect.Height = 5.0;
2089
2090 stat = GdipBeginContainer(graphics, &dstrect, &srcrect, UnitInch, &state1);
2091 expect(Ok, stat);
2092
2093 stat = GdipCreateSolidFill((ARGB)0xff00ffff, (GpSolidFill**)&brush);
2094 expect(Ok, stat);
2095
2096 stat = GdipFillRectangle(graphics, brush, 0.0, 0.0, dpix, dpiy);
2097 expect(Ok, stat);
2098
2099 stat = GdipDeleteBrush(brush);
2100 expect(Ok, stat);
2101
2102 stat = GdipEndContainer(graphics, state1);
2103 expect(Ok, stat);
2104
2105 /* Restoring an invalid state seems to break the graphics object? */
2106 if (0) {
2107 stat = GdipEndContainer(graphics, state1);
2108 expect(Ok, stat);
2109 }
2110
2111 /* Ending metafile with a state open */
2112 stat = GdipBeginContainer2(graphics, &state1);
2113 expect(Ok, stat);
2114
2115 stat = GdipDeleteGraphics(graphics);
2116 expect(Ok, stat);
2117
2118 check_metafile(metafile, container_records, "container metafile", dst_points, &frame, UnitPixel);
2119
2120 sync_metafile(&metafile, "container.emf");
2121
2122 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
2123 expect(Ok, stat);
2124
2125 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2126 expect(Ok, stat);
2127
2128 play_metafile(metafile, graphics, container_records, "container playback", dst_points, &frame, UnitPixel);
2129
2130 stat = GdipBitmapGetPixel(bitmap, 80, 80, &color);
2131 expect(Ok, stat);
2132 expect(0, color);
2133
2134 stat = GdipBitmapGetPixel(bitmap, 12, 12, &color);
2135 expect(Ok, stat);
2136 expect(0xff000000, color);
2137
2138 stat = GdipBitmapGetPixel(bitmap, 8, 8, &color);
2139 expect(Ok, stat);
2140 expect(0xff0000ff, color);
2141
2142 stat = GdipBitmapGetPixel(bitmap, 42, 42, &color);
2143 expect(Ok, stat);
2144 expect(0xff00ff00, color);
2145
2146 stat = GdipBitmapGetPixel(bitmap, 55, 5, &color);
2147 expect(Ok, stat);
2148 expect(0xff00ffff, color);
2149
2150 stat = GdipDeleteGraphics(graphics);
2151 expect(Ok, stat);
2152
2153 stat = GdipDisposeImage((GpImage*)bitmap);
2154 expect(Ok, stat);
2155
2156 stat = GdipDisposeImage((GpImage*)metafile);
2157 expect(Ok, stat);
2158 }
2159
2160 static const emfplus_record clipping_records[] = {
2161 { EMR_HEADER },
2162 { EmfPlusRecordTypeHeader },
2163 { EmfPlusRecordTypeSave },
2164 { EmfPlusRecordTypeSetClipRect },
2165 { EmfPlusRecordTypeFillRects, 0xc000 },
2166 { EmfPlusRecordTypeRestore },
2167 { EmfPlusRecordTypeSetClipRect, 0x300 },
2168 { EmfPlusRecordTypeFillRects, 0xc000 },
2169 { EmfPlusRecordTypeObject, ObjectTypeRegion << 8 },
2170 { EmfPlusRecordTypeSetClipRegion, 0x100 },
2171 { EmfPlusRecordTypeEndOfFile },
2172 { EMR_EOF },
2173 { 0 }
2174 };
2175
2176 static void test_clipping(void)
2177 {
2178 GpStatus stat;
2179 GpMetafile *metafile;
2180 GpGraphics *graphics;
2181 GpBitmap *bitmap;
2182 GpRegion *region;
2183 GpBrush *brush;
2184 GpRectF rect;
2185 ARGB color;
2186 HDC hdc;
2187 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
2188 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
2189 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
2190 GraphicsState state;
2191
2192 hdc = CreateCompatibleDC(0);
2193
2194 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2195 expect(Ok, stat);
2196
2197 DeleteDC(hdc);
2198
2199 if (stat != Ok)
2200 return;
2201
2202 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2203 expect(Ok, stat);
2204
2205 stat = GdipSaveGraphics(graphics, &state);
2206 expect(Ok, stat);
2207
2208 stat = GdipGetVisibleClipBounds(graphics, &rect);
2209 expect(Ok, stat);
2210 ok(rect.X == -0x400000, "rect.X = %f\n", rect.X);
2211 ok(rect.Y == -0x400000, "rect.Y = %f\n", rect.Y);
2212 ok(rect.Width == 0x800000, "rect.Width = %f\n", rect.Width);
2213 ok(rect.Height == 0x800000, "rect.Height = %f\n", rect.Height);
2214
2215 stat = GdipSetClipRect(graphics, 30, 30, 10, 10, CombineModeReplace);
2216 expect(Ok, stat);
2217
2218 stat = GdipGetVisibleClipBounds(graphics, &rect);
2219 expect(Ok, stat);
2220 ok(rect.X == 30, "rect.X = %f\n", rect.X);
2221 ok(rect.Y == 30, "rect.Y = %f\n", rect.Y);
2222 ok(rect.Width == 10, "rect.Width = %f\n", rect.Width);
2223 ok(rect.Height == 10, "rect.Height = %f\n", rect.Height);
2224
2225 stat = GdipCreateSolidFill((ARGB)0xff000000, (GpSolidFill**)&brush);
2226 expect(Ok, stat);
2227
2228 stat = GdipFillRectangle(graphics, brush, 0, 0, 100, 100);
2229 expect(Ok, stat);
2230
2231 stat = GdipDeleteBrush(brush);
2232 expect(Ok, stat);
2233
2234 stat = GdipRestoreGraphics(graphics, state);
2235 expect(Ok, stat);
2236
2237 stat = GdipSetClipRect(graphics, 30, 30, 10, 10, CombineModeXor);
2238 expect(Ok, stat);
2239
2240 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
2241 expect(Ok, stat);
2242
2243 stat = GdipFillRectangle(graphics, brush, 30, 30, 20, 10);
2244 expect(Ok, stat);
2245
2246 stat = GdipDeleteBrush(brush);
2247 expect(Ok, stat);
2248
2249 stat = GdipCreateRegionRect(&rect, &region);
2250 expect(Ok, stat);
2251
2252 stat = GdipSetClipRegion(graphics, region, CombineModeIntersect);
2253 expect(Ok, stat);
2254
2255 stat = GdipDeleteRegion(region);
2256 expect(Ok, stat);
2257
2258 stat = GdipDeleteGraphics(graphics);
2259 expect(Ok, stat);
2260
2261 check_metafile(metafile, clipping_records, "clipping metafile", dst_points, &frame, UnitPixel);
2262
2263 sync_metafile(&metafile, "clipping.emf");
2264
2265 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
2266 expect(Ok, stat);
2267
2268 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2269 expect(Ok, stat);
2270
2271 play_metafile(metafile, graphics, clipping_records, "clipping playback", dst_points, &frame, UnitPixel);
2272
2273 stat = GdipBitmapGetPixel(bitmap, 80, 80, &color);
2274 expect(Ok, stat);
2275 expect(0, color);
2276
2277 stat = GdipBitmapGetPixel(bitmap, 35, 35, &color);
2278 expect(Ok, stat);
2279 expect(0xff000000, color);
2280
2281 stat = GdipBitmapGetPixel(bitmap, 45, 35, &color);
2282 expect(Ok, stat);
2283 expect(0xff0000ff, color);
2284
2285 stat = GdipDeleteGraphics(graphics);
2286 expect(Ok, stat);
2287
2288 stat = GdipDisposeImage((GpImage*)bitmap);
2289 expect(Ok, stat);
2290
2291 stat = GdipDisposeImage((GpImage*)metafile);
2292 expect(Ok, stat);
2293 }
2294
2295 static void test_gditransform_cb(GpMetafile* metafile, EmfPlusRecordType record_type,
2296 unsigned int flags, unsigned int dataSize, const unsigned char *pStr)
2297 {
2298 static const XFORM xform = {0.5, 0, 0, 0.5, 0, 0};
2299 static const RECTL rectangle = {0,0,100,100};
2300 GpStatus stat;
2301
2302 stat = GdipPlayMetafileRecord(metafile, EMR_SETWORLDTRANSFORM, 0, sizeof(xform), (void*)&xform);
2303 expect(Ok, stat);
2304
2305 stat = GdipPlayMetafileRecord(metafile, EMR_RECTANGLE, 0, sizeof(rectangle), (void*)&rectangle);
2306 expect(Ok, stat);
2307 }
2308
2309 static const emfplus_record gditransform_records[] = {
2310 { EMR_HEADER },
2311 { EMR_CREATEBRUSHINDIRECT },
2312 { EMR_SELECTOBJECT },
2313 { EMR_GDICOMMENT, 0, 0, 0, test_gditransform_cb },
2314 { EMR_SELECTOBJECT },
2315 { EMR_DELETEOBJECT },
2316 { EMR_EOF },
2317 { 0 }
2318 };
2319
2320 static void test_gditransform(void)
2321 {
2322 GpStatus stat;
2323 GpMetafile *metafile;
2324 GpGraphics *graphics;
2325 HDC hdc, metafile_dc;
2326 HENHMETAFILE hemf;
2327 MetafileHeader header;
2328 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
2329 static const GpPointF dst_points[3] = {{0.0,0.0},{40.0,0.0},{0.0,40.0}};
2330 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
2331 HBRUSH hbrush, holdbrush;
2332 GpBitmap *bitmap;
2333 ARGB color;
2334
2335 hdc = CreateCompatibleDC(0);
2336
2337 stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2338 expect(Ok, stat);
2339
2340 DeleteDC(hdc);
2341
2342 if (stat != Ok)
2343 return;
2344
2345 stat = GdipGetHemfFromMetafile(metafile, &hemf);
2346 expect(InvalidParameter, stat);
2347
2348 memset(&header, 0xaa, sizeof(header));
2349 stat = GdipGetMetafileHeaderFromMetafile(metafile, &header);
2350 expect(Ok, stat);
2351 expect(MetafileTypeEmf, header.Type);
2352 ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
2353
2354 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2355 expect(Ok, stat);
2356
2357 stat = GdipGetDC(graphics, &metafile_dc);
2358 expect(Ok, stat);
2359
2360 if (stat != Ok)
2361 {
2362 GdipDeleteGraphics(graphics);
2363 GdipDisposeImage((GpImage*)metafile);
2364 return;
2365 }
2366
2367 hbrush = CreateSolidBrush(0xff);
2368
2369 holdbrush = SelectObject(metafile_dc, hbrush);
2370
2371 GdiComment(metafile_dc, 8, (const BYTE*)"winetest");
2372
2373 SelectObject(metafile_dc, holdbrush);
2374
2375 DeleteObject(hbrush);
2376
2377 stat = GdipReleaseDC(graphics, metafile_dc);
2378 expect(Ok, stat);
2379
2380 stat = GdipDeleteGraphics(graphics);
2381 expect(Ok, stat);
2382
2383 check_metafile(metafile, gditransform_records, "gditransform metafile", dst_points, &frame, UnitPixel);
2384
2385 sync_metafile(&metafile, "gditransform.emf");
2386
2387 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
2388 expect(Ok, stat);
2389
2390 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2391 expect(Ok, stat);
2392
2393 play_metafile(metafile, graphics, gditransform_records, "gditransform playback", dst_points, &frame, UnitPixel);
2394
2395 stat = GdipBitmapGetPixel(bitmap, 10, 10, &color);
2396 expect(Ok, stat);
2397 expect(0xffff0000, color);
2398
2399 stat = GdipBitmapGetPixel(bitmap, 30, 30, &color);
2400 expect(Ok, stat);
2401 expect(0x00000000, color);
2402
2403 stat = GdipDeleteGraphics(graphics);
2404 expect(Ok, stat);
2405
2406 stat = GdipDisposeImage((GpImage*)bitmap);
2407 expect(Ok, stat);
2408
2409 stat = GdipDisposeImage((GpImage*)metafile);
2410 expect(Ok, stat);
2411 }
2412
2413 static const emfplus_record draw_image_bitmap_records[] = {
2414 { EMR_HEADER },
2415 { EmfPlusRecordTypeHeader },
2416 { EmfPlusRecordTypeObject, ObjectTypeImage << 8 },
2417 { EmfPlusRecordTypeObject, (ObjectTypeImageAttributes << 8) | 1 },
2418 { EmfPlusRecordTypeDrawImagePoints, 0, 0, 0, NULL, 0x4000 },
2419 { EMR_SAVEDC, 0, 1 },
2420 { EMR_SETICMMODE, 0, 1 },
2421 { EMR_BITBLT, 0, 1 },
2422 { EMR_RESTOREDC, 0, 1 },
2423 { EmfPlusRecordTypeEndOfFile },
2424 { EMR_EOF },
2425 { 0 }
2426 };
2427
2428 static const emfplus_record draw_image_metafile_records[] = {
2429 { EMR_HEADER },
2430 { EmfPlusRecordTypeHeader },
2431 { EmfPlusRecordTypeObject, ObjectTypeImage << 8 },
2432 /* metafile object */
2433 { EMR_HEADER },
2434 { EmfPlusRecordTypeHeader },
2435 { EmfPlusRecordTypeObject, ObjectTypeImage << 8 },
2436 { EmfPlusRecordTypeObject, (ObjectTypeImageAttributes << 8) | 1 },
2437 { EmfPlusRecordTypeDrawImagePoints },
2438 { EMR_SAVEDC, 0, 1 },
2439 { EMR_SETICMMODE, 0, 1 },
2440 { EMR_BITBLT, 0, 1 },
2441 { EMR_RESTOREDC, 0, 1 },
2442 { EmfPlusRecordTypeEndOfFile },
2443 { EMR_EOF },
2444 /* end of metafile object */
2445 { EmfPlusRecordTypeDrawImagePoints },
2446 { EMR_SAVEDC, 0, 1 },
2447 { EMR_SETICMMODE, 0, 1 },
2448 { EMR_BITBLT, 0, 1 },
2449 { EMR_RESTOREDC, 0, 1 },
2450 { EmfPlusRecordTypeEndOfFile },
2451 { EMR_EOF },
2452 { 0 }
2453 };
2454
2455 static void test_drawimage(void)
2456 {
2457 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
2458 static const GpPointF dst_points[3] = {{10.0,10.0},{85.0,15.0},{10.0,80.0}};
2459 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
2460 const ColorMatrix double_red = {{
2461 {2.0,0.0,0.0,0.0,0.0},
2462 {0.0,1.0,0.0,0.0,0.0},
2463 {0.0,0.0,1.0,0.0,0.0},
2464 {0.0,0.0,0.0,1.0,0.0},
2465 {0.0,0.0,0.0,0.0,1.0}}};
2466
2467 GpImageAttributes *imageattr;
2468 GpMetafile *metafile;
2469 GpGraphics *graphics;
2470 HENHMETAFILE hemf;
2471 GpStatus stat;
2472 BITMAPINFO info;
2473 BYTE buff[400];
2474 GpImage *image;
2475 HDC hdc;
2476
2477 hdc = CreateCompatibleDC(0);
2478 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2479 expect(Ok, stat);
2480
2481 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2482 expect(Ok, stat);
2483
2484 memset(&info, 0, sizeof(info));
2485 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2486 info.bmiHeader.biWidth = 10;
2487 info.bmiHeader.biHeight = 10;
2488 info.bmiHeader.biPlanes = 1;
2489 info.bmiHeader.biBitCount = 32;
2490 info.bmiHeader.biCompression = BI_RGB;
2491 memset(buff, 0x80, sizeof(buff));
2492 stat = GdipCreateBitmapFromGdiDib(&info, buff, (GpBitmap**)&image);
2493 expect(Ok, stat);
2494
2495 stat = GdipCreateImageAttributes(&imageattr);
2496 expect(Ok, stat);
2497
2498 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2499 TRUE, &double_red, NULL, ColorMatrixFlagsDefault);
2500 expect(Ok, stat);
2501
2502 stat = GdipDrawImagePointsRect(graphics, image, dst_points, 3,
2503 0.0, 0.0, 10.0, 10.0, UnitPixel, imageattr, NULL, NULL);
2504 GdipDisposeImageAttributes(imageattr);
2505 expect(Ok, stat);
2506
2507 GdipDisposeImage(image);
2508
2509 stat = GdipDeleteGraphics(graphics);
2510 expect(Ok, stat);
2511 sync_metafile(&metafile, "draw_image_bitmap.emf");
2512
2513 stat = GdipGetHemfFromMetafile(metafile, &hemf);
2514 expect(Ok, stat);
2515
2516 check_emfplus(hemf, draw_image_bitmap_records, "draw image bitmap");
2517
2518 /* test drawing metafile */
2519 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2520 expect(Ok, stat);
2521
2522 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2523 expect(Ok, stat);
2524
2525 stat = GdipCreateMetafileFromEmf(hemf, TRUE, (GpMetafile**)&image);
2526 expect(Ok, stat);
2527
2528 stat = GdipDrawImagePointsRect(graphics, image, dst_points, 3,
2529 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
2530 expect(Ok, stat);
2531
2532 GdipDisposeImage(image);
2533
2534 stat = GdipDeleteGraphics(graphics);
2535 expect(Ok, stat);
2536 sync_metafile(&metafile, "draw_image_metafile.emf");
2537
2538 stat = GdipGetHemfFromMetafile(metafile, &hemf);
2539 expect(Ok, stat);
2540
2541 if (GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipConvertToEmfPlus"))
2542 {
2543 check_emfplus(hemf, draw_image_metafile_records, "draw image metafile");
2544 }
2545 else
2546 {
2547 win_skip("draw image metafile records tests skipped\n");
2548 }
2549 DeleteEnhMetaFile(hemf);
2550
2551 DeleteDC(hdc);
2552 stat = GdipDisposeImage((GpImage*)metafile);
2553 expect(Ok, stat);
2554 }
2555
2556 static const emfplus_record properties_records[] = {
2557 { EMR_HEADER },
2558 { EmfPlusRecordTypeHeader },
2559 { EmfPlusRecordTypeSetTextRenderingHint, TextRenderingHintAntiAlias },
2560 { EmfPlusRecordTypeSetPixelOffsetMode, PixelOffsetModeHighQuality },
2561 { EmfPlusRecordTypeSetAntiAliasMode, (SmoothingModeAntiAlias << 1) | 1, 0, 0, NULL, 0x1 },
2562 { EmfPlusRecordTypeSetCompositingMode, CompositingModeSourceCopy },
2563 { EmfPlusRecordTypeSetCompositingQuality, CompositingQualityHighQuality },
2564 { EmfPlusRecordTypeSetInterpolationMode, InterpolationModeHighQualityBicubic },
2565 { EmfPlusRecordTypeEndOfFile },
2566 { EMR_EOF },
2567 { 0 }
2568 };
2569
2570 static void test_properties(void)
2571 {
2572 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
2573 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
2574
2575 GpMetafile *metafile;
2576 GpGraphics *graphics;
2577 HENHMETAFILE hemf;
2578 GpStatus stat;
2579 HDC hdc;
2580
2581 hdc = CreateCompatibleDC(0);
2582 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2583 expect(Ok, stat);
2584 DeleteDC(hdc);
2585
2586 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2587 expect(Ok, stat);
2588
2589 stat = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
2590 expect(Ok, stat);
2591 stat = GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAlias);
2592 expect(Ok, stat);
2593
2594 stat = GdipSetPixelOffsetMode(graphics, PixelOffsetModeHighQuality);
2595 expect(Ok, stat);
2596 stat = GdipSetPixelOffsetMode(graphics, PixelOffsetModeHighQuality);
2597 expect(Ok, stat);
2598
2599 stat = GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias);
2600 expect(Ok, stat);
2601 stat = GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias);
2602 expect(Ok, stat);
2603
2604 stat = GdipSetCompositingMode(graphics, CompositingModeSourceOver);
2605 expect(Ok, stat);
2606 stat = GdipSetCompositingMode(graphics, CompositingModeSourceCopy);
2607 expect(Ok, stat);
2608
2609 stat = GdipSetCompositingQuality(graphics, CompositingQualityHighQuality);
2610 expect(Ok, stat);
2611 stat = GdipSetCompositingQuality(graphics, CompositingQualityHighQuality);
2612 expect(Ok, stat);
2613
2614 stat = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
2615 expect(Ok, stat);
2616 stat = GdipSetInterpolationMode(graphics, InterpolationModeHighQuality);
2617 expect(Ok, stat);
2618
2619 stat = GdipDeleteGraphics(graphics);
2620 expect(Ok, stat);
2621 sync_metafile(&metafile, "properties.emf");
2622
2623 stat = GdipGetHemfFromMetafile(metafile, &hemf);
2624 expect(Ok, stat);
2625
2626 check_emfplus(hemf, properties_records, "properties");
2627 DeleteEnhMetaFile(hemf);
2628
2629 stat = GdipDisposeImage((GpImage*)metafile);
2630 expect(Ok, stat);
2631 }
2632
2633 static const emfplus_record draw_path_records[] = {
2634 { EMR_HEADER },
2635 { EmfPlusRecordTypeHeader },
2636 { EmfPlusRecordTypeObject, ObjectTypePen << 8 },
2637 { EmfPlusRecordTypeObject, (ObjectTypePath << 8) | 1 },
2638 { EmfPlusRecordTypeDrawPath, 1 },
2639 { EMR_SAVEDC, 0, 1 },
2640 { EMR_SETICMMODE, 0, 1 },
2641 { EMR_BITBLT, 0, 1 },
2642 { EMR_RESTOREDC, 0, 1 },
2643 { EmfPlusRecordTypeEndOfFile },
2644 { EMR_EOF },
2645 { 0 }
2646 };
2647
2648 static void test_drawpath(void)
2649 {
2650 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
2651 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
2652
2653 GpMetafile *metafile;
2654 GpGraphics *graphics;
2655 HENHMETAFILE hemf;
2656 GpStatus stat;
2657 GpPath *path;
2658 GpPen *pen;
2659 HDC hdc;
2660
2661 hdc = CreateCompatibleDC(0);
2662 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2663 expect(Ok, stat);
2664 DeleteDC(hdc);
2665
2666 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2667 expect(Ok, stat);
2668
2669 stat = GdipCreatePath(FillModeAlternate, &path);
2670 expect(Ok, stat);
2671 stat = GdipAddPathLine(path, 5, 5, 30, 30);
2672 expect(Ok, stat);
2673
2674 stat = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
2675 expect(Ok, stat);
2676
2677 stat = GdipDrawPath(graphics, pen, path);
2678 expect(Ok, stat);
2679
2680 stat = GdipDeletePen(pen);
2681 expect(Ok, stat);
2682 stat = GdipDeletePath(path);
2683 expect(Ok, stat);
2684
2685 stat = GdipDeleteGraphics(graphics);
2686 expect(Ok, stat);
2687 sync_metafile(&metafile, "draw_path.emf");
2688
2689 stat = GdipGetHemfFromMetafile(metafile, &hemf);
2690 expect(Ok, stat);
2691
2692 check_emfplus(hemf, draw_path_records, "draw path");
2693 DeleteEnhMetaFile(hemf);
2694
2695 stat = GdipDisposeImage((GpImage*)metafile);
2696 expect(Ok, stat);
2697 }
2698
2699 static const emfplus_record fill_path_records[] = {
2700 { EMR_HEADER },
2701 { EmfPlusRecordTypeHeader },
2702 { EmfPlusRecordTypeObject, ObjectTypePath << 8 },
2703 { EmfPlusRecordTypeFillPath, 0x8000 },
2704 { EMR_SAVEDC, 0, 1 },
2705 { EMR_SETICMMODE, 0, 1 },
2706 { EMR_BITBLT, 0, 1 },
2707 { EMR_RESTOREDC, 0, 1 },
2708 { EmfPlusRecordTypeEndOfFile },
2709 { EMR_EOF },
2710 { 0 }
2711 };
2712
2713 static void test_fillpath(void)
2714 {
2715 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
2716 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
2717 static const WCHAR winetestemfW[] = {'w','i','n','e','t','e','s','t','.','e','m','f',0};
2718
2719 GpMetafile *metafile;
2720 GpGraphics *graphics;
2721 GpSolidFill *brush;
2722 HENHMETAFILE hemf;
2723 GpStatus stat;
2724 GpPath *path;
2725 HDC hdc;
2726
2727 hdc = CreateCompatibleDC(0);
2728 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
2729 expect(Ok, stat);
2730 DeleteDC(hdc);
2731
2732 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
2733 expect(Ok, stat);
2734
2735 stat = GdipCreatePath(FillModeAlternate, &path);
2736 expect(Ok, stat);
2737 stat = GdipAddPathLine(path, 5, 5, 30, 30);
2738 expect(Ok, stat);
2739 stat = GdipAddPathLine(path, 30, 30, 5, 30);
2740 expect(Ok, stat);
2741
2742 stat = GdipCreateSolidFill(0xffaabbcc, &brush);
2743 expect(Ok, stat);
2744
2745 stat = GdipFillPath(graphics, (GpBrush*)brush, path);
2746 expect(Ok, stat);
2747
2748 stat = GdipDeleteBrush((GpBrush*)brush);
2749 expect(Ok, stat);
2750 stat = GdipDeletePath(path);
2751 expect(Ok, stat);
2752
2753 stat = GdipDeleteGraphics(graphics);
2754 expect(Ok, stat);
2755 sync_metafile(&metafile, "fill_path.emf");
2756
2757 stat = GdipGetHemfFromMetafile(metafile, &hemf);
2758 expect(Ok, stat);
2759
2760 check_emfplus(hemf, fill_path_records, "fill path");
2761
2762 /* write to disk */
2763 DeleteEnhMetaFile(CopyEnhMetaFileW(hemf, winetestemfW));
2764
2765 DeleteEnhMetaFile(hemf);
2766
2767 stat = GdipDisposeImage((GpImage*)metafile);
2768 expect(Ok, stat);
2769
2770 /* should succeed when given path to an EMF */
2771 stat = GdipCreateMetafileFromWmfFile(winetestemfW, NULL, &metafile);
2772 expect(Ok, stat);
2773
2774 stat = GdipDisposeImage((GpImage*)metafile);
2775 expect(Ok, stat);
2776
2777 DeleteFileW(winetestemfW);
2778
2779 stat = GdipCreateMetafileFromWmfFile(winetestemfW, NULL, &metafile);
2780 expect(GenericError, stat);
2781 }
2782
2783 START_TEST(metafile)
2784 {
2785 struct GdiplusStartupInput gdiplusStartupInput;
2786 ULONG_PTR gdiplusToken;
2787 int myARGC;
2788 char **myARGV;
2789 HMODULE hmsvcrt;
2790