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