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