From: Paul Gofman pgofman@codeweavers.com
--- dlls/gdi32/tests/Makefile.in | 1 + dlls/gdi32/tests/font.c | 71 ++++++++++ dlls/gdi32/tests/resource.rc | 3 + dlls/gdi32/tests/wine_heavy.sfd | 244 ++++++++++++++++++++++++++++++++ dlls/gdi32/tests/wine_heavy.ttf | Bin 0 -> 1784 bytes 5 files changed, 319 insertions(+) create mode 100644 dlls/gdi32/tests/wine_heavy.sfd create mode 100644 dlls/gdi32/tests/wine_heavy.ttf
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in index d6f33ee087d..db8b7c7e5b1 100644 --- a/dlls/gdi32/tests/Makefile.in +++ b/dlls/gdi32/tests/Makefile.in @@ -24,6 +24,7 @@ SOURCES = \ wine_langnames3.sfd \ wine_longname.sfd \ wine_nul.sfd \ + wine_heavy.sfd \ wine_test.sfd \ wine_ttfnames.sfd \ wine_ttfnames_bold.sfd \ diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 0513c2b2ca8..198fba2d847 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -7767,6 +7767,76 @@ static void test_GetOutlineTextMetrics_subst(void) ReleaseDC(0, hdc); }
+static INT CALLBACK test_font_weight_enum(const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lparam +) +{ + const NEWTEXTMETRICW *ntm = (const NEWTEXTMETRICW *)tm; + int *called = (int *)lparam; + + if (type != TRUETYPE_FONTTYPE) return 1; + ok(!wcscmp(lf->lfFaceName, L"wine_heavy"), "got %s.\n", debugstr_w(lf->lfFaceName)); + ok((ntm->ntmFlags & (NTM_REGULAR | NTM_BOLD)) == NTM_REGULAR, "got %#lx.\n", ntm->ntmFlags); + todo_wine ok(ntm->tmWeight == 700, "got %ld.\n", ntm->tmWeight); + *called = 1; + + return 1; +} + +static void test_font_weight(void) +{ + HFONT hfont1, hfont2, old; + char ttf_name[MAX_PATH]; + TEXTMETRICW tm1, tm2; + int enum_called; + LOGFONTW lf; + DWORD count; + BOOL bret; + HDC hdc; + + bret = write_ttf_file("wine_heavy.ttf", ttf_name); + ok(bret, "Failed to create test font file.\n"); + + count = AddFontResourceExA(ttf_name, 0, NULL); + ok(count == 1, "got %lu.\n", count); + + hdc = GetDC(NULL); + + memset(&lf, 0, sizeof(lf)); + wcscpy(lf.lfFaceName, L"wine_heavy"); + lf.lfHeight = 90; + lf.lfWeight = FW_BOLD; + lf.lfCharSet = DEFAULT_CHARSET; + + enum_called = 0; + EnumFontFamiliesExW(hdc, &lf, test_font_weight_enum, (LPARAM)&enum_called, 0); + ok(enum_called, "font not found.\n"); + + enum_called = 0; + lf.lfWeight = FW_REGULAR; + EnumFontFamiliesExW(hdc, &lf, test_font_weight_enum, (LPARAM)&enum_called, 0); + ok(enum_called, "font not found.\n"); + + lf.lfWeight = FW_REGULAR; + hfont1 = CreateFontIndirectW(&lf); + lf.lfWeight = FW_BOLD; + hfont2 = CreateFontIndirectW(&lf); + + old = SelectObject(hdc, hfont1); + memset(&tm1, 0, sizeof(tm1)); + GetTextMetricsW(hdc, &tm1); + SelectObject(hdc, hfont2); + memset(&tm2, 0, sizeof(tm2)); + GetTextMetricsW(hdc, &tm2); + todo_wine ok(tm1.tmMaxCharWidth == tm2.tmMaxCharWidth, "got %ld, %ld.\n", tm1.tmMaxCharWidth, tm2.tmMaxCharWidth); + + SelectObject(hdc, old); + ReleaseDC(NULL, hdc); + DeleteObject(hfont1); + DeleteObject(hfont2); + bret = RemoveFontResourceExA(ttf_name, 0, NULL); + ok(bret, "got error %ld\n", GetLastError()); +} + START_TEST(font) { static const char *test_names[] = @@ -7856,6 +7926,7 @@ START_TEST(font) test_lang_names(); test_char_width(); test_select_object(); + test_font_weight();
/* These tests should be last test until RemoveFontResource * is properly implemented. diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc index 784d8602a9a..477d07de45d 100644 --- a/dlls/gdi32/tests/resource.rc +++ b/dlls/gdi32/tests/resource.rc @@ -49,3 +49,6 @@ wine_langnames3.ttf RCDATA wine_langnames3.ttf
/* @makedep: wine_nul.ttf */ wine_nul.ttf RCDATA wine_nul.ttf + +/* @makedep: wine_heavy.ttf */ +wine_heavy.ttf RCDATA wine_heavy.ttf diff --git a/dlls/gdi32/tests/wine_heavy.sfd b/dlls/gdi32/tests/wine_heavy.sfd new file mode 100644 index 00000000000..40269910232 --- /dev/null +++ b/dlls/gdi32/tests/wine_heavy.sfd @@ -0,0 +1,244 @@ +SplineFontDB: 3.0 +FontName: wine_heavy +FullName: wine_heavy +FamilyName: wine_heavy +Weight: Regular +Copyright: Copyright (c) 2024 Wine Test Suite +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -205 +UnderlineWidth: 102 +Ascent: 1638 +Descent: 410 +sfntRevision: 0x00010000 +LayerCount: 2 +Layer: 0 1 "Back" 1 +Layer: 1 1 "Fore" 0 +XUID: [1021 905 592216984 1247726] +FSType: 32767 +OS2Version: 2 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +PfmFamily: 17 +TTFWeight: 700 +TTFWidth: 5 +LineGap: 184 +VLineGap: 0 +Panose: 2 0 6 3 0 0 0 0 0 0 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 184 +OS2WinAscent: 1638 +OS2WinAOffset: 0 +OS2WinDescent: 410 +OS2WinDOffset: 0 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2SubXSize: 1331 +OS2SubYSize: 1433 +OS2SubXOff: 0 +OS2SubYOff: 286 +OS2SupXSize: 1331 +OS2SupYSize: 1433 +OS2SupXOff: 0 +OS2SupYOff: 983 +OS2StrikeYSize: 102 +OS2StrikeYPos: 530 +OS2Vendor: 'Wine' +OS2CodePages: 00000001.00000000 +OS2UnicodeRanges: 00000001.00000000.00000000.00000000 +MarkAttachClasses: 1 +DEI: 91125 +ShortTable: cvt 2 + 68 + 1297 +EndShort +ShortTable: maxp 16 + 1 + 0 + 4 + 8 + 2 + 0 + 0 + 2 + 0 + 1 + 1 + 0 + 64 + 46 + 0 + 0 +EndShort +LangName: 1033 "" "" "" "Wine : wine_heavy : 5-07-2024" +GaspTable: 1 65535 2 0 +Encoding: UnicodeBmp +UnicodeInterp: none +NameList: Adobe Glyph List +DisplaySize: -24 +AntiAlias: 1 +FitToEm: 1 +WinInfo: 48 16 4 +BeginPrivate: 0 +EndPrivate +BeginChars: 65539 7 + +StartChar: .notdef +Encoding: 65536 -1 0 +AltUni2: 00fffe.ffffffff.0 00fffd.ffffffff.0 00fffc.ffffffff.0 00fffb.ffffffff.0 +Width: 748 +Flags: W +TtInstrs: +PUSHB_2 + 1 + 0 +MDAP[rnd] +ALIGNRP +PUSHB_3 + 7 + 4 + 0 +MIRP[min,rnd,black] +SHP[rp2] +PUSHB_2 + 6 + 5 +MDRP[rp0,min,rnd,grey] +ALIGNRP +PUSHB_3 + 3 + 2 + 0 +MIRP[min,rnd,black] +SHP[rp2] +SVTCA[y-axis] +PUSHB_2 + 3 + 0 +MDAP[rnd] +ALIGNRP +PUSHB_3 + 5 + 4 + 0 +MIRP[min,rnd,black] +SHP[rp2] +PUSHB_3 + 7 + 6 + 1 +MIRP[rp0,min,rnd,grey] +ALIGNRP +PUSHB_3 + 1 + 2 + 0 +MIRP[min,rnd,black] +SHP[rp2] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +68 0 m 1,0,-1 + 68 1365 l 1,1,-1 + 612 1365 l 1,2,-1 + 612 0 l 1,3,-1 + 68 0 l 1,0,-1 +136 68 m 1,4,-1 + 544 68 l 1,5,-1 + 544 1297 l 1,6,-1 + 136 1297 l 1,7,-1 + 136 68 l 1,4,-1 +EndSplineSet +EndChar + +StartChar: .null +Encoding: 65537 -1 1 +Width: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: nonmarkingreturn +Encoding: 65538 -1 2 +Width: 682 +Flags: W +LayerCount: 2 +EndChar + +StartChar: exclam +Encoding: 33 33 3 +Width: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: dieresis +Encoding: 168 168 4 +Width: 1000 +VWidth: 0 +Flags: W +LayerCount: 2 +Fore +SplineSet +620.215 824.429 m 1,0,1 + 760.84 777.554 760.84 777.554 713.965 636.929 c 1,2,-1 + 620.215 824.429 l 1,0,1 +154.883 324.971 m 0,3,-1 +254.492 773.213 m 1,4,5 + 310.707 834.805 310.707 834.805 374.609 767.354 c 1,6,7 + 410.471 728.672 410.471 728.672 374.609 691.182 c 0,8,9 + 308.375 621.934 308.375 621.934 254.492 688.252 c 0,10,11 + 216.406 735.127 216.406 735.127 254.492 773.213 c 1,4,5 +254.492 773.213 m 1,12,13 + 216.406 735.127 216.406 735.127 254.492 688.252 c 0,14,15 + 308.375 621.934 308.375 621.934 374.609 691.182 c 0,16,17 + 410.471 728.672 410.471 728.672 374.609 767.354 c 1,18,19 + 310.707 834.805 310.707 834.805 254.492 773.213 c 1,12,13 +EndSplineSet +EndChar + +StartChar: A +Encoding: 65 65 5 +Width: 1000 +VWidth: 0 +Flags: WO +LayerCount: 2 +Fore +SplineSet +459 1258 m 25,0,-1 + 462 1639 l 1,1,-1 + 389 1638 l 1,2,-1 + 492 1815 l 1,3,-1 + 609 1638.5 l 1,4,-1 + 531 1637.5 l 1,5,-1 + 523 1258 l 1,6,-1 + 459 1258 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: D +Encoding: 68 68 6 +Width: 1000 +VWidth: 0 +Flags: WO +LayerCount: 2 +Fore +SplineSet +461 -30.7998 m 25,0,-1 + 464 -411.8 l 1,1,-1 + 391 -410.8 l 1,2,-1 + 494 -587.8 l 1,3,-1 + 611 -411.3 l 1,4,-1 + 533 -410.3 l 1,5,-1 + 525 -30.7998 l 1,6,-1 + 461 -30.7998 l 25,0,-1 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/dlls/gdi32/tests/wine_heavy.ttf b/dlls/gdi32/tests/wine_heavy.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e3b7e7fd80e923c18e5d1969d4a4f4898cc1a4b4 GIT binary patch literal 1784 zcmcIlPfVL-82`QBUjzeV5K0VV9~Qr|L}=G-tu|<IEvSj85w^vPw3hxerES{6Mx2?6 zE=x@2Sy|#?7Z;r-MGhQ1?6{~qXkxr9MmdqW9XxnIM?Zh>*AEzR2M_u*Z{OeZ=Y9UX z@6)Fc06Ot5R3xXSW~V<*c3c6B+msGGpO~CN0HfsB$lI^X1jC)LS04jJo_sRBkg7Pp z9r%R&FI;b>m+BT0dN-iHM7@?v)hdod&oHi&Z_5>zv%kiE_=@@@?UB!<<^$i2zDeC( zu1KDO_HV>h>W0Y==NIbdI&>vX{wDeUVmY0{b<xlBuaZBokUCevG$yHkfxJ~pEo9dF zf4sraNkAE>lxub8ieSFRdFn$9DZ?V%)q8%fYy1x!ZleI$_~Q3lyL)1LP1!Pi<lCS~ zDT!xH-}V~T)lJDNTdpSwcSv_7CVHW{B6(7{vI&g25>4GyzJ`9m(U0jLQ#sh$)t``6 z4$>zK-jhc%&s{oGC}sFQL%3#Sn^~+IS+PRpgEkg~au*4CMER_BP~8+4#U)5f=~u1+ z@60?od3u1k%6n^fD^(aFfoo2aF9zc0i2rgNX9IBFphTXK*Yzk@t45v3BVp_%BxLP7 zH@9m*uvg!XbpKAT54hZ~`;R%M`+tzz`*_m(OkkGprpR|u=Jivo-^5r$AUM8iYPc6} z82at;RaGHGLzQA(idRiT+#g@%HQoy!>mKTUVyJs4p;*mf@li9cpZfFjgeJRHh>O}C zCB;saci&@1eSTGZtG<|9e7Q}#Bi<2>M)Q5w?h-pX&3B}o-V^Xe1FE>yvOC;-k7h!= zO*;)MBB5-lab~Qd13mQGXNsPPug^3BcGU3oMI!-QDP9h4f1iGO!takqY*Hld_fM!# zja_cu6gQqt*!JYfplt_FPTDpLm(+<bcf0j*OnF$a?=E;);mxdgSj8dy>|qV<;-H6h zbcts?Y*3z-U93Gq|1wMq3;zBJ9#$Cl0}rc+;i`u<+T8cBjzMwA!v=cAG~y_uf@M_c zCx<-hurPu&j&Kiif`oCL=nS<bWQb<@U30Bwut;g0JmTfba<!1l*R7HC5i1-DAGhR> z*qY7M>ekF+p-!8#o{KpK$smO#2E|!g&2b1W5x+)pjy{W2R>@{^i^UYdUhEj-Kg^BA zYAu}L+zuhi@14BiCK0ptqF6EO#AqlwDpULyDV=6YRhC=eC6yQ=#LrQVH@Sy^)0t|m zP%c@a(9y9_h=PYDx35NTN;p|$WuyFqOiBd%QNu9*hdz`Xr<3A#ft*8q7<4(o-WKju Sk{*S(xVab`+K9ya=KSB#KL!i{
literal 0 HcmV?d00001
From: Paul Gofman pgofman@codeweavers.com
--- dlls/gdi32/tests/font.c | 2 +- dlls/win32u/freetype.c | 15 ++------------- 2 files changed, 3 insertions(+), 14 deletions(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 198fba2d847..1212e88fdfa 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -7776,7 +7776,7 @@ static INT CALLBACK test_font_weight_enum(const LOGFONTW *lf, const TEXTMETRICW if (type != TRUETYPE_FONTTYPE) return 1; ok(!wcscmp(lf->lfFaceName, L"wine_heavy"), "got %s.\n", debugstr_w(lf->lfFaceName)); ok((ntm->ntmFlags & (NTM_REGULAR | NTM_BOLD)) == NTM_REGULAR, "got %#lx.\n", ntm->ntmFlags); - todo_wine ok(ntm->tmWeight == 700, "got %ld.\n", ntm->tmWeight); + ok(ntm->tmWeight == 700, "got %ld.\n", ntm->tmWeight); *called = 1;
return 1; diff --git a/dlls/win32u/freetype.c b/dlls/win32u/freetype.c index 3e640115ab7..2c4d2c446df 100644 --- a/dlls/win32u/freetype.c +++ b/dlls/win32u/freetype.c @@ -3751,19 +3751,8 @@ static BOOL freetype_set_outline_text_metrics( struct gdi_font *font ) TM.tmAveCharWidth = 1; } TM.tmMaxCharWidth = SCALE_X(ft_face->bbox.xMax - ft_face->bbox.xMin); - TM.tmWeight = FW_REGULAR; - if (font->fake_bold) - TM.tmWeight = FW_BOLD; - else - { - if (ft_face->style_flags & FT_STYLE_FLAG_BOLD) - { - if (pOS2->usWeightClass > FW_MEDIUM) - TM.tmWeight = pOS2->usWeightClass; - } - else if (pOS2->usWeightClass <= FW_MEDIUM) - TM.tmWeight = pOS2->usWeightClass; - } + TM.tmWeight = font->fake_bold ? FW_BOLD : pOS2->usWeightClass; + TM.tmOverhang = 0; TM.tmDigitizedAspectX = 96; /* FIXME */ TM.tmDigitizedAspectY = 96; /* FIXME */
From: Paul Gofman pgofman@codeweavers.com
--- dlls/gdi32/tests/font.c | 2 +- dlls/win32u/font.c | 18 +++++++++++------- dlls/win32u/freetype.c | 12 +++++++++--- dlls/win32u/ntgdi_private.h | 4 ++-- dlls/win32u/opentype.c | 3 ++- 5 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 1212e88fdfa..06d3b042deb 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -7827,7 +7827,7 @@ static void test_font_weight(void) SelectObject(hdc, hfont2); memset(&tm2, 0, sizeof(tm2)); GetTextMetricsW(hdc, &tm2); - todo_wine ok(tm1.tmMaxCharWidth == tm2.tmMaxCharWidth, "got %ld, %ld.\n", tm1.tmMaxCharWidth, tm2.tmMaxCharWidth); + ok(tm1.tmMaxCharWidth == tm2.tmMaxCharWidth, "got %ld, %ld.\n", tm1.tmMaxCharWidth, tm2.tmMaxCharWidth);
SelectObject(hdc, old); ReleaseDC(NULL, hdc); diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 8fb3128f5e0..c8ab5e4f625 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -85,6 +85,7 @@ struct gdi_font_face UINT face_index; FONTSIGNATURE fs; UINT ntmFlags; + UINT weight; UINT version; UINT flags; /* ADDFONT flags */ BOOL scalable; @@ -1165,7 +1166,7 @@ static BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_f static struct gdi_font_face *create_face( struct gdi_font_family *family, const WCHAR *style, const WCHAR *fullname, const WCHAR *file, void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs, - DWORD ntmflags, DWORD version, DWORD flags, + DWORD ntmflags, DWORD weight, DWORD version, DWORD flags, const struct bitmap_font_size *size ) { struct gdi_font_face *face = calloc( 1, sizeof(*face) ); @@ -1176,6 +1177,7 @@ static struct gdi_font_face *create_face( struct gdi_font_family *family, const face->face_index = index; face->fs = fs; face->ntmFlags = ntmflags; + face->weight = weight; face->version = version; face->flags = flags; face->data_ptr = data_ptr; @@ -1191,7 +1193,7 @@ static struct gdi_font_face *create_face( struct gdi_font_family *family, const int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, const WCHAR *style, const WCHAR *fullname, const WCHAR *file, void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs, - DWORD ntmflags, DWORD version, DWORD flags, + DWORD ntmflags, DWORD weight, DWORD version, DWORD flags, const struct bitmap_font_size *size ) { struct gdi_font_face *face; @@ -1202,7 +1204,7 @@ int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, else if (!(family = create_family( family_name, second_name ))) return ret;
if ((face = create_face( family, style, fullname, file, data_ptr, data_size, - index, fs, ntmflags, version, flags, size ))) + index, fs, ntmflags, weight, version, flags, size ))) { if (flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face ); release_face( face ); @@ -1235,7 +1237,7 @@ int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, else if (!(family = create_family( vert_family, vert_second ))) return ret;
if ((face = create_face( family, style, fullname, file, data_ptr, data_size, - index, fs, ntmflags, version, flags | ADDFONT_VERTICAL_FONT, size ))) + index, fs, ntmflags, weight, version, flags | ADDFONT_VERTICAL_FONT, size ))) { if (flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face ); release_face( face ); @@ -1253,6 +1255,7 @@ struct cached_face DWORD index; DWORD flags; DWORD ntmflags; + DWORD weight; DWORD version; struct bitmap_font_size size; FONTSIGNATURE fs; @@ -1280,8 +1283,8 @@ static void load_face_from_cache( HKEY hkey_family, struct gdi_font_family *fami ((DWORD *)cached)[info->DataLength / sizeof(DWORD)] = 0; if ((face = create_face( family, name, cached->full_name, cached->full_name + lstrlenW(cached->full_name) + 1, - NULL, 0, cached->index, cached->fs, cached->ntmflags, cached->version, - cached->flags, scalable ? NULL : &cached->size ))) + NULL, 0, cached->index, cached->fs, cached->ntmflags, cached->weight, + cached->version, cached->flags, scalable ? NULL : &cached->size ))) { if (!scalable) TRACE("Adding bitmap size h %d w %d size %d x_ppem %d y_ppem %d\n", @@ -1372,6 +1375,7 @@ static void add_face_to_cache( struct gdi_font_face *face ) cached->index = face->face_index; cached->flags = face->flags; cached->ntmflags = face->ntmFlags; + cached->weight = face->weight; cached->version = face->version; cached->fs = face->fs; if (!face->scalable) cached->size = face->size; @@ -2444,7 +2448,7 @@ static struct gdi_font *create_gdi_font( const struct gdi_font_face *face, const font->fs = face->fs; font->lf = *lf; font->fake_italic = (lf->lfItalic && !(face->ntmFlags & NTM_ITALIC)); - font->fake_bold = (lf->lfWeight > 550 && !(face->ntmFlags & NTM_BOLD)); + font->fake_bold = lf->lfWeight > 550 && !(face->ntmFlags & NTM_BOLD) && face->weight < 550; font->scalable = face->scalable; font->face_index = face->face_index; font->ntmFlags = face->ntmFlags; diff --git a/dlls/win32u/freetype.c b/dlls/win32u/freetype.c index 2c4d2c446df..1c82fc9b602 100644 --- a/dlls/win32u/freetype.c +++ b/dlls/win32u/freetype.c @@ -1163,6 +1163,7 @@ struct unix_face WCHAR *style_name; WCHAR *full_name; DWORD ntm_flags; + UINT weight; DWORD font_version; FONTSIGNATURE fs; struct bitmap_font_size size; @@ -1202,7 +1203,7 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ) && opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ) && opentype_get_properties( data_ptr, data_size, ttc_sfnt_v1, &This->font_version, - &This->fs, &This->ntm_flags )) + &This->fs, &This->ntm_flags, &This->weight )) { struct family_names_data family_names; struct face_name_data style_name; @@ -1246,6 +1247,8 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr } else if ((This->ft_face = new_ft_face( unix_name, data_ptr, data_size, face_index, flags & ADDFONT_ALLOW_BITMAP ))) { + TT_OS2 *os2; + WARN( "unable to parse font, falling back to FreeType\n" ); This->scalable = FT_IS_SCALABLE( This->ft_face ); This->num_faces = This->ft_face->num_faces; @@ -1267,8 +1270,11 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
This->style_name = ft_face_get_style_name( This->ft_face, system_lcid ); This->full_name = ft_face_get_full_name( This->ft_face, system_lcid ); - This->ntm_flags = get_ntm_flags( This->ft_face ); + if ((os2 = pFT_Get_Sfnt_Table(This->ft_face, ft_sfnt_os2))) + This->weight = os2->usWeightClass; + else + This->weight = This->ntm_flags & NTM_BOLD ? FW_BOLD : FW_NORMAL; This->font_version = get_font_version( This->ft_face ); if (!This->scalable) get_bitmap_size( This->ft_face, &This->size ); get_fontsig( This->ft_face, &This->fs ); @@ -1315,7 +1321,7 @@ static int add_unix_face( const char *unix_name, const WCHAR *file, void *data_p if (!HIWORD( flags )) flags |= ADDFONT_AA_FLAGS( default_aa_flags );
ret = add_gdi_face( unix_face->family_name, unix_face->second_name, unix_face->style_name, unix_face->full_name, - file, data_ptr, data_size, face_index, unix_face->fs, unix_face->ntm_flags, + file, data_ptr, data_size, face_index, unix_face->fs, unix_face->ntm_flags, unix_face->weight, unix_face->font_version, flags, unix_face->scalable ? NULL : &unix_face->size );
TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n", diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 5c4f8279c87..5e260d8713d 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -339,7 +339,7 @@ struct font_backend_funcs extern int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, const WCHAR *style, const WCHAR *fullname, const WCHAR *file, void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs, - DWORD ntmflags, DWORD version, DWORD flags, + DWORD ntmflags, DWORD weight, DWORD version, DWORD flags, const struct bitmap_font_size *size ); extern UINT font_init(void); extern const struct font_backend_funcs *init_freetype_lib(void); @@ -370,7 +370,7 @@ extern BOOL opentype_enum_full_names( const struct tt_name_v0 *tt_name_v0, opentype_enum_names_cb callback, void *user );
extern BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1, - DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags ); + DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags, UINT *weight );
/* gdiobj.c */ extern HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, diff --git a/dlls/win32u/opentype.c b/dlls/win32u/opentype.c index 7a541ae4e4a..97c8b9dbbce 100644 --- a/dlls/win32u/opentype.c +++ b/dlls/win32u/opentype.c @@ -724,7 +724,7 @@ BOOL opentype_enum_full_names( const struct tt_name_v0 *header, opentype_enum_na }
BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1, - DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags ) + DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags, UINT *weight ) { const struct tt_os2_v1 *tt_os2_v1; const struct tt_head *tt_head; @@ -762,6 +762,7 @@ BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sf if (selection & OS2_FSSELECTION_BOLD) flags |= NTM_BOLD; if (selection & OS2_FSSELECTION_REGULAR) flags |= NTM_REGULAR; if (flags == 0) flags = NTM_REGULAR; + *weight = GET_BE_WORD( tt_os2_v1->usWeightClass );
if (opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_CFF__TAG, &cff_header, &table_size )) flags |= NTM_PS_OPENTYPE;
Fixes font rendering in Insanely Twisted Shadow Planet.
Looks like on Windows the actual extent of synthesized emboldening depends on the ratio of the requested weight and the weight specified in font. This patchset doesn't alter emboldening algorithm but improves the current way of detecting whether emboldening is required. The dynamic extent of emboldening will need the font weight properly retrieved and stored anyway (which is done in these patches).
Does it mean that on Windows it's rendered bolder if you ask for lfWeight bolder than FW_BOLD? For example if you create "Tahoma Bold", with lfWeight of 2*FW_BOLD.
I can tell that for directwrite it's not the case, and simulated bold only exists when there is no detected bold in the family. There it's not about a degree of how bold it is.
This is probably more complicated with Tahoma because it has different versions including bold, properly flagged as bold with weight 700. Windows probably doesn't embolden fonts properly flagged as bold, as far as my interactive test goes. However, the degree of emboldenment does depend on the original font weight and requested font weight when synthetic emboldenment is performed. I am attaching an interactive test program I used for testing the appearence with various fonts. With the wine_heavy.ttf added to tests with this MR dropped into the run directory (as well as with the font from the game) it clearly shows how the text with higher requested weight is bolder than FW_BOLD (700) (look at first 'A' character displayed as | from test font, the rest is substituted from some other font on Windows).
[ttf2.c](/uploads/8d9ef1340da25f4fbec0f2755c20874d/ttf2.c)
I. e., as far as I can tell, bold flagged as bold won't be synthetically emboldened at all (like with Wine), but for fonts flagged as regular the degree of boldening depends on the ration of requested to font weight.
This merge request was approved by Huw Davies.