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