1 /* 2 * Unit test suite for fonts 3 * 4 * Copyright (C) 2007 Google (Evan Stade) 5 * Copyright (C) 2012 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include <math.h> 23 24 #define WIN32_NO_STATUS 25 #define _INC_WINDOWS 26 #define COM_NO_WINDOWS_H 27 28 //#include "windows.h" 29 #include <wine/test.h> 30 #include <wingdi.h> 31 #include <winnls.h> 32 #include <objbase.h> 33 #include <gdiplus.h> 34 35 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) 36 #define expect_(expected, got, precision) ok(abs((expected) - (got)) <= (precision), "Expected %d, got %d\n", (expected), (got)) 37 #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got)) 38 #define expectf(expected, got) expectf_((expected), (got), 0.001) 39 40 static const WCHAR nonexistent[] = {'T','h','i','s','F','o','n','t','s','h','o','u','l','d','N','o','t','E','x','i','s','t','\0'}; 41 static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}; 42 static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'}; 43 static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0}; 44 45 static void set_rect_empty(RectF *rc) 46 { 47 rc->X = 0.0; 48 rc->Y = 0.0; 49 rc->Width = 0.0; 50 rc->Height = 0.0; 51 } 52 53 static void test_createfont(void) 54 { 55 GpFontFamily* fontfamily = NULL, *fontfamily2; 56 GpFont* font = NULL; 57 GpStatus stat; 58 Unit unit; 59 UINT i; 60 REAL size; 61 WCHAR familyname[LF_FACESIZE]; 62 63 stat = GdipCreateFontFamilyFromName(nonexistent, NULL, &fontfamily); 64 expect (FontFamilyNotFound, stat); 65 stat = GdipDeleteFont(font); 66 expect (InvalidParameter, stat); 67 stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily); 68 expect (Ok, stat); 69 stat = GdipCreateFont(fontfamily, 12, FontStyleRegular, UnitPoint, &font); 70 expect (Ok, stat); 71 stat = GdipGetFontUnit (font, &unit); 72 expect (Ok, stat); 73 expect (UnitPoint, unit); 74 75 stat = GdipGetFamily(font, &fontfamily2); 76 expect(Ok, stat); 77 stat = GdipGetFamilyName(fontfamily2, familyname, 0); 78 expect(Ok, stat); 79 ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n", 80 wine_dbgstr_w(familyname)); 81 stat = GdipDeleteFontFamily(fontfamily2); 82 expect(Ok, stat); 83 84 /* Test to see if returned size is based on unit (it's not) */ 85 GdipGetFontSize(font, &size); 86 ok (size == 12, "Expected 12, got %f\n", size); 87 GdipDeleteFont(font); 88 89 /* Make sure everything is converted correctly for all Units */ 90 for (i = UnitWorld; i <=UnitMillimeter; i++) 91 { 92 if (i == UnitDisplay) continue; /* Crashes WindowsXP, wtf? */ 93 GdipCreateFont(fontfamily, 24, FontStyleRegular, i, &font); 94 GdipGetFontSize (font, &size); 95 ok (size == 24, "Expected 24, got %f (with unit: %d)\n", size, i); 96 GdipGetFontUnit (font, &unit); 97 expect (i, unit); 98 GdipDeleteFont(font); 99 } 100 101 GdipDeleteFontFamily(fontfamily); 102 } 103 104 static void test_logfont(void) 105 { 106 LOGFONTA lfa, lfa2; 107 GpFont *font; 108 GpFontFamily *family; 109 GpStatus stat; 110 GpGraphics *graphics; 111 HDC hdc = GetDC(0); 112 INT style; 113 REAL rval; 114 UINT16 em_height, line_spacing; 115 Unit unit; 116 117 GdipCreateFromHDC(hdc, &graphics); 118 119 memset(&lfa, 0, sizeof(LOGFONTA)); 120 memset(&lfa2, 0xff, sizeof(LOGFONTA)); 121 lstrcpyA(lfa.lfFaceName, "Tahoma"); 122 123 stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font); 124 expect(Ok, stat); 125 stat = GdipGetLogFontA(font, graphics, &lfa2); 126 expect(Ok, stat); 127 128 ok(lfa2.lfHeight < 0, "Expected negative height\n"); 129 expect(0, lfa2.lfWidth); 130 expect(0, lfa2.lfEscapement); 131 expect(0, lfa2.lfOrientation); 132 ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n"); 133 expect(0, lfa2.lfItalic); 134 expect(0, lfa2.lfUnderline); 135 expect(0, lfa2.lfStrikeOut); 136 ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET, 137 "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet); 138 expect(0, lfa2.lfOutPrecision); 139 expect(0, lfa2.lfClipPrecision); 140 expect(0, lfa2.lfQuality); 141 expect(0, lfa2.lfPitchAndFamily); 142 143 GdipDeleteFont(font); 144 145 memset(&lfa, 0, sizeof(LOGFONTA)); 146 lfa.lfHeight = 25; 147 lfa.lfWidth = 25; 148 lfa.lfEscapement = lfa.lfOrientation = 50; 149 lfa.lfItalic = lfa.lfUnderline = lfa.lfStrikeOut = TRUE; 150 151 memset(&lfa2, 0xff, sizeof(LOGFONTA)); 152 lstrcpyA(lfa.lfFaceName, "Tahoma"); 153 154 stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font); 155 expect(Ok, stat); 156 stat = GdipGetLogFontA(font, graphics, &lfa2); 157 expect(Ok, stat); 158 159 ok(lfa2.lfHeight < 0, "Expected negative height\n"); 160 expect(0, lfa2.lfWidth); 161 expect(0, lfa2.lfEscapement); 162 expect(0, lfa2.lfOrientation); 163 ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n"); 164 expect(TRUE, lfa2.lfItalic); 165 expect(TRUE, lfa2.lfUnderline); 166 expect(TRUE, lfa2.lfStrikeOut); 167 ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET, 168 "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet); 169 expect(0, lfa2.lfOutPrecision); 170 expect(0, lfa2.lfClipPrecision); 171 expect(0, lfa2.lfQuality); 172 expect(0, lfa2.lfPitchAndFamily); 173 174 stat = GdipGetFontStyle(font, &style); 175 expect(Ok, stat); 176 ok (style == (FontStyleItalic | FontStyleUnderline | FontStyleStrikeout), 177 "Expected , got %d\n", style); 178 179 stat = GdipGetFontUnit(font, &unit); 180 expect(Ok, stat); 181 expect(UnitWorld, unit); 182 183 stat = GdipGetFontHeight(font, graphics, &rval); 184 expect(Ok, stat); 185 expectf(25.347656, rval); 186 stat = GdipGetFontSize(font, &rval); 187 expect(Ok, stat); 188 expectf(21.0, rval); 189 190 stat = GdipGetFamily(font, &family); 191 expect(Ok, stat); 192 stat = GdipGetEmHeight(family, FontStyleRegular, &em_height); 193 expect(Ok, stat); 194 expect(2048, em_height); 195 stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing); 196 expect(Ok, stat); 197 expect(2472, line_spacing); 198 GdipDeleteFontFamily(family); 199 200 GdipDeleteFont(font); 201 202 memset(&lfa, 0, sizeof(lfa)); 203 lfa.lfHeight = -25; 204 lstrcpyA(lfa.lfFaceName, "Tahoma"); 205 stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font); 206 expect(Ok, stat); 207 memset(&lfa2, 0xff, sizeof(lfa2)); 208 stat = GdipGetLogFontA(font, graphics, &lfa2); 209 expect(Ok, stat); 210 expect(lfa.lfHeight, lfa2.lfHeight); 211 212 stat = GdipGetFontUnit(font, &unit); 213 expect(Ok, stat); 214 expect(UnitWorld, unit); 215 216 stat = GdipGetFontHeight(font, graphics, &rval); 217 expect(Ok, stat); 218 expectf(30.175781, rval); 219 stat = GdipGetFontSize(font, &rval); 220 expect(Ok, stat); 221 expectf(25.0, rval); 222 223 stat = GdipGetFamily(font, &family); 224 expect(Ok, stat); 225 stat = GdipGetEmHeight(family, FontStyleRegular, &em_height); 226 expect(Ok, stat); 227 expect(2048, em_height); 228 stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing); 229 expect(Ok, stat); 230 expect(2472, line_spacing); 231 GdipDeleteFontFamily(family); 232 233 GdipDeleteFont(font); 234 235 GdipDeleteGraphics(graphics); 236 ReleaseDC(0, hdc); 237 } 238 239 static void test_fontfamily (void) 240 { 241 GpFontFamily *family, *clonedFontFamily; 242 WCHAR itsName[LF_FACESIZE]; 243 GpStatus stat; 244 245 /* FontFamily cannot be NULL */ 246 stat = GdipCreateFontFamilyFromName (Tahoma , NULL, NULL); 247 expect (InvalidParameter, stat); 248 249 /* FontFamily must be able to actually find the family. 250 * If it can't, any subsequent calls should fail. 251 */ 252 stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family); 253 expect (FontFamilyNotFound, stat); 254 255 /* Bitmap fonts are not found */ 256 stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family); 257 expect (FontFamilyNotFound, stat); 258 if(stat == Ok) GdipDeleteFontFamily(family); 259 260 stat = GdipCreateFontFamilyFromName (Tahoma, NULL, &family); 261 expect (Ok, stat); 262 263 stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL); 264 expect (Ok, stat); 265 expect (0, lstrcmpiW(itsName, Tahoma)); 266 267 if (0) 268 { 269 /* Crashes on Windows XP SP2, Vista, and so Wine as well */ 270 stat = GdipGetFamilyName (family, NULL, LANG_NEUTRAL); 271 expect (Ok, stat); 272 } 273 274 /* Make sure we don't read old data */ 275 ZeroMemory (itsName, sizeof(itsName)); 276 stat = GdipCloneFontFamily(family, &clonedFontFamily); 277 expect (Ok, stat); 278 GdipDeleteFontFamily(family); 279 stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL); 280 expect(Ok, stat); 281 expect(0, lstrcmpiW(itsName, Tahoma)); 282 283 GdipDeleteFontFamily(clonedFontFamily); 284 } 285 286 static void test_fontfamily_properties (void) 287 { 288 GpFontFamily* FontFamily = NULL; 289 GpStatus stat; 290 UINT16 result = 0; 291 292 stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &FontFamily); 293 expect(Ok, stat); 294 295 stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result); 296 expect(Ok, stat); 297 ok (result == 2472, "Expected 2472, got %d\n", result); 298 result = 0; 299 stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result); 300 expect(Ok, stat); 301 ok(result == 2048, "Expected 2048, got %d\n", result); 302 result = 0; 303 stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result); 304 expect(Ok, stat); 305 ok(result == 2049, "Expected 2049, got %d\n", result); 306 result = 0; 307 stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result); 308 expect(Ok, stat); 309 ok(result == 423, "Expected 423, got %d\n", result); 310 GdipDeleteFontFamily(FontFamily); 311 312 stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, &FontFamily); 313 if(stat == FontFamilyNotFound) 314 skip("Times New Roman not installed\n"); 315 else 316 { 317 result = 0; 318 stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result); 319 expect(Ok, stat); 320 ok(result == 2355, "Expected 2355, got %d\n", result); 321 result = 0; 322 stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result); 323 expect(Ok, stat); 324 ok(result == 2048, "Expected 2048, got %d\n", result); 325 result = 0; 326 stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result); 327 expect(Ok, stat); 328 ok(result == 1825, "Expected 1825, got %d\n", result); 329 result = 0; 330 stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result); 331 expect(Ok, stat); 332 ok(result == 443, "Expected 443 got %d\n", result); 333 GdipDeleteFontFamily(FontFamily); 334 } 335 } 336 337 static void check_family(const char* context, GpFontFamily *family, WCHAR *name) 338 { 339 GpStatus stat; 340 GpFont* font; 341 342 *name = 0; 343 stat = GdipGetFamilyName(family, name, LANG_NEUTRAL); 344 ok(stat == Ok, "could not get the %s family name: %.8x\n", context, stat); 345 346 stat = GdipCreateFont(family, 12, FontStyleRegular, UnitPixel, &font); 347 ok(stat == Ok, "could not create a font for the %s family: %.8x\n", context, stat); 348 if (stat == Ok) 349 { 350 stat = GdipDeleteFont(font); 351 ok(stat == Ok, "could not delete the %s family font: %.8x\n", context, stat); 352 } 353 354 stat = GdipDeleteFontFamily(family); 355 ok(stat == Ok, "could not delete the %s family: %.8x\n", context, stat); 356 } 357 358 static void test_getgenerics (void) 359 { 360 GpStatus stat; 361 GpFontFamily *family; 362 WCHAR sansname[LF_FACESIZE], serifname[LF_FACESIZE], mononame[LF_FACESIZE]; 363 int missingfonts = 0; 364 365 stat = GdipGetGenericFontFamilySansSerif(&family); 366 expect (Ok, stat); 367 if (stat == FontFamilyNotFound) 368 missingfonts = 1; 369 else 370 check_family("Sans Serif", family, sansname); 371 372 stat = GdipGetGenericFontFamilySerif(&family); 373 expect (Ok, stat); 374 if (stat == FontFamilyNotFound) 375 missingfonts = 1; 376 else 377 check_family("Serif", family, serifname); 378 379 stat = GdipGetGenericFontFamilyMonospace(&family); 380 expect (Ok, stat); 381 if (stat == FontFamilyNotFound) 382 missingfonts = 1; 383 else 384 check_family("Monospace", family, mononame); 385 386 if (missingfonts && strcmp(winetest_platform, "wine") == 0) 387 trace("You may need to install either the Microsoft Web Fonts or the Liberation Fonts\n"); 388 389 /* Check that the family names are all different */ 390 ok(lstrcmpiW(sansname, serifname) != 0, "Sans Serif and Serif families should be different: %s\n", wine_dbgstr_w(sansname)); 391 ok(lstrcmpiW(sansname, mononame) != 0, "Sans Serif and Monospace families should be different: %s\n", wine_dbgstr_w(sansname)); 392 ok(lstrcmpiW(serifname, mononame) != 0, "Serif and Monospace families should be different: %s\n", wine_dbgstr_w(serifname)); 393 } 394 395 static void test_installedfonts (void) 396 { 397 GpStatus stat; 398 GpFontCollection* collection=NULL; 399 400 stat = GdipNewInstalledFontCollection(NULL); 401 expect (InvalidParameter, stat); 402 403 stat = GdipNewInstalledFontCollection(&collection); 404 expect (Ok, stat); 405 ok (collection != NULL, "got NULL font collection\n"); 406 } 407 408 static void test_heightgivendpi(void) 409 { 410 GpStatus stat; 411 GpFont* font = NULL; 412 GpFontFamily* fontfamily = NULL; 413 REAL height; 414 Unit unit; 415 416 stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily); 417 expect(Ok, stat); 418 419 stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font); 420 expect(Ok, stat); 421 422 stat = GdipGetFontHeightGivenDPI(NULL, 96, &height); 423 expect(InvalidParameter, stat); 424 425 stat = GdipGetFontHeightGivenDPI(font, 96, NULL); 426 expect(InvalidParameter, stat); 427 428 stat = GdipGetFontHeightGivenDPI(font, 96, &height); 429 expect(Ok, stat); 430 expectf(36.210938, height); 431 GdipDeleteFont(font); 432 433 height = 12345; 434 stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitWorld, &font); 435 expect(Ok, stat); 436 437 stat = GdipGetFontUnit(font, &unit); 438 expect(Ok, stat); 439 expect(UnitWorld, unit); 440 441 stat = GdipGetFontHeightGivenDPI(font, 96, &height); 442 expect(Ok, stat); 443 expectf(36.210938, height); 444 GdipDeleteFont(font); 445 446 height = 12345; 447 stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPoint, &font); 448 expect(Ok, stat); 449 stat = GdipGetFontHeightGivenDPI(font, 96, &height); 450 expect(Ok, stat); 451 expectf(48.281250, height); 452 GdipDeleteFont(font); 453 454 height = 12345; 455 stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitInch, &font); 456 expect(Ok, stat); 457 458 stat = GdipGetFontUnit(font, &unit); 459 expect(Ok, stat); 460 expect(UnitInch, unit); 461 462 stat = GdipGetFontHeightGivenDPI(font, 96, &height); 463 expect(Ok, stat); 464 expectf(3476.250000, height); 465 GdipDeleteFont(font); 466 467 height = 12345; 468 stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitDocument, &font); 469 expect(Ok, stat); 470 471 stat = GdipGetFontUnit(font, &unit); 472 expect(Ok, stat); 473 expect(UnitDocument, unit); 474 475 stat = GdipGetFontHeightGivenDPI(font, 96, &height); 476 expect(Ok, stat); 477 expectf(11.587500, height); 478 GdipDeleteFont(font); 479 480 height = 12345; 481 stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitMillimeter, &font); 482 expect(Ok, stat); 483 484 stat = GdipGetFontUnit(font, &unit); 485 expect(Ok, stat); 486 expect(UnitMillimeter, unit); 487 488 stat = GdipGetFontHeightGivenDPI(font, 96, &height); 489 expect(Ok, stat); 490 expectf(136.860245, height); 491 GdipDeleteFont(font); 492 493 GdipDeleteFontFamily(fontfamily); 494 } 495 496 static int CALLBACK font_enum_proc(const LOGFONTW *lfe, const TEXTMETRICW *ntme, 497 DWORD type, LPARAM lparam) 498 { 499 NEWTEXTMETRICW *ntm = (NEWTEXTMETRICW *)lparam; 500 501 if (type != TRUETYPE_FONTTYPE) return 1; 502 503 *ntm = *(NEWTEXTMETRICW *)ntme; 504 return 0; 505 } 506 507 struct font_metrics 508 { 509 UINT16 em_height, line_spacing, ascent, descent; 510 REAL font_height, font_size; 511 INT lfHeight; 512 }; 513 514 static void gdi_get_font_metrics(LOGFONTW *lf, struct font_metrics *fm) 515 { 516 HDC hdc; 517 HFONT hfont; 518 NEWTEXTMETRICW ntm; 519 OUTLINETEXTMETRICW otm; 520 int ret; 521 522 hdc = CreateCompatibleDC(0); 523 524 /* it's the only way to get extended NEWTEXTMETRIC fields */ 525 ret = EnumFontFamiliesExW(hdc, lf, font_enum_proc, (LPARAM)&ntm, 0); 526 ok(!ret, "EnumFontFamiliesExW failed to find %s\n", wine_dbgstr_w(lf->lfFaceName)); 527 528 hfont = CreateFontIndirectW(lf); 529 SelectObject(hdc, hfont); 530 531 otm.otmSize = sizeof(otm); 532 ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm); 533 ok(ret, "GetOutlineTextMetrics failed\n"); 534 535 DeleteDC(hdc); 536 DeleteObject(hfont); 537 538 fm->lfHeight = -otm.otmTextMetrics.tmAscent; 539 fm->line_spacing = ntm.ntmCellHeight; 540 fm->font_size = (REAL)otm.otmTextMetrics.tmAscent; 541 fm->font_height = (REAL)fm->line_spacing * fm->font_size / (REAL)ntm.ntmSizeEM; 542 fm->em_height = ntm.ntmSizeEM; 543 fm->ascent = ntm.ntmSizeEM; 544 fm->descent = ntm.ntmCellHeight - ntm.ntmSizeEM; 545 } 546 547 static void gdip_get_font_metrics(GpFont *font, struct font_metrics *fm) 548 { 549 INT style; 550 GpFontFamily *family; 551 GpStatus stat; 552 553 stat = GdipGetFontStyle(font, &style); 554 expect(Ok, stat); 555 556 stat = GdipGetFontHeight(NULL, NULL, &fm->font_height); 557 expect(InvalidParameter, stat); 558 559 stat = GdipGetFontHeight(font, NULL, NULL); 560 expect(InvalidParameter, stat); 561 562 stat = GdipGetFontHeight(font, NULL, &fm->font_height); 563 expect(Ok, stat); 564 stat = GdipGetFontSize(font, &fm->font_size); 565 expect(Ok, stat); 566 567 fm->lfHeight = (INT)(fm->font_size * -1.0); 568 569 stat = GdipGetFamily(font, &family); 570 expect(Ok, stat); 571 572 stat = GdipGetEmHeight(family, style, &fm->em_height); 573 expect(Ok, stat); 574 stat = GdipGetLineSpacing(family, style, &fm->line_spacing); 575 expect(Ok, stat); 576 stat = GdipGetCellAscent(family, style, &fm->ascent); 577 expect(Ok, stat); 578 stat = GdipGetCellDescent(family, style, &fm->descent); 579 expect(Ok, stat); 580 581 GdipDeleteFontFamily(family); 582 } 583 584 static void cmp_font_metrics(struct font_metrics *fm1, struct font_metrics *fm2, int line) 585 { 586 ok_(__FILE__, line)(fm1->lfHeight == fm2->lfHeight, "lfHeight %d != %d\n", fm1->lfHeight, fm2->lfHeight); 587 ok_(__FILE__, line)(fm1->em_height == fm2->em_height, "em_height %u != %u\n", fm1->em_height, fm2->em_height); 588 ok_(__FILE__, line)(fm1->line_spacing == fm2->line_spacing, "line_spacing %u != %u\n", fm1->line_spacing, fm2->line_spacing); 589 ok_(__FILE__, line)(abs(fm1->ascent - fm2->ascent) <= 1, "ascent %u != %u\n", fm1->ascent, fm2->ascent); 590 ok_(__FILE__, line)(abs(fm1->descent - fm2->descent) <= 1, "descent %u != %u\n", fm1->descent, fm2->descent); 591 ok(fm1->font_height > 0.0, "fm1->font_height should be positive, got %f\n", fm1->font_height); 592 ok(fm2->font_height > 0.0, "fm2->font_height should be positive, got %f\n", fm2->font_height); 593 ok_(__FILE__, line)(fm1->font_height == fm2->font_height, "font_height %f != %f\n", fm1->font_height, fm2->font_height); 594 ok(fm1->font_size > 0.0, "fm1->font_size should be positive, got %f\n", fm1->font_size); 595 ok(fm2->font_size > 0.0, "fm2->font_size should be positive, got %f\n", fm2->font_size); 596 ok_(__FILE__, line)(fm1->font_size == fm2->font_size, "font_size %f != %f\n", fm1->font_size, fm2->font_size); 597 } 598 599 static void test_font_metrics(void) 600 { 601 LOGFONTW lf; 602 GpFont *font; 603 GpFontFamily *family; 604 GpGraphics *graphics; 605 GpStatus stat; 606 Unit unit; 607 struct font_metrics fm_gdi, fm_gdip; 608 HDC hdc; 609 610 hdc = CreateCompatibleDC(0); 611 stat = GdipCreateFromHDC(hdc, &graphics); 612 expect(Ok, stat); 613 614 memset(&lf, 0, sizeof(lf)); 615 616 /* Tahoma,-13 */ 617 lstrcpyW(lf.lfFaceName, Tahoma); 618 lf.lfHeight = -13; 619 stat = GdipCreateFontFromLogfontW(hdc, &lf, &font); 620 expect(Ok, stat); 621 622 stat = GdipGetFontUnit(font, &unit); 623 expect(Ok, stat); 624 expect(UnitWorld, unit); 625 626 gdip_get_font_metrics(font, &fm_gdip); 627 trace("gdiplus:\n"); 628 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 629 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 630 fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent, 631 fm_gdip.font_height, fm_gdip.font_size); 632 633 gdi_get_font_metrics(&lf, &fm_gdi); 634 trace("gdi:\n"); 635 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 636 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 637 fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent, 638 fm_gdi.font_height, fm_gdi.font_size); 639 640 cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__); 641 642 stat = GdipGetLogFontW(font, graphics, &lf); 643 expect(Ok, stat); 644 ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight); 645 gdi_get_font_metrics(&lf, &fm_gdi); 646 trace("gdi:\n"); 647 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 648 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 649 fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent, 650 fm_gdi.font_height, fm_gdi.font_size); 651 ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size); 652 653 cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__); 654 655 GdipDeleteFont(font); 656 657 /* Tahoma,13 */ 658 lstrcpyW(lf.lfFaceName, Tahoma); 659 lf.lfHeight = 13; 660 stat = GdipCreateFontFromLogfontW(hdc, &lf, &font); 661 expect(Ok, stat); 662 663 stat = GdipGetFontUnit(font, &unit); 664 expect(Ok, stat); 665 expect(UnitWorld, unit); 666 667 gdip_get_font_metrics(font, &fm_gdip); 668 trace("gdiplus:\n"); 669 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 670 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 671 fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent, 672 fm_gdip.font_height, fm_gdip.font_size); 673 674 gdi_get_font_metrics(&lf, &fm_gdi); 675 trace("gdi:\n"); 676 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 677 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 678 fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent, 679 fm_gdi.font_height, fm_gdi.font_size); 680 681 cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__); 682 683 stat = GdipGetLogFontW(font, graphics, &lf); 684 expect(Ok, stat); 685 ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight); 686 gdi_get_font_metrics(&lf, &fm_gdi); 687 trace("gdi:\n"); 688 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 689 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 690 fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent, 691 fm_gdi.font_height, fm_gdi.font_size); 692 ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size); 693 694 cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__); 695 696 GdipDeleteFont(font); 697 698 stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &family); 699 expect(Ok, stat); 700 701 /* Tahoma,13 */ 702 stat = GdipCreateFont(family, 13.0, FontStyleRegular, UnitPixel, &font); 703 expect(Ok, stat); 704 705 gdip_get_font_metrics(font, &fm_gdip); 706 trace("gdiplus:\n"); 707 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 708 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 709 fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent, 710 fm_gdip.font_height, fm_gdip.font_size); 711 712 stat = GdipGetLogFontW(font, graphics, &lf); 713 expect(Ok, stat); 714 ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight); 715 gdi_get_font_metrics(&lf, &fm_gdi); 716 trace("gdi:\n"); 717 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n", 718 wine_dbgstr_w(lf.lfFaceName), lf.lfHeight, 719 fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent, 720 fm_gdi.font_height, fm_gdi.font_size); 721 ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size); 722 723 cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__); 724 725 stat = GdipGetLogFontW(font, NULL, &lf); 726 expect(InvalidParameter, stat); 727 728 GdipDeleteFont(font); 729 730 stat = GdipCreateFont(family, -13.0, FontStyleRegular, UnitPixel, &font); 731 expect(InvalidParameter, stat); 732 733 GdipDeleteFontFamily(family); 734 735 GdipDeleteGraphics(graphics); 736 DeleteDC(hdc); 737 } 738 739 static void test_font_substitution(void) 740 { 741 WCHAR ms_shell_dlg[LF_FACESIZE]; 742 char fallback_font[LF_FACESIZE]; 743 HDC hdc; 744 HFONT hfont; 745 LOGFONTA lf; 746 GpStatus status; 747 GpGraphics *graphics; 748 GpFont *font; 749 GpFontFamily *family; 750 int ret; 751 752 hdc = CreateCompatibleDC(0); 753 status = GdipCreateFromHDC(hdc, &graphics); 754 expect(Ok, status); 755 756 hfont = GetStockObject(DEFAULT_GUI_FONT); 757 ok(hfont != 0, "GetStockObject(DEFAULT_GUI_FONT) failed\n"); 758 759 memset(&lf, 0xfe, sizeof(lf)); 760 ret = GetObjectA(hfont, sizeof(lf), &lf); 761 ok(ret == sizeof(lf), "GetObject failed\n"); 762 ok(!lstrcmpA(lf.lfFaceName, "MS Shell Dlg"), "wrong face name %s\n", lf.lfFaceName); 763 MultiByteToWideChar(CP_ACP, 0, lf.lfFaceName, -1, ms_shell_dlg, LF_FACESIZE); 764 765 status = GdipCreateFontFromLogfontA(hdc, &lf, &font); 766 expect(Ok, status); 767 memset(&lf, 0xfe, sizeof(lf)); 768 status = GdipGetLogFontA(font, graphics, &lf); 769 expect(Ok, status); 770 ok(!lstrcmpA(lf.lfFaceName, "Microsoft Sans Serif") || 771 !lstrcmpA(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName); 772 GdipDeleteFont(font); 773 774 status = GdipCreateFontFamilyFromName(ms_shell_dlg, NULL, &family); 775 expect(Ok, status); 776 status = GdipCreateFont(family, 12, FontStyleRegular, UnitPoint, &font); 777 expect(Ok, status); 778 memset(&lf, 0xfe, sizeof(lf)); 779 status = GdipGetLogFontA(font, graphics, &lf); 780 expect(Ok, status); 781 ok(!lstrcmpA(lf.lfFaceName, "Microsoft Sans Serif") || 782 !lstrcmpA(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName); 783 GdipDeleteFont(font); 784 GdipDeleteFontFamily(family); 785 786 status = GdipCreateFontFamilyFromName(nonexistent, NULL, &family); 787 ok(status == FontFamilyNotFound, "expected FontFamilyNotFound, got %d\n", status); 788 789 /* nonexistent fonts fallback to Arial, or something else if it's missing */ 790 strcpy(lf.lfFaceName,"Arial"); 791 status = GdipCreateFontFromLogfontA(hdc, &lf, &font); 792 expect(Ok, status); 793 status = GdipGetLogFontA(font, graphics, &lf); 794 expect(Ok, status); 795 strcpy(fallback_font,lf.lfFaceName); 796 trace("fallback font %s\n", fallback_font); 797 GdipDeleteFont(font); 798 799 lstrcpyA(lf.lfFaceName, "ThisFontShouldNotExist"); 800 status = GdipCreateFontFromLogfontA(hdc, &lf, &font); 801 expect(Ok, status); 802 memset(&lf, 0xfe, sizeof(lf)); 803 status = GdipGetLogFontA(font, graphics, &lf); 804 expect(Ok, status); 805 ok(!lstrcmpA(lf.lfFaceName, fallback_font), "wrong face name %s / %s\n", lf.lfFaceName, fallback_font); 806 GdipDeleteFont(font); 807 808 /* empty FaceName */ 809 lf.lfFaceName[0] = 0; 810 status = GdipCreateFontFromLogfontA(hdc, &lf, &font); 811 expect(Ok, status); 812 memset(&lf, 0xfe, sizeof(lf)); 813 status = GdipGetLogFontA(font, graphics, &lf); 814 expect(Ok, status); 815 ok(!lstrcmpA(lf.lfFaceName, fallback_font), "wrong face name %s / %s\n", lf.lfFaceName, fallback_font); 816 GdipDeleteFont(font); 817 818 /* zeroing out lfWeight and lfCharSet leads to font creation failure */ 819 lf.lfWeight = 0; 820 lf.lfCharSet = 0; 821 lstrcpyA(lf.lfFaceName, "ThisFontShouldNotExist"); 822 font = NULL; 823 status = GdipCreateFontFromLogfontA(hdc, &lf, &font); 824 todo_wine 825 ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */ 826 "expected NotTrueTypeFont, got %d\n", status); 827 /* FIXME: remove when wine is fixed */ 828 if (font) GdipDeleteFont(font); 829 830 /* empty FaceName */ 831 lf.lfFaceName[0] = 0; 832 font = NULL; 833 status = GdipCreateFontFromLogfontA(hdc, &lf, &font); 834 todo_wine 835 ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */ 836 "expected NotTrueTypeFont, got %d\n", status); 837 /* FIXME: remove when wine is fixed */ 838 if (font) GdipDeleteFont(font); 839 840 GdipDeleteGraphics(graphics); 841 DeleteDC(hdc); 842 } 843 844 static void test_font_transform(void) 845 { 846 static const WCHAR string[] = { 'A',0 }; 847 GpStatus status; 848 HDC hdc; 849 LOGFONTA lf; 850 GpFont *font; 851 GpGraphics *graphics; 852 GpMatrix *matrix; 853 GpStringFormat *format, *typographic; 854 PointF pos[1] = { { 0,0 } }; 855 REAL height, margin_y; 856 RectF bounds, rect; 857 858 hdc = CreateCompatibleDC(0); 859 status = GdipCreateFromHDC(hdc, &graphics); 860 expect(Ok, status); 861 862 status = GdipSetPageUnit(graphics, UnitPixel); 863 expect(Ok, status); 864 865 status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format); 866 expect(Ok, status); 867 status = GdipStringFormatGetGenericTypographic(&typographic); 868 expect(Ok, status); 869 870 memset(&lf, 0, sizeof(lf)); 871 lstrcpyA(lf.lfFaceName, "Tahoma"); 872 lf.lfHeight = -100; 873 lf.lfWidth = 100; 874 status = GdipCreateFontFromLogfontA(hdc, &lf, &font); 875 expect(Ok, status); 876 877 margin_y = 100.0 / 8.0; 878 879 /* identity matrix */ 880 status = GdipCreateMatrix(&matrix); 881 expect(Ok, status); 882 status = GdipSetWorldTransform(graphics, matrix); 883 expect(Ok, status); 884 status = GdipGetLogFontA(font, graphics, &lf); 885 expect(Ok, status); 886 expect(-100, lf.lfHeight); 887 expect(0, lf.lfWidth); 888 expect(0, lf.lfEscapement); 889 expect(0, lf.lfOrientation); 890 status = GdipGetFontHeight(font, graphics, &height); 891 expect(Ok, status); 892 expectf(120.703125, height); 893 set_rect_empty(&rect); 894 set_rect_empty(&bounds); 895 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL); 896 expect(Ok, status); 897 expectf(0.0, bounds.X); 898 expectf(0.0, bounds.Y); 899 todo_wine 900 expectf(height + margin_y, bounds.Height); 901 set_rect_empty(&rect); 902 set_rect_empty(&bounds); 903 status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL); 904 expect(Ok, status); 905 expectf(0.0, bounds.X); 906 expectf(0.0, bounds.Y); 907 expectf_(height, bounds.Height, 1.0); 908 set_rect_empty(&bounds); 909 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 910 DriverStringOptionsCmapLookup, NULL, &bounds); 911 expect(Ok, status); 912 expectf(0.0, bounds.X); 913 expectf_(-100.0, bounds.Y, 0.05); 914 expectf_(height, bounds.Height, 0.5); 915 set_rect_empty(&bounds); 916 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 917 DriverStringOptionsCmapLookup, matrix, &bounds); 918 expect(Ok, status); 919 expectf(0.0, bounds.X); 920 expectf_(-100.0, bounds.Y, 0.05); 921 expectf_(height, bounds.Height, 0.5); 922 923 /* scale matrix */ 924 status = GdipScaleMatrix(matrix, 2.0, 3.0, MatrixOrderAppend); 925 expect(Ok, status); 926 status = GdipSetWorldTransform(graphics, matrix); 927 expect(Ok, status); 928 status = GdipGetLogFontA(font, graphics, &lf); 929 expect(Ok, status); 930 expect(-300, lf.lfHeight); 931 expect(0, lf.lfWidth); 932 expect(0, lf.lfEscapement); 933 expect(0, lf.lfOrientation); 934 status = GdipGetFontHeight(font, graphics, &height); 935 expect(Ok, status); 936 expectf(120.703125, height); 937 set_rect_empty(&rect); 938 set_rect_empty(&bounds); 939 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL); 940 expect(Ok, status); 941 expectf(0.0, bounds.X); 942 expectf(0.0, bounds.Y); 943 todo_wine 944 expectf(height + margin_y, bounds.Height); 945 set_rect_empty(&rect); 946 set_rect_empty(&bounds); 947 status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL); 948 expect(Ok, status); 949 expectf(0.0, bounds.X); 950 expectf(0.0, bounds.Y); 951 expectf_(height, bounds.Height, 0.05); 952 set_rect_empty(&bounds); 953 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 954 DriverStringOptionsCmapLookup, NULL, &bounds); 955 expect(Ok, status); 956 expectf(0.0, bounds.X); 957 expectf_(-100.0, bounds.Y, 0.05); 958 expectf_(height, bounds.Height, 0.2); 959 set_rect_empty(&bounds); 960 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 961 DriverStringOptionsCmapLookup, matrix, &bounds); 962 expect(Ok, status); 963 expectf(0.0, bounds.X); 964 todo_wine 965 expectf_(-300.0, bounds.Y, 0.15); 966 todo_wine 967 expectf(height * 3.0, bounds.Height); 968 969 /* scale + ratate matrix */ 970 status = GdipRotateMatrix(matrix, 45.0, MatrixOrderAppend); 971 expect(Ok, status); 972 status = GdipSetWorldTransform(graphics, matrix); 973 expect(Ok, status); 974 status = GdipGetLogFontA(font, graphics, &lf); 975 expect(Ok, status); 976 expect(-300, lf.lfHeight); 977 expect(0, lf.lfWidth); 978 expect_(3151, lf.lfEscapement, 1); 979 expect_(3151, lf.lfOrientation, 1); 980 status = GdipGetFontHeight(font, graphics, &height); 981 expect(Ok, status); 982 expectf(120.703125, height); 983 set_rect_empty(&rect); 984 set_rect_empty(&bounds); 985 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL); 986 expect(Ok, status); 987 expectf(0.0, bounds.X); 988 expectf(0.0, bounds.Y); 989 todo_wine 990 expectf(height + margin_y, bounds.Height); 991 set_rect_empty(&rect); 992 set_rect_empty(&bounds); 993 status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL); 994 expect(Ok, status); 995 expectf(0.0, bounds.X); 996 expectf(0.0, bounds.Y); 997 expectf_(height, bounds.Height, 0.05); 998 set_rect_empty(&bounds); 999 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 1000 DriverStringOptionsCmapLookup, NULL, &bounds); 1001 expect(Ok, status); 1002 expectf(0.0, bounds.X); 1003 expectf_(-100.0, bounds.Y, 0.05); 1004 expectf_(height, bounds.Height, 0.2); 1005 set_rect_empty(&bounds); 1006 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 1007 DriverStringOptionsCmapLookup, matrix, &bounds); 1008 expect(Ok, status); 1009 todo_wine 1010 expectf_(-43.814377, bounds.X, 0.05); 1011 todo_wine 1012 expectf_(-212.235611, bounds.Y, 0.05); 1013 todo_wine 1014 expectf_(340.847534, bounds.Height, 0.05); 1015 1016 /* scale + ratate + shear matrix */ 1017 status = GdipShearMatrix(matrix, 4.0, 5.0, MatrixOrderAppend); 1018 expect(Ok, status); 1019 status = GdipSetWorldTransform(graphics, matrix); 1020 expect(Ok, status); 1021 status = GdipGetLogFontA(font, graphics, &lf); 1022 expect(Ok, status); 1023 todo_wine 1024 expect(1032, lf.lfHeight); 1025 expect(0, lf.lfWidth); 1026 expect_(3099, lf.lfEscapement, 1); 1027 expect_(3099, lf.lfOrientation, 1); 1028 status = GdipGetFontHeight(font, graphics, &height); 1029 expect(Ok, status); 1030 expectf(120.703125, height); 1031 set_rect_empty(&rect); 1032 set_rect_empty(&bounds); 1033 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL); 1034 expect(Ok, status); 1035 expectf(0.0, bounds.X); 1036 expectf(0.0, bounds.Y); 1037 todo_wine 1038 expectf(height + margin_y, bounds.Height); 1039 set_rect_empty(&rect); 1040 set_rect_empty(&bounds); 1041 status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL); 1042 expect(Ok, status); 1043 expectf(0.0, bounds.X); 1044 expectf(0.0, bounds.Y); 1045 expectf_(height, bounds.Height, 0.2); 1046 set_rect_empty(&bounds); 1047 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 1048 DriverStringOptionsCmapLookup, NULL, &bounds); 1049 expect(Ok, status); 1050 expectf(0.0, bounds.X); 1051 expectf_(-100.0, bounds.Y, 0.2); 1052 expectf_(height, bounds.Height, 0.2); 1053 set_rect_empty(&bounds); 1054 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 1055 DriverStringOptionsCmapLookup, matrix, &bounds); 1056 expect(Ok, status); 1057 todo_wine 1058 expectf_(-636.706848, bounds.X, 0.05); 1059 todo_wine 1060 expectf_(-175.257523, bounds.Y, 0.05); 1061 todo_wine 1062 expectf_(1532.984985, bounds.Height, 0.05); 1063 1064 /* scale + ratate + shear + translate matrix */ 1065 status = GdipTranslateMatrix(matrix, 10.0, 20.0, MatrixOrderAppend); 1066 expect(Ok, status); 1067 status = GdipSetWorldTransform(graphics, matrix); 1068 expect(Ok, status); 1069 status = GdipGetLogFontA(font, graphics, &lf); 1070 expect(Ok, status); 1071 todo_wine 1072 expect(1032, lf.lfHeight); 1073 expect(0, lf.lfWidth); 1074 expect_(3099, lf.lfEscapement, 1); 1075 expect_(3099, lf.lfOrientation, 1); 1076 status = GdipGetFontHeight(font, graphics, &height); 1077 expect(Ok, status); 1078 expectf(120.703125, height); 1079 set_rect_empty(&rect); 1080 set_rect_empty(&bounds); 1081 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL); 1082 expect(Ok, status); 1083 expectf(0.0, bounds.X); 1084 expectf(0.0, bounds.Y); 1085 todo_wine 1086 expectf(height + margin_y, bounds.Height); 1087 set_rect_empty(&rect); 1088 set_rect_empty(&bounds); 1089 status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL); 1090 expect(Ok, status); 1091 expectf(0.0, bounds.X); 1092 expectf(0.0, bounds.Y); 1093 expectf_(height, bounds.Height, 0.1); 1094 set_rect_empty(&bounds); 1095 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 1096 DriverStringOptionsCmapLookup, NULL, &bounds); 1097 expect(Ok, status); 1098 expectf(0.0, bounds.X); 1099 expectf_(-100.0, bounds.Y, 0.2); 1100 expectf_(height, bounds.Height, 0.2); 1101 set_rect_empty(&bounds); 1102 status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos, 1103 DriverStringOptionsCmapLookup, matrix, &bounds); 1104 expect(Ok, status); 1105 todo_wine 1106 expectf_(-626.706848, bounds.X, 0.05); 1107 todo_wine 1108 expectf_(-155.257523, bounds.Y, 0.05); 1109 todo_wine 1110 expectf_(1532.984985, bounds.Height, 0.05); 1111 1112 GdipDeleteMatrix(matrix); 1113 GdipDeleteFont(font); 1114 GdipDeleteGraphics(graphics); 1115 GdipDeleteStringFormat(typographic); 1116 GdipDeleteStringFormat(format); 1117 DeleteDC(hdc); 1118 } 1119 1120 START_TEST(font) 1121 { 1122 struct GdiplusStartupInput gdiplusStartupInput; 1123 ULONG_PTR gdiplusToken; 1124 HMODULE hmsvcrt; 1125 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); 1126 1127 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ 1128 hmsvcrt = LoadLibraryA("msvcrt"); 1129 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); 1130 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); 1131 1132 gdiplusStartupInput.GdiplusVersion = 1; 1133 gdiplusStartupInput.DebugEventCallback = NULL; 1134 gdiplusStartupInput.SuppressBackgroundThread = 0; 1135 gdiplusStartupInput.SuppressExternalCodecs = 0; 1136 1137 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 1138 1139 test_font_transform(); 1140 if (!winetest_interactive) 1141 skip("ROSTESTS-154: Skipping test_font_substitution because of improper error handling\n"); 1142 else 1143 test_font_substitution(); 1144 test_font_metrics(); 1145 test_createfont(); 1146 test_logfont(); 1147 test_fontfamily(); 1148 test_fontfamily_properties(); 1149 test_getgenerics(); 1150 test_installedfonts(); 1151 test_heightgivendpi(); 1152 1153 GdiplusShutdown(gdiplusToken); 1154 } 1155