c268d9efa8f907f7ca298d8abe37f6d5103a02e8
[reactos.git] / 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 #define WIN32_NO_STATUS
22 #define _INC_WINDOWS
23 #define COM_NO_WINDOWS_H
24
25 #include <math.h>
26
27 #include <wine/test.h>
28 #include <wingdi.h>
29 #include <objbase.h>
30 #include <gdiplus.h>
31
32 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
33 #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
34 #define expectf(expected, got) expectf_((expected), (got), 0.001)
35
36 static BOOL save_metafiles;
37
38 typedef struct emfplus_record
39 {
40 BOOL todo;
41 ULONG record_type;
42 BOOL playback_todo;
43 } emfplus_record;
44
45 typedef struct emfplus_check_state
46 {
47 const char *desc;
48 int count;
49 const struct emfplus_record *expected;
50 GpMetafile *metafile;
51 } emfplus_check_state;
52
53 static void check_record(int count, const char *desc, const struct emfplus_record *expected, const struct emfplus_record *actual)
54 {
55 todo_wine_if (expected->todo)
56 ok(expected->record_type == actual->record_type,
57 "%s.%i: Expected record type 0x%x, got 0x%x\n", desc, count,
58 expected->record_type, actual->record_type);
59 }
60
61 typedef struct EmfPlusRecordHeader
62 {
63 WORD Type;
64 WORD Flags;
65 DWORD Size;
66 DWORD DataSize;
67 } EmfPlusRecordHeader;
68
69 static int CALLBACK enum_emf_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
70 int nObj, LPARAM lpData)
71 {
72 emfplus_check_state *state = (emfplus_check_state*)lpData;
73 emfplus_record actual;
74
75 if (lpEMFR->iType == EMR_GDICOMMENT)
76 {
77 const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
78
79 if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
80 {
81 int offset = 4;
82
83 while (offset + sizeof(EmfPlusRecordHeader) <= comment->cbData)
84 {
85 const EmfPlusRecordHeader *record = (const EmfPlusRecordHeader*)&comment->Data[offset];
86
87 ok(record->Size == record->DataSize + sizeof(EmfPlusRecordHeader),
88 "%s: EMF+ record datasize %u and size %u mismatch\n", state->desc, record->DataSize, record->Size);
89
90 ok(offset + record->DataSize <= comment->cbData,
91 "%s: EMF+ record truncated\n", state->desc);
92
93 if (offset + record->DataSize > comment->cbData)
94 return 0;
95
96 if (state->expected[state->count].record_type)
97 {
98 actual.todo = FALSE;
99 actual.record_type = record->Type;
100
101 check_record(state->count, state->desc, &state->expected[state->count], &actual);
102
103 state->count++;
104 }
105 else
106 {
107 ok(0, "%s: Unexpected EMF+ 0x%x record\n", state->desc, record->Type);
108 }
109
110 offset += record->Size;
111 }
112
113 ok(offset == comment->cbData, "%s: truncated EMF+ record data?\n", state->desc);
114
115 return 1;
116 }
117 }
118
119 if (state->expected[state->count].record_type)
120 {
121 actual.todo = FALSE;
122 actual.record_type = lpEMFR->iType;
123
124 check_record(state->count, state->desc, &state->expected[state->count], &actual);
125
126 state->count++;
127 }
128 else
129 {
130 ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, lpEMFR->iType);
131 }
132
133 return 1;
134 }
135
136 static void check_emfplus(HENHMETAFILE hemf, const emfplus_record *expected, const char *desc)
137 {
138 emfplus_check_state state;
139
140 state.desc = desc;
141 state.count = 0;
142 state.expected = expected;
143
144 EnumEnhMetaFile(0, hemf, enum_emf_proc, &state, NULL);
145
146 todo_wine_if (expected[state.count].todo)
147 ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
148 }
149
150 static BOOL CALLBACK enum_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
151 unsigned int dataSize, const unsigned char *pStr, void *userdata)
152 {
153 emfplus_check_state *state = (emfplus_check_state*)userdata;
154 emfplus_record actual;
155
156 actual.todo = FALSE;
157 actual.record_type = record_type;
158
159 if (dataSize == 0)
160 ok(pStr == NULL, "non-NULL pStr\n");
161
162 if (state->expected[state->count].record_type)
163 {
164 check_record(state->count, state->desc, &state->expected[state->count], &actual);
165
166 state->count++;
167 }
168 else
169 {
170 ok(0, "%s: Unexpected EMF 0x%x record\n", state->desc, record_type);
171 }
172
173 return TRUE;
174 }
175
176 static void check_metafile(GpMetafile *metafile, const emfplus_record *expected, const char *desc,
177 const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
178 {
179 GpStatus stat;
180 HDC hdc;
181 GpGraphics *graphics;
182 emfplus_check_state state;
183
184 state.desc = desc;
185 state.count = 0;
186 state.expected = expected;
187 state.metafile = metafile;
188
189 hdc = CreateCompatibleDC(0);
190
191 stat = GdipCreateFromHDC(hdc, &graphics);
192 expect(Ok, stat);
193
194 stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
195 3, src_rect, src_unit, enum_metafile_proc, &state, NULL);
196 expect(Ok, stat);
197
198 todo_wine_if (expected[state.count].todo)
199 ok(expected[state.count].record_type == 0, "%s: Got %i records, expecting more\n", desc, state.count);
200
201 GdipDeleteGraphics(graphics);
202
203 DeleteDC(hdc);
204 }
205
206 static BOOL CALLBACK play_metafile_proc(EmfPlusRecordType record_type, unsigned int flags,
207 unsigned int dataSize, const unsigned char *pStr, void *userdata)
208 {
209 emfplus_check_state *state = (emfplus_check_state*)userdata;
210 GpStatus stat;
211
212 stat = GdipPlayMetafileRecord(state->metafile, record_type, flags, dataSize, pStr);
213
214 if (state->expected[state->count].record_type)
215 {
216 todo_wine_if (state->expected[state->count].playback_todo)
217 ok(stat == Ok, "%s.%i: GdipPlayMetafileRecord failed with stat %i\n", state->desc, state->count, stat);
218 state->count++;
219 }
220 else
221 {
222 todo_wine_if (state->expected[state->count].playback_todo)
223 ok(0, "%s: too many records\n", state->desc);
224
225 return FALSE;
226 }
227
228 return TRUE;
229 }
230
231 static void play_metafile(GpMetafile *metafile, GpGraphics *graphics, const emfplus_record *expected,
232 const char *desc, const GpPointF *dst_points, const GpRectF *src_rect, Unit src_unit)
233 {
234 GpStatus stat;
235 emfplus_check_state state;
236
237 state.desc = desc;
238 state.count = 0;
239 state.expected = expected;
240 state.metafile = metafile;
241
242 stat = GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, dst_points,
243 3, src_rect, src_unit, play_metafile_proc, &state, NULL);
244 expect(Ok, stat);
245 }
246
247 static void save_metafile(GpMetafile *metafile, const char *filename)
248 {
249 if (save_metafiles)
250 {
251 GpMetafile *clone;
252 HENHMETAFILE hemf;
253 GpStatus stat;
254
255 stat = GdipCloneImage((GpImage*)metafile, (GpImage**)&clone);
256 expect(Ok, stat);
257
258 stat = GdipGetHemfFromMetafile(clone, &hemf);
259 expect(Ok, stat);
260
261 DeleteEnhMetaFile(CopyEnhMetaFileA(hemf, filename));
262
263 DeleteEnhMetaFile(hemf);
264
265 stat = GdipDisposeImage((GpImage*)clone);
266 expect(Ok, stat);
267 }
268 }
269
270 static const emfplus_record empty_records[] = {
271 {0, EMR_HEADER},
272 {0, EmfPlusRecordTypeHeader},
273 {0, EmfPlusRecordTypeEndOfFile},
274 {0, EMR_EOF},
275 {0}
276 };
277
278 static void test_empty(void)
279 {
280 GpStatus stat;
281 GpMetafile *metafile;
282 GpGraphics *graphics;
283 HDC hdc;
284 GpRectF bounds;
285 GpUnit unit;
286 REAL xres, yres;
287 HENHMETAFILE hemf, dummy;
288 MetafileHeader header;
289 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
290 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
291 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
292
293 hdc = CreateCompatibleDC(0);
294
295 stat = GdipRecordMetafile(NULL, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
296 expect(InvalidParameter, stat);
297
298 stat = GdipRecordMetafile(hdc, MetafileTypeInvalid, &frame, MetafileFrameUnitPixel, description, &metafile);
299 expect(InvalidParameter, stat);
300
301 stat = GdipRecordMetafile(hdc, MetafileTypeWmf, &frame, MetafileFrameUnitPixel, description, &metafile);
302 expect(InvalidParameter, stat);
303
304 stat = GdipRecordMetafile(hdc, MetafileTypeWmfPlaceable, &frame, MetafileFrameUnitPixel, description, &metafile);
305 expect(InvalidParameter, stat);
306
307 stat = GdipRecordMetafile(hdc, MetafileTypeEmfPlusDual+1, &frame, MetafileFrameUnitPixel, description, &metafile);
308 expect(InvalidParameter, stat);
309
310 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, NULL);
311 expect(InvalidParameter, stat);
312
313 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
314 expect(Ok, stat);
315
316 DeleteDC(hdc);
317
318 if (stat != Ok)
319 return;
320
321 stat = GdipGetHemfFromMetafile(metafile, &hemf);
322 expect(InvalidParameter, stat);
323
324 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
325 expect(Ok, stat);
326
327 stat = GdipGetHemfFromMetafile(metafile, &hemf);
328 expect(InvalidParameter, stat);
329
330 stat = GdipDeleteGraphics(graphics);
331 expect(Ok, stat);
332
333 check_metafile(metafile, empty_records, "empty metafile", dst_points, &frame, UnitPixel);
334
335 save_metafile(metafile, "empty.emf");
336
337 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
338 expect(Ok, stat);
339 expectf(0.0, bounds.X);
340 expectf(0.0, bounds.Y);
341 expectf_(100.0, bounds.Width, 0.05);
342 expectf_(100.0, bounds.Height, 0.05);
343 expect(UnitPixel, unit);
344
345 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
346 expect(Ok, stat);
347
348 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
349 expect(Ok, stat);
350
351 stat = GdipGetHemfFromMetafile(metafile, &hemf);
352 expect(Ok, stat);
353
354 stat = GdipGetHemfFromMetafile(metafile, &dummy);
355 expect(InvalidParameter, stat);
356
357 stat = GdipDisposeImage((GpImage*)metafile);
358 expect(Ok, stat);
359
360 check_emfplus(hemf, empty_records, "empty emf");
361
362 memset(&header, 0xaa, sizeof(header));
363 stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
364 expect(Ok, stat);
365 expect(MetafileTypeEmfPlusOnly, header.Type);
366 expect(U(header).EmfHeader.nBytes, header.Size);
367 ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
368 expect(1, header.EmfPlusFlags); /* reference device was display, not printer */
369 expectf(xres, header.DpiX);
370 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
371 expectf(yres, header.DpiY);
372 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
373 expect(0, header.X);
374 expect(0, header.Y);
375 expect(100, header.Width);
376 expect(100, header.Height);
377 expect(28, header.EmfPlusHeaderSize);
378 expect(96, header.LogicalDpiX);
379 expect(96, header.LogicalDpiX);
380 expect(EMR_HEADER, U(header).EmfHeader.iType);
381 expect(0, U(header).EmfHeader.rclBounds.left);
382 expect(0, U(header).EmfHeader.rclBounds.top);
383 expect(-1, U(header).EmfHeader.rclBounds.right);
384 expect(-1, U(header).EmfHeader.rclBounds.bottom);
385 expect(0, U(header).EmfHeader.rclFrame.left);
386 expect(0, U(header).EmfHeader.rclFrame.top);
387 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
388 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
389
390 stat = GdipCreateMetafileFromEmf(hemf, TRUE, &metafile);
391 expect(Ok, stat);
392
393 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
394 expect(Ok, stat);
395 expectf(0.0, bounds.X);
396 expectf(0.0, bounds.Y);
397 expectf_(100.0, bounds.Width, 0.05);
398 expectf_(100.0, bounds.Height, 0.05);
399 expect(UnitPixel, unit);
400
401 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
402 expect(Ok, stat);
403 expectf(header.DpiX, xres);
404
405 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
406 expect(Ok, stat);
407 expectf(header.DpiY, yres);
408
409 stat = GdipDisposeImage((GpImage*)metafile);
410 expect(Ok, stat);
411 }
412
413 static const emfplus_record getdc_records[] = {
414 {0, EMR_HEADER},
415 {0, EmfPlusRecordTypeHeader},
416 {0, EmfPlusRecordTypeGetDC},
417 {0, EMR_CREATEBRUSHINDIRECT},
418 {0, EMR_SELECTOBJECT},
419 {0, EMR_RECTANGLE},
420 {0, EMR_SELECTOBJECT},
421 {0, EMR_DELETEOBJECT},
422 {0, EmfPlusRecordTypeEndOfFile},
423 {0, EMR_EOF},
424 {0}
425 };
426
427 static void test_getdc(void)
428 {
429 GpStatus stat;
430 GpMetafile *metafile;
431 GpGraphics *graphics;
432 HDC hdc, metafile_dc;
433 HENHMETAFILE hemf;
434 BOOL ret;
435 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
436 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
437 static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
438 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
439 HBRUSH hbrush, holdbrush;
440 GpBitmap *bitmap;
441 ARGB color;
442
443 hdc = CreateCompatibleDC(0);
444
445 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
446 expect(Ok, stat);
447
448 DeleteDC(hdc);
449
450 if (stat != Ok)
451 return;
452
453 stat = GdipGetHemfFromMetafile(metafile, &hemf);
454 expect(InvalidParameter, stat);
455
456 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
457 expect(Ok, stat);
458
459 stat = GdipGetDC(graphics, &metafile_dc);
460 expect(Ok, stat);
461
462 if (stat != Ok)
463 {
464 GdipDeleteGraphics(graphics);
465 GdipDisposeImage((GpImage*)metafile);
466 return;
467 }
468
469 hbrush = CreateSolidBrush(0xff0000);
470
471 holdbrush = SelectObject(metafile_dc, hbrush);
472
473 Rectangle(metafile_dc, 25, 25, 75, 75);
474
475 SelectObject(metafile_dc, holdbrush);
476
477 DeleteObject(hbrush);
478
479 stat = GdipReleaseDC(graphics, metafile_dc);
480 expect(Ok, stat);
481
482 stat = GdipDeleteGraphics(graphics);
483 expect(Ok, stat);
484
485 check_metafile(metafile, getdc_records, "getdc metafile", dst_points, &frame, UnitPixel);
486
487 save_metafile(metafile, "getdc.emf");
488
489 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
490 expect(Ok, stat);
491
492 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
493 expect(Ok, stat);
494
495 play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points, &frame, UnitPixel);
496
497 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
498 expect(Ok, stat);
499 expect(0, color);
500
501 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
502 expect(Ok, stat);
503 expect(0xff0000ff, color);
504
505 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
506 expect(Ok, stat);
507
508 play_metafile(metafile, graphics, getdc_records, "getdc playback", dst_points_half, &frame, UnitPixel);
509
510 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
511 expect(Ok, stat);
512 expect(0xff0000ff, color);
513
514 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
515 expect(Ok, stat);
516 expect(0, color);
517
518 stat = GdipBitmapSetPixel(bitmap, 15, 15, 0);
519 expect(Ok, stat);
520
521 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
522 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
523 expect(Ok, stat);
524
525 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
526 expect(Ok, stat);
527 expect(0, color);
528
529 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
530 expect(Ok, stat);
531 expect(0xff0000ff, color);
532
533 stat = GdipDeleteGraphics(graphics);
534 expect(Ok, stat);
535
536 stat = GdipDisposeImage((GpImage*)bitmap);
537 expect(Ok, stat);
538
539 stat = GdipGetHemfFromMetafile(metafile, &hemf);
540 expect(Ok, stat);
541
542 stat = GdipDisposeImage((GpImage*)metafile);
543 expect(Ok, stat);
544
545 check_emfplus(hemf, getdc_records, "getdc emf");
546
547 ret = DeleteEnhMetaFile(hemf);
548 ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf);
549 }
550
551 static const emfplus_record emfonly_records[] = {
552 {0, EMR_HEADER},
553 {0, EMR_CREATEBRUSHINDIRECT},
554 {0, EMR_SELECTOBJECT},
555 {0, EMR_RECTANGLE},
556 {0, EMR_SELECTOBJECT},
557 {0, EMR_DELETEOBJECT},
558 {0, EMR_EOF},
559 {0}
560 };
561
562 static void test_emfonly(void)
563 {
564 GpStatus stat;
565 GpMetafile *metafile;
566 GpImage *clone;
567 GpGraphics *graphics;
568 HDC hdc, metafile_dc;
569 GpRectF bounds;
570 GpUnit unit;
571 REAL xres, yres;
572 HENHMETAFILE hemf;
573 MetafileHeader header;
574 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
575 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
576 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
577 HBRUSH hbrush, holdbrush;
578 GpBitmap *bitmap;
579 ARGB color;
580
581 hdc = CreateCompatibleDC(0);
582
583 stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
584 expect(Ok, stat);
585
586 DeleteDC(hdc);
587
588 if (stat != Ok)
589 return;
590
591 stat = GdipGetHemfFromMetafile(metafile, &hemf);
592 expect(InvalidParameter, stat);
593
594 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
595 expect(Ok, stat);
596
597 stat = GdipGetDC(graphics, &metafile_dc);
598 expect(Ok, stat);
599
600 if (stat != Ok)
601 {
602 GdipDeleteGraphics(graphics);
603 GdipDisposeImage((GpImage*)metafile);
604 return;
605 }
606
607 hbrush = CreateSolidBrush(0xff0000);
608
609 holdbrush = SelectObject(metafile_dc, hbrush);
610
611 Rectangle(metafile_dc, 25, 25, 75, 75);
612
613 SelectObject(metafile_dc, holdbrush);
614
615 DeleteObject(hbrush);
616
617 stat = GdipReleaseDC(graphics, metafile_dc);
618 expect(Ok, stat);
619
620 stat = GdipDeleteGraphics(graphics);
621 expect(Ok, stat);
622
623 check_metafile(metafile, emfonly_records, "emfonly metafile", dst_points, &frame, UnitPixel);
624
625 save_metafile(metafile, "emfonly.emf");
626
627 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
628 expect(Ok, stat);
629 expectf(0.0, bounds.X);
630 expectf(0.0, bounds.Y);
631 expectf_(100.0, bounds.Width, 0.05);
632 expectf_(100.0, bounds.Height, 0.05);
633 expect(UnitPixel, unit);
634
635 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
636 expect(Ok, stat);
637
638 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
639 expect(Ok, stat);
640
641 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
642 expect(Ok, stat);
643
644 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
645 expect(Ok, stat);
646
647 play_metafile(metafile, graphics, emfonly_records, "emfonly playback", dst_points, &frame, UnitPixel);
648
649 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
650 expect(Ok, stat);
651 expect(0, color);
652
653 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
654 expect(Ok, stat);
655 expect(0xff0000ff, color);
656
657 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
658 expect(Ok, stat);
659
660 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
661 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
662 expect(Ok, stat);
663
664 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
665 expect(Ok, stat);
666 expect(0, color);
667
668 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
669 expect(Ok, stat);
670 expect(0xff0000ff, color);
671
672 stat = GdipCloneImage((GpImage*)metafile, &clone);
673 expect(Ok, stat);
674
675 if (stat == Ok)
676 {
677 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
678 expect(Ok, stat);
679
680 stat = GdipDrawImagePointsRect(graphics, clone, dst_points, 3,
681 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
682 expect(Ok, stat);
683
684 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
685 expect(Ok, stat);
686 expect(0, color);
687
688 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
689 expect(Ok, stat);
690 expect(0xff0000ff, color);
691
692 GdipDisposeImage(clone);
693 }
694
695 stat = GdipDeleteGraphics(graphics);
696 expect(Ok, stat);
697
698 stat = GdipDisposeImage((GpImage*)bitmap);
699 expect(Ok, stat);
700
701 stat = GdipGetHemfFromMetafile(metafile, &hemf);
702 expect(Ok, stat);
703
704 stat = GdipDisposeImage((GpImage*)metafile);
705 expect(Ok, stat);
706
707 check_emfplus(hemf, emfonly_records, "emfonly emf");
708
709 memset(&header, 0xaa, sizeof(header));
710 stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
711 expect(Ok, stat);
712 expect(MetafileTypeEmf, header.Type);
713 expect(U(header).EmfHeader.nBytes, header.Size);
714 expect(0x10000, header.Version);
715 expect(0, header.EmfPlusFlags);
716 expectf(xres, header.DpiX);
717 expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
718 expectf(yres, header.DpiY);
719 expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
720 expect(0, header.X);
721 expect(0, header.Y);
722 expect(100, header.Width);
723 expect(100, header.Height);
724 expect(0, header.EmfPlusHeaderSize);
725 expect(0, header.LogicalDpiX);
726 expect(0, header.LogicalDpiX);
727 expect(EMR_HEADER, U(header).EmfHeader.iType);
728 expect(25, U(header).EmfHeader.rclBounds.left);
729 expect(25, U(header).EmfHeader.rclBounds.top);
730 expect(74, U(header).EmfHeader.rclBounds.right);
731 expect(74, U(header).EmfHeader.rclBounds.bottom);
732 expect(0, U(header).EmfHeader.rclFrame.left);
733 expect(0, U(header).EmfHeader.rclFrame.top);
734 expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
735 expectf_(100.0, U(header).EmfHeader.rclFrame.bottom * yres / 2540.0, 2.0);
736
737 stat = GdipCreateMetafileFromEmf(hemf, TRUE, &metafile);
738 expect(Ok, stat);
739
740 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
741 expect(Ok, stat);
742 expectf(0.0, bounds.X);
743 expectf(0.0, bounds.Y);
744 expectf_(100.0, bounds.Width, 0.05);
745 expectf_(100.0, bounds.Height, 0.05);
746 expect(UnitPixel, unit);
747
748 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &xres);
749 expect(Ok, stat);
750 expectf(header.DpiX, xres);
751
752 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &yres);
753 expect(Ok, stat);
754 expectf(header.DpiY, yres);
755
756 stat = GdipDisposeImage((GpImage*)metafile);
757 expect(Ok, stat);
758 }
759
760 static const emfplus_record fillrect_records[] = {
761 {0, EMR_HEADER},
762 {0, EmfPlusRecordTypeHeader},
763 {0, EmfPlusRecordTypeFillRects},
764 {0, EmfPlusRecordTypeEndOfFile},
765 {0, EMR_EOF},
766 {0}
767 };
768
769 static void test_fillrect(void)
770 {
771 GpStatus stat;
772 GpMetafile *metafile;
773 GpGraphics *graphics;
774 HDC hdc;
775 HENHMETAFILE hemf;
776 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
777 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
778 static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
779 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
780 GpBitmap *bitmap;
781 ARGB color;
782 GpBrush *brush;
783
784 hdc = CreateCompatibleDC(0);
785
786 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
787 expect(Ok, stat);
788
789 DeleteDC(hdc);
790
791 if (stat != Ok)
792 return;
793
794 stat = GdipGetHemfFromMetafile(metafile, &hemf);
795 expect(InvalidParameter, stat);
796
797 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
798 expect(Ok, stat);
799
800 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
801 expect(Ok, stat);
802
803 stat = GdipFillRectangleI(graphics, brush, 25, 25, 75, 75);
804 expect(Ok, stat);
805
806 stat = GdipDeleteBrush(brush);
807 expect(Ok, stat);
808
809 stat = GdipDeleteGraphics(graphics);
810 expect(Ok, stat);
811
812 check_metafile(metafile, fillrect_records, "fillrect metafile", dst_points, &frame, UnitPixel);
813
814 save_metafile(metafile, "fillrect.emf");
815
816 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
817 expect(Ok, stat);
818
819 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
820 expect(Ok, stat);
821
822 play_metafile(metafile, graphics, fillrect_records, "fillrect playback", dst_points, &frame, UnitPixel);
823
824 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
825 expect(Ok, stat);
826 expect(0, color);
827
828 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
829 expect(Ok, stat);
830 expect(0xff0000ff, color);
831
832 stat = GdipBitmapSetPixel(bitmap, 50, 50, 0);
833 expect(Ok, stat);
834
835 play_metafile(metafile, graphics, fillrect_records, "fillrect playback", dst_points_half, &frame, UnitPixel);
836
837 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
838 expect(Ok, stat);
839 expect(0xff0000ff, color);
840
841 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
842 expect(Ok, stat);
843 expect(0, color);
844
845 stat = GdipBitmapSetPixel(bitmap, 15, 15, 0);
846 expect(Ok, stat);
847
848 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
849 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
850 expect(Ok, stat);
851
852 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
853 expect(Ok, stat);
854 expect(0, color);
855
856 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
857 expect(Ok, stat);
858 expect(0xff0000ff, color);
859
860 stat = GdipDeleteGraphics(graphics);
861 expect(Ok, stat);
862
863 stat = GdipDisposeImage((GpImage*)bitmap);
864 expect(Ok, stat);
865
866 stat = GdipDisposeImage((GpImage*)metafile);
867 expect(Ok, stat);
868 }
869
870 static const emfplus_record clear_emf_records[] = {
871 {0, EMR_HEADER},
872 {0, EmfPlusRecordTypeHeader},
873 {0, EmfPlusRecordTypeClear},
874 {1, EMR_SAVEDC},
875 {1, EMR_SETICMMODE},
876 {1, EMR_BITBLT},
877 {1, EMR_RESTOREDC},
878 {0, EmfPlusRecordTypeEndOfFile},
879 {0, EMR_EOF},
880 {0}
881 };
882
883 static void test_clear(void)
884 {
885 GpStatus stat;
886 GpMetafile *metafile;
887 GpGraphics *graphics;
888 HDC hdc;
889 HENHMETAFILE hemf;
890 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
891 static const GpPointF dst_points[3] = {{10.0,10.0},{20.0,10.0},{10.0,20.0}};
892 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
893 GpBitmap *bitmap;
894 ARGB color;
895
896 hdc = CreateCompatibleDC(0);
897
898 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
899 expect(Ok, stat);
900
901 DeleteDC(hdc);
902
903 if (stat != Ok)
904 return;
905
906 stat = GdipGetHemfFromMetafile(metafile, &hemf);
907 expect(InvalidParameter, stat);
908
909 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
910 expect(Ok, stat);
911
912 stat = GdipGraphicsClear(graphics, 0xffffff00);
913 expect(Ok, stat);
914
915 stat = GdipDeleteGraphics(graphics);
916 expect(Ok, stat);
917
918 save_metafile(metafile, "clear.emf");
919
920 stat = GdipCreateBitmapFromScan0(30, 30, 0, PixelFormat32bppRGB, NULL, &bitmap);
921 expect(Ok, stat);
922
923 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
924 expect(Ok, stat);
925
926 stat = GdipDrawImagePointsRect(graphics, (GpImage*)metafile, dst_points, 3,
927 0.0, 0.0, 100.0, 100.0, UnitPixel, NULL, NULL, NULL);
928 expect(Ok, stat);
929
930 stat = GdipBitmapGetPixel(bitmap, 5, 5, &color);
931 expect(Ok, stat);
932 expect(0xff000000, color);
933
934 stat = GdipBitmapGetPixel(bitmap, 15, 15, &color);
935 expect(Ok, stat);
936 expect(0xffffff00, color);
937
938 stat = GdipBitmapGetPixel(bitmap, 25, 25, &color);
939 expect(Ok, stat);
940 expect(0xff000000, color);
941
942 stat = GdipDeleteGraphics(graphics);
943 expect(Ok, stat);
944
945 stat = GdipDisposeImage((GpImage*)bitmap);
946 expect(Ok, stat);
947
948 stat = GdipGetHemfFromMetafile(metafile, &hemf);
949 expect(Ok, stat);
950
951 stat = GdipDisposeImage((GpImage*)metafile);
952 expect(Ok, stat);
953
954 check_emfplus(hemf, clear_emf_records, "clear emf");
955
956 DeleteEnhMetaFile(hemf);
957 }
958
959 static void test_nullframerect(void) {
960 GpStatus stat;
961 GpMetafile *metafile;
962 GpGraphics *graphics;
963 HDC hdc, metafile_dc;
964 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
965 GpBrush *brush;
966 HBRUSH hbrush, holdbrush;
967 GpRectF bounds;
968 GpUnit unit;
969
970 hdc = CreateCompatibleDC(0);
971
972 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, NULL, MetafileFrameUnitPixel, description, &metafile);
973 expect(Ok, stat);
974
975 DeleteDC(hdc);
976
977 if (stat != Ok)
978 return;
979
980 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
981 expect(Ok, stat);
982 expect(UnitPixel, unit);
983 expectf(0.0, bounds.X);
984 expectf(0.0, bounds.Y);
985 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
986 "expected 1.0, got %f\n", bounds.Width);
987 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
988 "expected 1.0, got %f\n", bounds.Height);
989
990 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
991 expect(Ok, stat);
992
993 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
994 expect(Ok, stat);
995
996 stat = GdipFillRectangleI(graphics, brush, 25, 25, 75, 75);
997 expect(Ok, stat);
998
999 stat = GdipDeleteBrush(brush);
1000 expect(Ok, stat);
1001
1002 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1003 expect(Ok, stat);
1004 expect(UnitPixel, unit);
1005 expectf(0.0, bounds.X);
1006 expectf(0.0, bounds.Y);
1007 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
1008 "expected 1.0, got %f\n", bounds.Width);
1009 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
1010 "expected 1.0, got %f\n", bounds.Height);
1011
1012 stat = GdipDeleteGraphics(graphics);
1013 expect(Ok, stat);
1014
1015 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1016 expect(Ok, stat);
1017 expect(UnitPixel, unit);
1018 expectf_(25.0, bounds.X, 0.05);
1019 expectf_(25.0, bounds.Y, 0.05);
1020 expectf_(75.0, bounds.Width, 0.05);
1021 expectf_(75.0, bounds.Height, 0.05);
1022
1023 stat = GdipDisposeImage((GpImage*)metafile);
1024 expect(Ok, stat);
1025
1026 hdc = CreateCompatibleDC(0);
1027
1028 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, NULL, MetafileFrameUnitMillimeter, description, &metafile);
1029 expect(Ok, stat);
1030
1031 DeleteDC(hdc);
1032
1033 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1034 expect(Ok, stat);
1035
1036 stat = GdipGetDC(graphics, &metafile_dc);
1037 expect(Ok, stat);
1038
1039 if (stat != Ok)
1040 {
1041 GdipDeleteGraphics(graphics);
1042 GdipDisposeImage((GpImage*)metafile);
1043 return;
1044 }
1045
1046 hbrush = CreateSolidBrush(0xff0000);
1047
1048 holdbrush = SelectObject(metafile_dc, hbrush);
1049
1050 Rectangle(metafile_dc, 25, 25, 75, 75);
1051
1052 SelectObject(metafile_dc, holdbrush);
1053
1054 DeleteObject(hbrush);
1055
1056 stat = GdipReleaseDC(graphics, metafile_dc);
1057 expect(Ok, stat);
1058
1059 stat = GdipDeleteGraphics(graphics);
1060 expect(Ok, stat);
1061
1062 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1063 expect(Ok, stat);
1064 expect(UnitPixel, unit);
1065 expectf_(25.0, bounds.X, 0.05);
1066 expectf_(25.0, bounds.Y, 0.05);
1067 todo_wine expectf_(50.0, bounds.Width, 0.05);
1068 todo_wine expectf_(50.0, bounds.Height, 0.05);
1069
1070 stat = GdipDisposeImage((GpImage*)metafile);
1071 expect(Ok, stat);
1072 }
1073
1074 static const emfplus_record pagetransform_records[] = {
1075 {0, EMR_HEADER},
1076 {0, EmfPlusRecordTypeHeader},
1077 {0, EmfPlusRecordTypeFillRects},
1078 {0, EmfPlusRecordTypeSetPageTransform},
1079 {0, EmfPlusRecordTypeFillRects},
1080 {0, EmfPlusRecordTypeSetPageTransform},
1081 {0, EmfPlusRecordTypeFillRects},
1082 {0, EmfPlusRecordTypeSetPageTransform},
1083 {0, EmfPlusRecordTypeFillRects},
1084 {0, EmfPlusRecordTypeSetPageTransform},
1085 {0, EmfPlusRecordTypeFillRects},
1086 {0, EmfPlusRecordTypeEndOfFile},
1087 {0, EMR_EOF},
1088 {0}
1089 };
1090
1091 static void test_pagetransform(void)
1092 {
1093 GpStatus stat;
1094 GpMetafile *metafile;
1095 GpGraphics *graphics;
1096 HDC hdc;
1097 static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
1098 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1099 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1100 GpBitmap *bitmap;
1101 ARGB color;
1102 GpBrush *brush;
1103 GpUnit unit;
1104 REAL scale, dpix, dpiy;
1105 UINT width, height;
1106
1107 hdc = CreateCompatibleDC(0);
1108
1109 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitInch, description, &metafile);
1110 expect(Ok, stat);
1111
1112 DeleteDC(hdc);
1113
1114 if (stat != Ok)
1115 return;
1116
1117 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &dpix);
1118 todo_wine expect(InvalidParameter, stat);
1119
1120 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &dpiy);
1121 todo_wine expect(InvalidParameter, stat);
1122
1123 stat = GdipGetImageWidth((GpImage*)metafile, &width);
1124 todo_wine expect(InvalidParameter, stat);
1125
1126 stat = GdipGetImageHeight((GpImage*)metafile, &height);
1127 todo_wine expect(InvalidParameter, stat);
1128
1129 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1130 expect(Ok, stat);
1131
1132 /* initial scale */
1133 stat = GdipGetPageUnit(graphics, &unit);
1134 expect(Ok, stat);
1135 expect(UnitDisplay, unit);
1136
1137 stat = GdipGetPageScale(graphics, &scale);
1138 expect(Ok, stat);
1139 expectf(1.0, scale);
1140
1141 stat = GdipGetDpiX(graphics, &dpix);
1142 expect(Ok, stat);
1143 expectf(96.0, dpix);
1144
1145 stat = GdipGetDpiY(graphics, &dpiy);
1146 expect(Ok, stat);
1147 expectf(96.0, dpiy);
1148
1149 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
1150 expect(Ok, stat);
1151
1152 stat = GdipFillRectangleI(graphics, brush, 1, 2, 1, 1);
1153 expect(Ok, stat);
1154
1155 stat = GdipDeleteBrush(brush);
1156 expect(Ok, stat);
1157
1158 /* page unit = pixels */
1159 stat = GdipSetPageUnit(graphics, UnitPixel);
1160 expect(Ok, stat);
1161
1162 stat = GdipGetPageUnit(graphics, &unit);
1163 expect(Ok, stat);
1164 expect(UnitPixel, unit);
1165
1166 stat = GdipCreateSolidFill((ARGB)0xff00ff00, (GpSolidFill**)&brush);
1167 expect(Ok, stat);
1168
1169 stat = GdipFillRectangleI(graphics, brush, 0, 1, 1, 1);
1170 expect(Ok, stat);
1171
1172 stat = GdipDeleteBrush(brush);
1173 expect(Ok, stat);
1174
1175 /* page scale = 3, unit = pixels */
1176 stat = GdipSetPageScale(graphics, 3.0);
1177 expect(Ok, stat);
1178
1179 stat = GdipGetPageScale(graphics, &scale);
1180 expect(Ok, stat);
1181 expectf(3.0, scale);
1182
1183 stat = GdipCreateSolidFill((ARGB)0xff00ffff, (GpSolidFill**)&brush);
1184 expect(Ok, stat);
1185
1186 stat = GdipFillRectangleI(graphics, brush, 0, 1, 2, 2);
1187 expect(Ok, stat);
1188
1189 stat = GdipDeleteBrush(brush);
1190 expect(Ok, stat);
1191
1192 /* page scale = 3, unit = inches */
1193 stat = GdipSetPageUnit(graphics, UnitInch);
1194 expect(Ok, stat);
1195
1196 stat = GdipGetPageUnit(graphics, &unit);
1197 expect(Ok, stat);
1198 expect(UnitInch, unit);
1199
1200 stat = GdipCreateSolidFill((ARGB)0xffff0000, (GpSolidFill**)&brush);
1201 expect(Ok, stat);
1202
1203 stat = GdipFillRectangle(graphics, brush, 1.0/96.0, 0, 1, 1);
1204 expect(Ok, stat);
1205
1206 stat = GdipDeleteBrush(brush);
1207 expect(Ok, stat);
1208
1209 /* page scale = 3, unit = display */
1210 stat = GdipSetPageUnit(graphics, UnitDisplay);
1211 expect(Ok, stat);
1212
1213 stat = GdipGetPageUnit(graphics, &unit);
1214 expect(Ok, stat);
1215 expect(UnitDisplay, unit);
1216
1217 stat = GdipCreateSolidFill((ARGB)0xffff00ff, (GpSolidFill**)&brush);
1218 expect(Ok, stat);
1219
1220 stat = GdipFillRectangle(graphics, brush, 3, 3, 2, 2);
1221 expect(Ok, stat);
1222
1223 stat = GdipDeleteBrush(brush);
1224 expect(Ok, stat);
1225
1226 stat = GdipDeleteGraphics(graphics);
1227 expect(Ok, stat);
1228
1229 check_metafile(metafile, pagetransform_records, "pagetransform metafile", dst_points, &frame, UnitPixel);
1230
1231 save_metafile(metafile, "pagetransform.emf");
1232
1233 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
1234 expect(Ok, stat);
1235
1236 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1237 expect(Ok, stat);
1238
1239 play_metafile(metafile, graphics, pagetransform_records, "pagetransform playback", dst_points, &frame, UnitPixel);
1240
1241 stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
1242 expect(Ok, stat);
1243 expect(0, color);
1244
1245 stat = GdipBitmapGetPixel(bitmap, 30, 50, &color);
1246 expect(Ok, stat);
1247 expect(0xff0000ff, color);
1248
1249 stat = GdipBitmapGetPixel(bitmap, 10, 30, &color);
1250 expect(Ok, stat);
1251 expect(0xff00ff00, color);
1252
1253 stat = GdipBitmapGetPixel(bitmap, 20, 80, &color);
1254 expect(Ok, stat);
1255 expect(0xff00ffff, color);
1256
1257 stat = GdipBitmapGetPixel(bitmap, 80, 20, &color);
1258 expect(Ok, stat);
1259 expect(0xffff0000, color);
1260
1261 stat = GdipBitmapGetPixel(bitmap, 80, 80, &color);
1262 expect(Ok, stat);
1263 expect(0xffff00ff, color);
1264
1265 stat = GdipDeleteGraphics(graphics);
1266 expect(Ok, stat);
1267
1268 stat = GdipDisposeImage((GpImage*)bitmap);
1269 expect(Ok, stat);
1270
1271 stat = GdipDisposeImage((GpImage*)metafile);
1272 expect(Ok, stat);
1273 }
1274
1275 static const emfplus_record worldtransform_records[] = {
1276 {0, EMR_HEADER},
1277 {0, EmfPlusRecordTypeHeader},
1278 {0, EmfPlusRecordTypeFillRects},
1279 {0, EmfPlusRecordTypeScaleWorldTransform},
1280 {0, EmfPlusRecordTypeFillRects},
1281 {0, EmfPlusRecordTypeResetWorldTransform},
1282 {0, EmfPlusRecordTypeFillRects},
1283 {0, EmfPlusRecordTypeEndOfFile},
1284 {0, EMR_EOF},
1285 {0}
1286 };
1287
1288 static void test_worldtransform(void)
1289 {
1290 GpStatus stat;
1291 GpMetafile *metafile;
1292 GpGraphics *graphics;
1293 HDC hdc;
1294 static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
1295 static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
1296 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1297 GpBitmap *bitmap;
1298 ARGB color;
1299 GpBrush *brush;
1300 GpMatrix *transform;
1301 BOOL identity;
1302 REAL elements[6];
1303
1304 hdc = CreateCompatibleDC(0);
1305
1306 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &metafile);
1307 expect(Ok, stat);
1308
1309 DeleteDC(hdc);
1310
1311 if (stat != Ok)
1312 return;
1313
1314 stat = GdipCreateMatrix(&transform);
1315 expect(Ok, stat);
1316
1317 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1318 expect(Ok, stat);
1319
1320 /* initial transform */
1321 stat = GdipGetWorldTransform(graphics, transform);
1322 expect(Ok, stat);
1323
1324 stat = GdipIsMatrixIdentity(transform, &identity);
1325 expect(Ok, stat);
1326 expect(TRUE, identity);
1327
1328 stat = GdipCreateSolidFill((ARGB)0xff0000ff, (GpSolidFill**)&brush);
1329 expect(Ok, stat);
1330
1331 stat = GdipFillRectangleI(graphics, brush, 0, 0, 1, 1);
1332 expect(Ok, stat);
1333
1334 stat = GdipDeleteBrush(brush);
1335 expect(Ok, stat);
1336
1337 /* scale transform */
1338 stat = GdipScaleWorldTransform(graphics, 2.0, 4.0, MatrixOrderPrepend);
1339 expect(Ok, stat);
1340
1341 stat = GdipGetWorldTransform(graphics, transform);
1342 expect(Ok, stat);
1343
1344 stat = GdipGetMatrixElements(transform, elements);
1345 expect(Ok, stat);
1346 expectf(2.0, elements[0]);
1347 expectf(0.0, elements[1]);
1348 expectf(0.0, elements[2]);
1349 expectf(4.0, elements[3]);
1350 expectf(0.0, elements[4]);
1351 expectf(0.0, elements[5]);
1352
1353 stat = GdipCreateSolidFill((ARGB)0xff00ff00, (GpSolidFill**)&brush);
1354 expect(Ok, stat);
1355
1356 stat = GdipFillRectangle(graphics, brush, 0.5, 0.5, 0.5, 0.25);
1357 expect(Ok, stat);
1358
1359 stat = GdipDeleteBrush(brush);
1360 expect(Ok, stat);
1361
1362 /* reset transform */
1363 stat = GdipResetWorldTransform(graphics);
1364 expect(Ok, stat);
1365
1366 stat = GdipGetWorldTransform(graphics, transform);
1367 expect(Ok, stat);
1368
1369 stat = GdipIsMatrixIdentity(transform, &identity);
1370 expect(Ok, stat);
1371 expect(TRUE, identity);
1372
1373 stat = GdipCreateSolidFill((ARGB)0xff00ffff, (GpSolidFill**)&brush);
1374 expect(Ok, stat);
1375
1376 stat = GdipFillRectangle(graphics, brush, 1.0, 0.0, 1.0, 1.0);
1377 expect(Ok, stat);
1378
1379 stat = GdipDeleteBrush(brush);
1380 expect(Ok, stat);
1381
1382 stat = GdipDeleteMatrix(transform);
1383 expect(Ok, stat);
1384
1385 stat = GdipDeleteGraphics(graphics);
1386 expect(Ok, stat);
1387
1388 check_metafile(metafile, worldtransform_records, "worldtransform metafile", dst_points, &frame, UnitPixel);
1389
1390 save_metafile(metafile, "worldtransform.emf");
1391
1392 stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap);
1393 expect(Ok, stat);
1394
1395 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1396 expect(Ok, stat);
1397
1398 play_metafile(metafile, graphics, worldtransform_records, "worldtransform playback", dst_points, &frame, UnitPixel);
1399
1400 stat = GdipBitmapGetPixel(bitmap, 80, 80, &color);
1401 expect(Ok, stat);
1402 expect(0, color);
1403
1404 stat = GdipBitmapGetPixel(bitmap, 10, 10, &color);
1405 expect(Ok, stat);
1406 expect(0xff0000ff, color);
1407
1408 stat = GdipBitmapGetPixel(bitmap, 30, 50, &color);
1409 expect(Ok, stat);
1410 expect(0xff00ff00, color);
1411
1412 stat = GdipBitmapGetPixel(bitmap, 30, 10, &color);
1413 expect(Ok, stat);
1414 expect(0xff00ffff, color);
1415
1416 stat = GdipDeleteGraphics(graphics);
1417 expect(Ok, stat);
1418
1419 stat = GdipDisposeImage((GpImage*)bitmap);
1420 expect(Ok, stat);
1421
1422 stat = GdipDisposeImage((GpImage*)metafile);
1423 expect(Ok, stat);
1424 }
1425
1426 static void test_converttoemfplus(void)
1427 {
1428 GpStatus (WINAPI *pGdipConvertToEmfPlus)( const GpGraphics *graphics, GpMetafile *metafile, BOOL *succ,
1429 EmfType emfType, const WCHAR *description, GpMetafile **outmetafile);
1430 static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
1431 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1432 GpStatus stat;
1433 GpMetafile *metafile, *metafile2 = NULL, *emhmeta;
1434 GpGraphics *graphics;
1435 HDC hdc;
1436 BOOL succ;
1437 HMODULE mod = GetModuleHandleA("gdiplus.dll");
1438
1439 pGdipConvertToEmfPlus = (void*)GetProcAddress( mod, "GdipConvertToEmfPlus");
1440 if(!pGdipConvertToEmfPlus)
1441 {
1442 /* GdipConvertToEmfPlus was introduced in Windows Vista. */
1443 win_skip("GDIPlus version 1.1 not available\n");
1444 return;
1445 }
1446
1447 hdc = CreateCompatibleDC(0);
1448
1449 stat = GdipRecordMetafile(hdc, MetafileTypeEmf, &frame, MetafileFrameUnitPixel, description, &metafile);
1450 expect(Ok, stat);
1451
1452 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitPixel, description, &emhmeta);
1453 expect(Ok, stat);
1454
1455 DeleteDC(hdc);
1456
1457 if (stat != Ok)
1458 return;
1459
1460 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1461 expect(Ok, stat);
1462
1463 /* Invalid Parameters */
1464 stat = pGdipConvertToEmfPlus(NULL, metafile, &succ, EmfTypeEmfPlusOnly, description, &metafile2);
1465 expect(InvalidParameter, stat);
1466
1467 stat = pGdipConvertToEmfPlus(graphics, NULL, &succ, EmfTypeEmfPlusOnly, description, &metafile2);
1468 expect(InvalidParameter, stat);
1469
1470 stat = pGdipConvertToEmfPlus(graphics, metafile, &succ, EmfTypeEmfPlusOnly, description, NULL);
1471 expect(InvalidParameter, stat);
1472
1473 stat = pGdipConvertToEmfPlus(graphics, metafile, NULL, MetafileTypeInvalid, NULL, &metafile2);
1474 expect(InvalidParameter, stat);
1475
1476 stat = pGdipConvertToEmfPlus(graphics, metafile, NULL, MetafileTypeEmfPlusDual+1, NULL, &metafile2);
1477 expect(InvalidParameter, stat);
1478
1479 /* If we are already an Enhanced Metafile then the conversion fails. */
1480 stat = pGdipConvertToEmfPlus(graphics, emhmeta, NULL, EmfTypeEmfPlusOnly, NULL, &metafile2);
1481 todo_wine expect(InvalidParameter, stat);
1482
1483 stat = pGdipConvertToEmfPlus(graphics, metafile, NULL, EmfTypeEmfPlusOnly, NULL, &metafile2);
1484 todo_wine expect(Ok, stat);
1485 if(metafile2)
1486 GdipDisposeImage((GpImage*)metafile2);
1487
1488 succ = FALSE;
1489 stat = pGdipConvertToEmfPlus(graphics, metafile, &succ, EmfTypeEmfPlusOnly, NULL, &metafile2);
1490 todo_wine expect(Ok, stat);
1491 if(metafile2)
1492 GdipDisposeImage((GpImage*)metafile2);
1493
1494 stat = GdipDeleteGraphics(graphics);
1495 expect(Ok, stat);
1496
1497 stat = GdipDisposeImage((GpImage*)metafile);
1498 expect(Ok, stat);
1499
1500 stat = GdipDisposeImage((GpImage*)emhmeta);
1501 expect(Ok, stat);
1502 }
1503
1504 static void test_frameunit(void)
1505 {
1506 GpStatus stat;
1507 GpMetafile *metafile;
1508 GpGraphics *graphics;
1509 HDC hdc;
1510 static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
1511 static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
1512 GpUnit unit;
1513 REAL dpix, dpiy;
1514 GpRectF bounds;
1515
1516 hdc = CreateCompatibleDC(0);
1517
1518 stat = GdipRecordMetafile(hdc, EmfTypeEmfPlusOnly, &frame, MetafileFrameUnitInch, description, &metafile);
1519 expect(Ok, stat);
1520
1521 DeleteDC(hdc);
1522
1523 if (stat != Ok)
1524 return;
1525
1526 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1527 expect(Ok, stat);
1528 expect(UnitPixel, unit);
1529 expectf(0.0, bounds.X);
1530 expectf(0.0, bounds.Y);
1531 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
1532 "expected 1.0, got %f\n", bounds.Width);
1533 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
1534 "expected 1.0, got %f\n", bounds.Height);
1535
1536 stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics);
1537 expect(Ok, stat);
1538
1539 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1540 expect(Ok, stat);
1541 expect(UnitPixel, unit);
1542 expectf(0.0, bounds.X);
1543 expectf(0.0, bounds.Y);
1544 ok(bounds.Width == 1.0 || broken(bounds.Width == 0.0) /* xp sp1 */,
1545 "expected 1.0, got %f\n", bounds.Width);
1546 ok(bounds.Height == 1.0 || broken(bounds.Height == 0.0) /* xp sp1 */,
1547 "expected 1.0, got %f\n", bounds.Height);
1548
1549 stat = GdipDeleteGraphics(graphics);
1550 expect(Ok, stat);
1551
1552 stat = GdipGetImageHorizontalResolution((GpImage*)metafile, &dpix);
1553 expect(Ok, stat);
1554
1555 stat = GdipGetImageVerticalResolution((GpImage*)metafile, &dpiy);
1556 expect(Ok, stat);
1557
1558 stat = GdipGetImageBounds((GpImage*)metafile, &bounds, &unit);
1559 expect(Ok, stat);
1560 expect(UnitPixel, unit);
1561 expectf(0.0, bounds.X);
1562 expectf(0.0, bounds.Y);
1563 expectf_(5.0 * dpix, bounds.Width, 1.0);
1564 expectf_(5.0 * dpiy, bounds.Height, 1.0);
1565
1566 stat = GdipDisposeImage((GpImage*)metafile);
1567 expect(Ok, stat);
1568 }
1569
1570 START_TEST(metafile)
1571 {
1572 struct GdiplusStartupInput gdiplusStartupInput;
1573 ULONG_PTR gdiplusToken;
1574 int myARGC;
1575 char **myARGV;
1576
1577 gdiplusStartupInput.GdiplusVersion = 1;
1578 gdiplusStartupInput.DebugEventCallback = NULL;
1579 gdiplusStartupInput.SuppressBackgroundThread = 0;
1580 gdiplusStartupInput.SuppressExternalCodecs = 0;
1581
1582 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
1583
1584 myARGC = winetest_get_mainargs( &myARGV );
1585
1586 if (myARGC >= 3 && !strcmp(myARGV[2], "save"))
1587 save_metafiles = TRUE;
1588
1589 test_empty();
1590 test_getdc();
1591 test_emfonly();
1592 test_fillrect();
1593 test_clear();
1594 test_nullframerect();
1595 test_pagetransform();
1596 test_worldtransform();
1597 test_converttoemfplus();
1598 test_frameunit();
1599
1600 GdiplusShutdown(gdiplusToken);
1601 }