This shows that although Windows is only matching family names up to LF_FACESIZE chars, and that it doesn't match against the preferred / typographic family names and styles, it still keeps the faces separate when the full names don't match. Wine incorrectly discard one of them.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This "bug fix" is mostly an excuse to begin cleaning up the code. I'm planning on refactoring things a bit to improve process startup time.
dlls/gdi32/tests/font.c | 71 ++++++++++++++++++++ dlls/gdi32/tests/resource.rc | 6 ++ dlls/gdi32/tests/wine_ttfnames.sfd | 85 ++++++++++++++++++++++++ dlls/gdi32/tests/wine_ttfnames.ttf | Bin 0 -> 2232 bytes dlls/gdi32/tests/wine_ttfnames_bold.sfd | 85 ++++++++++++++++++++++++ dlls/gdi32/tests/wine_ttfnames_bold.ttf | Bin 0 -> 2272 bytes 6 files changed, 247 insertions(+) create mode 100644 dlls/gdi32/tests/wine_ttfnames.sfd create mode 100644 dlls/gdi32/tests/wine_ttfnames.ttf create mode 100644 dlls/gdi32/tests/wine_ttfnames_bold.sfd create mode 100644 dlls/gdi32/tests/wine_ttfnames_bold.ttf
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index ad894dfdcad..b1848a43743 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -6940,6 +6940,76 @@ static void test_long_names(void) ReleaseDC(NULL, dc); }
+static void test_ttf_names(void) +{ + struct enum_fullname_data efnd; + char ttf_name[MAX_PATH], ttf_name_bold[MAX_PATH]; + LOGFONTA font = {0}; + HFONT handle_font; + int ret; + HDC dc; + + if (!write_ttf_file("wine_ttfnames.ttf", ttf_name)) + { + skip("Failed to create ttf file for testing\n"); + return; + } + + if (!write_ttf_file("wine_ttfnames_bold.ttf", ttf_name_bold)) + { + skip("Failed to create ttf file for testing\n"); + DeleteFileA(ttf_name); + return; + } + + ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "AddFontResourceEx() failed\n"); + + ret = AddFontResourceExA(ttf_name_bold, FR_PRIVATE, 0); + ok(ret, "AddFontResourceEx() failed\n"); + + dc = GetDC(NULL); + + strcpy(font.lfFaceName, "Wine_TTF_Names_Long_Family1_Con"); + memset(&efnd, 0, sizeof(efnd)); + EnumFontFamiliesExA(dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0); + ok(efnd.total == 0, "EnumFontFamiliesExA must not find font.\n"); + + /* Windows doesn't match with Typographic/Preferred Family tags */ + strcpy(font.lfFaceName, "Wine TTF Names Long Family1"); + memset(&efnd, 0, sizeof(efnd)); + EnumFontFamiliesExA(dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0); + ok(efnd.total == 0, "EnumFontFamiliesExA must not find font.\n"); + + strcpy(font.lfFaceName, "Wine TTF Names Long Family1 Ext"); + memset(&efnd, 0, sizeof(efnd)); + EnumFontFamiliesExA(dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0); + todo_wine + ok(efnd.total == 2, "EnumFontFamiliesExA found %d fonts, expected 2.\n", efnd.total); + + strcpy(font.lfFaceName, "Wine TTF Names Long Family1 Con"); + memset(&efnd, 0, sizeof(efnd)); + EnumFontFamiliesExA(dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0); + todo_wine + ok(efnd.total == 2, "EnumFontFamiliesExA found %d fonts, expected 2.\n", efnd.total); + + handle_font = CreateFontIndirectA(&font); + ok(handle_font != NULL, "CreateFontIndirectA failed\n"); + DeleteObject(handle_font); + + ret = RemoveFontResourceExA(ttf_name_bold, FR_PRIVATE, 0); + todo_wine + ok(ret, "RemoveFontResourceEx() failed\n"); + + DeleteFileA(ttf_name_bold); + + ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "RemoveFontResourceEx() failed\n"); + + DeleteFileA(ttf_name); + ReleaseDC(NULL, dc); +} + typedef struct { USHORT majorVersion; @@ -7351,6 +7421,7 @@ START_TEST(font) test_bitmap_font_glyph_index(); test_GetCharWidthI(); test_long_names(); + test_ttf_names(); test_char_width();
/* These tests should be last test until RemoveFontResource diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc index 6dcbd42ab52..b5a6107a987 100644 --- a/dlls/gdi32/tests/resource.rc +++ b/dlls/gdi32/tests/resource.rc @@ -31,3 +31,9 @@ vertical.ttf RCDATA vertical.ttf
/* @makedep: wine_longname.ttf */ wine_longname.ttf RCDATA wine_longname.ttf + +/* @makedep: wine_ttfnames.ttf */ +wine_ttfnames.ttf RCDATA wine_ttfnames.ttf + +/* @makedep: wine_ttfnames_bold.ttf */ +wine_ttfnames_bold.ttf RCDATA wine_ttfnames_bold.ttf diff --git a/dlls/gdi32/tests/wine_ttfnames.sfd b/dlls/gdi32/tests/wine_ttfnames.sfd new file mode 100644 index 00000000000..566749d19a7 --- /dev/null +++ b/dlls/gdi32/tests/wine_ttfnames.sfd @@ -0,0 +1,85 @@ +SplineFontDB: 3.2 +FontName: Wine_TTF_Names_Long_Family1_Cond_Regular +FamilyName: Wine_TTF_Names_Long_Family1_Cond +Weight: Regular +Copyright: Copyright (c) 2020, Remi Bernon for CodeWeavers +UComments: "2017-11-17: Created with FontForge (http://fontforge.org)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -102 +UnderlineWidth: 51 +Ascent: 819 +Descent: 205 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "Back" 1 +Layer: 1 0 "Fore" 0 +XUID: [1021 48 28337276 3092883] +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1510948643 +ModificationTime: 1598865292 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 0 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +LangName: 1033 \ + "" \ + "Wine TTF Names Long Family1 Cond" \ + "Regular" \ + "" \ + "Wine TTF Names Long Family1 Extremely Long Full Name Condensed" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "Wine TTF Names Long Family1" \ + "Condensed Regular" \ + +Encoding: ISO8859-1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 64 16 4 +BeginPrivate: 0 +EndPrivate +BeginChars: 256 1 + +StartChar: at +Encoding: 64 64 0 +Width: 1024 +VWidth: 0 +Flags: HW +LayerCount: 2 +Fore +SplineSet +259 332 m 29 + 468 664 l 29 + 514 332 l 29 + 259 332 l 29 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/dlls/gdi32/tests/wine_ttfnames.ttf b/dlls/gdi32/tests/wine_ttfnames.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2eb2ad1f95e7bb384abe41bcf68f64da320fefb9 GIT binary patch literal 2232 zcmdT`O>7%Q6#iy+?W8oKb_J*AFt|aaC_ft;MWu?6mDHvOQ>qXpJyhK+$@)jKcdfM( zVhN-kdqAQW1eFk%-YVsgs22{1142S57eGR&px#j_Js>zi%{SwT?exH(xG>i2eDBSB zZ{FX|8UnzRxCR^R#p22<Z-00-0!BX|cl_n^g(9BDQ>3pc`qkHFv#SaJ4M0>$uWvN` zCQc;plm3=-abvqJk+H4=_Bi*Qir;E>yR?ka9nzzfdZ+x^-oDHIDbmeq;BTJ%;nphg zkDT*WG7`s}1Z_=_o~Sn3J7W;flKz}@svd3lcpWR$m!zL)_&ZHpz>D0!Kw5@=BY3zw z(d9n<cXpdmtKGeac^+Nj{_{|=a(=ygx$B)+_yxxuGJtPhcz8>#-^I-_WB|*uZj&5^ zrMMi_(VQzidCSt4dV9U6qd87rM`;Sp%VS21I25@7#%A5L4#;_@w~G77iDTp<!KWF@ z&;GbnE^M+sdF1U}H-{_Q6YW!9L_*Lrdd{fz6wJBGyPo65+XYg}@;HSgSBF1E=UF5D z?0#w_A(Ddwgo;JY;c>*n;f(=S$N$fV?q&9k`kiGgmddfnvH~_nFtaBxyRbjv;6ZjT znfQKT-?j*`XDfC>vG+%k;<tr;rtm>FmwqPwTrPb&BT_#d99Xx1U(Hx$niIAtvE$xX zIToi#emNsbqV(vFO5RD_JFE$2v2L(n{k}5T!U(I~tA~yA;$4FsykuQAIDwS)k-<q! z^6l)&r*O)C%iuK9_Q$G29My+cIeS<jj~fPCyeWP**v55n++YW9in|6UAg%WdPU4dF zg~2Jz+XaKu$k;crga}P^5Tk|)s%SH+No?Q@*DPE;r-+vkpg|dlMWPrX^+Hl*t}$0- zXOlZ?oIbX-Obb|wnw_{-skY_h#u=G)v+k5!4jMJN7{p-|%5oITrD!u)3;gXMrotM} z2&pZ3!>pjl^&;&x$Y~Lm^r;o1qUP36r|)y5)%hVkz*;Q~<jP7>UgSm8lBFoD$fDn< z)jM-MDWrr7rGhQ0`g9%3L1nA%6BM<Hwq9dOC?~SKI9#shI1gR(jBDPIYhK?q?=jcB zzH8oNC-<!8=>9Ytd%B-)6r-?RjN(clvoo$dCsjxuL-KS;o(jn`A$ck!&xAnH+}!lp zX_e-GpUDDt*ab1eS6Ns2J(_owxH@@<bs6M7U<F##`HLzPcG_{!2<jbEoUM9Y7fY8X z2wMU5S7|1uv6`-lWDQ*AN!3FABn8+lH8zmz&ds>4OU{2?9^FZQC+&ly|5?-iS*!BR zF%3OPYVRc+>ReTOoiDypriXcBn6E_l4sxUf=h5Mi6qGux*@EAl!IyN5|1;FSvY|A4 Q+WL9-*GHcyjp6U~A6<%D%m4rY
literal 0 HcmV?d00001
diff --git a/dlls/gdi32/tests/wine_ttfnames_bold.sfd b/dlls/gdi32/tests/wine_ttfnames_bold.sfd new file mode 100644 index 00000000000..b3bf4ddfe90 --- /dev/null +++ b/dlls/gdi32/tests/wine_ttfnames_bold.sfd @@ -0,0 +1,85 @@ +SplineFontDB: 3.2 +FontName: Wine_TTF_Names_Long_Family1_Cond_Regular +FamilyName: Wine_TTF_Names_Long_Family1_Cond +Weight: Regular +Copyright: Copyright (c) 2020, Remi Bernon for CodeWeavers +UComments: "2017-11-17: Created with FontForge (http://fontforge.org)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -102 +UnderlineWidth: 51 +Ascent: 819 +Descent: 205 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "Back" 1 +Layer: 1 0 "Fore" 0 +XUID: [1021 48 28337276 3092883] +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1510948643 +ModificationTime: 1598865292 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 0 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +LangName: 1033 \ + "" \ + "Wine TTF Names Long Family1 CondBold" \ + "Regular" \ + "" \ + "Wine TTF Names Long Family1 Extremely Long Full Name Condensed Bold" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "" \ + "Wine TTF Names Long Family1" \ + "Condensed Bold Regular" \ + +Encoding: ISO8859-1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 64 16 4 +BeginPrivate: 0 +EndPrivate +BeginChars: 256 1 + +StartChar: at +Encoding: 64 64 0 +Width: 1024 +VWidth: 0 +Flags: HW +LayerCount: 2 +Fore +SplineSet +259 332 m 29 + 468 664 l 29 + 514 332 l 29 + 259 332 l 29 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/dlls/gdi32/tests/wine_ttfnames_bold.ttf b/dlls/gdi32/tests/wine_ttfnames_bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..919a5ea1310dd95904d882afb56b95aaf94dc9be GIT binary patch literal 2272 zcmdT`O>7%Q6#iy+?W7Qqq~hn$9ELQA6eZ5aMxj(bL`h?M2yGRj<WhCB#2eevde>Sz zA-)v}p&pRvjUpj_)C<ZjR_+`Ci9;?(2v9*iAc0i1g%g~h=9}@vPAY^7;=)+7?|X0F zn|Xh`V+a6`;R<Z56$;BQzxDp*80i0u(vg?WE)?(t9w+~?;xD{1m0d~suK}V=er>(# z*D#pAL;hRNx%I7v#He)@ut&J=l>B<F-R92d|B!rtDQs?hzT0xSK0&@#4*cTr+c#E- z?{dzRDM%f2Qrv5d{8+i#*dBm*hWr=ghr)Q>$E#STy(Irg)!(k+9A4!5Ir1{{tHC>& z*AuS4$K$`L#q~z}7G`*KgX_;h#mf1{&IcE~!Thgy)S&?Q`uSgODEeJe8^9=FS=J8O zeppJ%K^rZ()X}#ry;Enc^K`Vt>Dnkup=GnkXcdPl*TC4UcddO&-tJIw2RU(!Ql$7a zL;2Yq7dIA)xPn>C+PQWPm$WC^r>=^Gpl9@)QR^v~bCq{JM~t_5a%$%hDoIj@KgG|o zM*7+Q)M!Gadj|*=i<*bW5f2Y9^sqYqe?D|Cvv1VzG-I(;jzyLgu+fLiuE12j)#u<| zb~l~+KHst}LhRZ~oKoUeUt0X0Z!v}Uvbo`>ho8+2pBxoKKkx5bJAbT<S{vL>*kX|# zcU|RJoFMyUMl6cO`+F*R$8qbRCYZvS!2)BrX|RPpF=()jv*IIz9n4#i!6^(`Um2Xn zxc!2`LpWhyH+UFN+CQicaa12(=Img>H|(0h7QYngeO5X)u8OA&cJQY7$>0>E)iOAZ zi`I_@4`Ie$Gk6#i_8#UDqlP9DR8T@04R+-?)^Un73s=tx;w1#AQb%HrC_zNKh};Hg zLaO#Da%Gj%$ClQq1M_jMnN&*Uh8$l%C9`hUosdgGwIb(&B#I-s5hrp!E(WWCzZE1j zSmhZJttG!O%P5eZ=YCa6>cors)DlraODhQJ`!soVenb!ENJCPrR-!;IFBjx_evs;N zF^)>I;8!bQbDAec#kn}7mI|wcO`7-&14}_^GxP}xdb@_E2{n{MS$;%Z(leX~ZhFQ| z?~t2b*G=yMH@&W#-UBChcFi%ANjCXpH}xpQQKJwir9fsgt~?`ESRTXjbXcAW%QInl zDlE^0K-Jvz<mpM3@_(Pz1#Gh;5{9oTpmKe*1}bqOWd}9t)gfRt>a;0x^`UCAu-!<4 zY7jO}sW!t<mrfTei0VO6c1pIwT@&tI(It{BiOaO9(x{&VR@g`t_Ll2TXI$5%<iD<# zZmx%^LhtB**3W;}y?m)mum4q!J8$ZtmR3#COCMi8)8PlVNqY}DerE*d(V;FeL9LTo gEO<ZlZrlO>A5rV-MpBj?YyG_W+x<_J#o_z>Pvq`pzyJUM
literal 0 HcmV?d00001
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/gdi32/freetype.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 38d59e3fd9b..2f04b76ef44 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1482,6 +1482,26 @@ static WCHAR *get_face_name(FT_Face ft_face, FT_UShort name_id, LANGID language_ return NULL; }
+static WCHAR *ft_face_get_family_name( FT_Face ft_face, LANGID langid ) +{ + WCHAR *family_name; + + if ((family_name = get_face_name( ft_face, TT_NAME_ID_FONT_FAMILY, langid ))) + return family_name; + + return towstr( CP_ACP, ft_face->family_name ); +} + +static WCHAR *ft_face_get_style_name( FT_Face ft_face, LANGID langid ) +{ + WCHAR *style_name; + + if ((style_name = get_face_name( ft_face, TT_NAME_ID_FONT_SUBFAMILY, langid ))) + return style_name; + + return towstr( CP_ACP, ft_face->style_name ); +} + static inline BOOL faces_equal( const Face *f1, const Face *f2 ) { if (strcmpiW( f1->StyleName, f2->StyleName )) return FALSE; @@ -1907,16 +1927,10 @@ static WCHAR *prepend_at(WCHAR *family)
static void get_family_names( FT_Face ft_face, WCHAR **name, WCHAR **english, BOOL vertical ) { - *english = get_face_name( ft_face, TT_NAME_ID_FONT_FAMILY, MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT) ); - if (!*english) *english = towstr( CP_ACP, ft_face->family_name ); + *english = ft_face_get_family_name( ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) ); + *name = ft_face_get_family_name( ft_face, GetSystemDefaultLCID() );
- *name = get_face_name( ft_face, TT_NAME_ID_FONT_FAMILY, GetSystemDefaultLCID() ); - if (!*name) - { - *name = *english; - *english = NULL; - } - else if (!strcmpiW( *name, *english )) + if (!strcmpiW( *name, *english )) { HeapFree( GetProcessHeap(), 0, *english ); *english = NULL; @@ -2088,9 +2102,7 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file, Face *face = HeapAlloc( GetProcessHeap(), 0, sizeof(*face) );
face->refcount = 1; - face->StyleName = get_face_name( ft_face, TT_NAME_ID_FONT_SUBFAMILY, GetSystemDefaultLangID() ); - if (!face->StyleName) face->StyleName = towstr( CP_ACP, ft_face->style_name ); - + face->StyleName = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() ); face->FullName = get_face_name( ft_face, TT_NAME_ID_FULL_NAME, GetSystemDefaultLangID() ); if (flags & ADDFONT_VERTICAL_FONT) face->FullName = prepend_at( face->FullName ); @@ -7955,12 +7967,7 @@ static BOOL get_outline_text_metrics(GdiFont *font) lenfam = (strlenW(font->name) + 1) * sizeof(WCHAR); family_nameW = strdupW(font->name);
- style_nameW = get_face_name( ft_face, TT_NAME_ID_FONT_SUBFAMILY, GetSystemDefaultLangID() ); - if (!style_nameW) - { - FIXME("failed to read style_nameW for font %s!\n", wine_dbgstr_w(font->name)); - style_nameW = towstr( CP_ACP, ft_face->style_name ); - } + style_nameW = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() ); lensty = (strlenW(style_nameW) + 1) * sizeof(WCHAR);
face_nameW = get_face_name( ft_face, TT_NAME_ID_FULL_NAME, GetSystemDefaultLangID() );
And only prepend @ if it's not already prepended.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/gdi32/freetype.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 2f04b76ef44..ed4dc9f034e 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1911,18 +1911,17 @@ static void remove_face_from_cache( Face *face ) RegCloseKey(hkey_family); }
-static WCHAR *prepend_at(WCHAR *family) +static WCHAR *get_vertical_name( WCHAR *name ) { - WCHAR *str; + SIZE_T length; + if (!name) return NULL; + if (name[0] == '@') return name;
- if (!family) - return NULL; - - str = HeapAlloc(GetProcessHeap(), 0, sizeof (WCHAR) * (strlenW(family) + 2)); - str[0] = '@'; - strcpyW(str + 1, family); - HeapFree(GetProcessHeap(), 0, family); - return str; + length = strlenW( name ) + 1; + name = HeapReAlloc( GetProcessHeap(), 0, name, (length + 1) * sizeof(WCHAR) ); + memmove( name + 1, name, length * sizeof(WCHAR) ); + name[0] = '@'; + return name; }
static void get_family_names( FT_Face ft_face, WCHAR **name, WCHAR **english, BOOL vertical ) @@ -1938,8 +1937,8 @@ static void get_family_names( FT_Face ft_face, WCHAR **name, WCHAR **english, BO
if (vertical) { - *name = prepend_at( *name ); - *english = prepend_at( *english ); + *name = get_vertical_name( *name ); + *english = get_vertical_name( *english ); } }
@@ -2104,8 +2103,7 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file, face->refcount = 1; face->StyleName = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() ); face->FullName = get_face_name( ft_face, TT_NAME_ID_FULL_NAME, GetSystemDefaultLangID() ); - if (flags & ADDFONT_VERTICAL_FONT) - face->FullName = prepend_at( face->FullName ); + if (flags & ADDFONT_VERTICAL_FONT) face->FullName = get_vertical_name( face->FullName );
face->dev = 0; face->ino = 0; @@ -2383,10 +2381,10 @@ static BOOL map_vertical_font_family(const WCHAR *orig, const WCHAR *repl, const if (!face || !(face->fs.fsCsb[0] & FS_DBCS_MASK)) return FALSE;
- at_orig = prepend_at(strdupW(orig)); + at_orig = get_vertical_name( strdupW( orig ) ); if (at_orig && !find_family_from_any_name(at_orig)) { - at_repl = prepend_at(strdupW(repl)); + at_repl = get_vertical_name( strdupW( repl ) ); if (at_repl) ret = map_font_family(at_orig, at_repl); } @@ -7976,7 +7974,7 @@ static BOOL get_outline_text_metrics(GdiFont *font) FIXME("failed to read face_nameW for font %s!\n", wine_dbgstr_w(font->name)); face_nameW = strdupW(font->name); } - if (font->name[0] == '@') face_nameW = prepend_at( face_nameW ); + if (font->name[0] == '@') face_nameW = get_vertical_name( face_nameW ); lenface = (strlenW(face_nameW) + 1) * sizeof(WCHAR);
full_nameW = get_face_name( ft_face, TT_NAME_ID_UNIQUE_ID, GetSystemDefaultLangID() );
And rename the field to full_name for consistency with most face fields.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/gdi32/freetype.c | 81 ++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 36 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index ed4dc9f034e..fad7143dd58 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -270,7 +270,7 @@ typedef struct tagFace { struct list entry; unsigned int refcount; WCHAR *StyleName; - WCHAR *FullName; + WCHAR *full_name; WCHAR *file; dev_t dev; ino_t ino; @@ -1502,6 +1502,29 @@ static WCHAR *ft_face_get_style_name( FT_Face ft_face, LANGID langid ) return towstr( CP_ACP, ft_face->style_name ); }
+static WCHAR *ft_face_get_full_name( FT_Face ft_face, LANGID langid ) +{ + static const WCHAR space_w[] = {' ',0}; + WCHAR *full_name, *style_name; + SIZE_T length; + + if ((full_name = get_face_name( ft_face, TT_NAME_ID_FULL_NAME, langid ))) + return full_name; + + full_name = ft_face_get_family_name( ft_face, langid ); + style_name = ft_face_get_style_name( ft_face, langid ); + + length = strlenW( full_name ) + strlenW( style_name ) + 1; + full_name = HeapReAlloc( GetProcessHeap(), 0, full_name, length * sizeof(WCHAR) ); + + strcatW( full_name, space_w ); + strcatW( full_name, style_name ); + HeapFree( GetProcessHeap(), 0, style_name ); + + WARN( "full name not found, using %s instead\n", debugstr_w(full_name) ); + return full_name; +} + static inline BOOL faces_equal( const Face *f1, const Face *f2 ) { if (strcmpiW( f1->StyleName, f2->StyleName )) return FALSE; @@ -1531,7 +1554,7 @@ static void release_face( Face *face ) } HeapFree( GetProcessHeap(), 0, face->file ); HeapFree( GetProcessHeap(), 0, face->StyleName ); - HeapFree( GetProcessHeap(), 0, face->FullName ); + HeapFree( GetProcessHeap(), 0, face->full_name ); HeapFree( GetProcessHeap(), 0, face->cached_enum_data ); HeapFree( GetProcessHeap(), 0, face ); } @@ -1677,10 +1700,14 @@ static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family, void *bu face->StyleName = strdupW(face_name);
needed = buffer_size; - if(RegQueryValueExW(hkey_face, face_full_name_value, NULL, NULL, buffer, &needed) == ERROR_SUCCESS) - face->FullName = strdupW( buffer ); - else - face->FullName = NULL; + if (RegQueryValueExW( hkey_face, face_full_name_value, NULL, NULL, buffer, &needed ) != ERROR_SUCCESS) + { + ERR( "couldn't find full name for %s %s in cache\n", debugstr_w(family->FamilyName), + debugstr_w(face->StyleName) ); + release_face( face ); + return; + } + face->full_name = strdupW( buffer );
reg_load_ftlong(hkey_face, face_index_value, &face->face_index); reg_load_dword(hkey_face, face_ntmflags_value, &face->ntmFlags); @@ -1866,9 +1893,8 @@ static void add_face_to_cache(Face *face)
RegSetValueExW(hkey_face, face_file_name_value, 0, REG_SZ, (BYTE *)face->file, (strlenW(face->file) + 1) * sizeof(WCHAR)); - if (face->FullName) - RegSetValueExW(hkey_face, face_full_name_value, 0, REG_SZ, (BYTE*)face->FullName, - (strlenW(face->FullName) + 1) * sizeof(WCHAR)); + RegSetValueExW( hkey_face, face_full_name_value, 0, REG_SZ, (BYTE *)face->full_name, + (strlenW( face->full_name ) + 1) * sizeof(WCHAR) );
reg_save_dword(hkey_face, face_index_value, face->face_index); reg_save_dword(hkey_face, face_ntmflags_value, face->ntmFlags); @@ -2102,8 +2128,8 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file,
face->refcount = 1; face->StyleName = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() ); - face->FullName = get_face_name( ft_face, TT_NAME_ID_FULL_NAME, GetSystemDefaultLangID() ); - if (flags & ADDFONT_VERTICAL_FONT) face->FullName = get_vertical_name( face->FullName ); + face->full_name = ft_face_get_full_name( ft_face, GetSystemDefaultLangID() ); + if (flags & ADDFONT_VERTICAL_FONT) face->full_name = get_vertical_name( face->full_name );
face->dev = 0; face->ino = 0; @@ -3202,18 +3228,14 @@ static void update_reg_entries(void) LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { LIST_FOR_EACH_ENTRY( face, &family->faces, Face, entry ) { char *buffer; - WCHAR *name; - if (!(face->flags & ADDFONT_EXTERNAL_FONT)) continue;
- name = face->FullName ? face->FullName : family->FamilyName; - - len = strlenW(name) + 1; + len = strlenW( face->full_name ) + 1; if (face->scalable) len += ARRAY_SIZE(TrueType);
valueW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - strcpyW(valueW, name); + strcpyW( valueW, face->full_name );
if (face->scalable) strcatW(valueW, TrueType); @@ -5688,8 +5710,7 @@ static HFONT CDECL freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { face_list = get_face_list_from_family(family); LIST_FOR_EACH_ENTRY( face, face_list, Face, entry ) { - if(face->FullName && !strncmpiW(face->FullName, FaceName, LF_FACESIZE - 1) && - (face->scalable || can_use_bitmap)) + if (!strncmpiW( face->full_name, FaceName, LF_FACESIZE - 1 ) && (face->scalable || can_use_bitmap)) { if (csi.fs.fsCsb[0] & face->fs.fsCsb[0] || !csi.fs.fsCsb[0]) goto found_face; @@ -6182,10 +6203,7 @@ static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEX pntm->ntmTm.ntmAvgWidth = pntm->ntmTm.tmAveCharWidth;
lstrcpynW(pelf->elfLogFont.lfFaceName, family_name, LF_FACESIZE); - if (face->FullName) - lstrcpynW(pelf->elfFullName, face->FullName, LF_FULLFACESIZE); - else - lstrcpynW(pelf->elfFullName, family_name, LF_FULLFACESIZE); + lstrcpynW( pelf->elfFullName, face->full_name, LF_FULLFACESIZE ); lstrcpynW(pelf->elfStyle, face->StyleName, LF_FACESIZE); }
@@ -6236,7 +6254,7 @@ static BOOL family_matches(Family *family, const WCHAR *face_name)
face_list = get_face_list_from_family(family); LIST_FOR_EACH_ENTRY(face, face_list, Face, entry) - if (face->FullName && !strncmpiW(face_name, face->FullName, LF_FACESIZE - 1)) return TRUE; + if (!strncmpiW( face_name, face->full_name, LF_FACESIZE - 1 )) return TRUE;
return FALSE; } @@ -6244,8 +6262,7 @@ static BOOL family_matches(Family *family, const WCHAR *face_name) static BOOL face_matches(const WCHAR *family_name, Face *face, const WCHAR *face_name) { if (!strncmpiW(face_name, family_name, LF_FACESIZE - 1)) return TRUE; - - return (face->FullName && !strncmpiW(face_name, face->FullName, LF_FACESIZE - 1)); + return !strncmpiW( face_name, face->full_name, LF_FACESIZE - 1 ); }
static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_charset_list *list, @@ -6278,10 +6295,7 @@ static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_cha if (family != face->family) { lstrcpynW(elf.elfLogFont.lfFaceName, family->FamilyName, LF_FACESIZE); - if (face->FullName) - lstrcpynW(elf.elfFullName, face->FullName, LF_FULLFACESIZE); - else - lstrcpynW(elf.elfFullName, family->FamilyName, LF_FULLFACESIZE); + lstrcpynW( elf.elfFullName, face->full_name, LF_FULLFACESIZE ); } if (subst) strcpyW(elf.elfLogFont.lfFaceName, subst); @@ -7968,12 +7982,7 @@ static BOOL get_outline_text_metrics(GdiFont *font) style_nameW = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() ); lensty = (strlenW(style_nameW) + 1) * sizeof(WCHAR);
- face_nameW = get_face_name( ft_face, TT_NAME_ID_FULL_NAME, GetSystemDefaultLangID() ); - if (!face_nameW) - { - FIXME("failed to read face_nameW for font %s!\n", wine_dbgstr_w(font->name)); - face_nameW = strdupW(font->name); - } + face_nameW = ft_face_get_full_name( ft_face, GetSystemDefaultLangID() ); if (font->name[0] == '@') face_nameW = get_vertical_name( face_nameW ); lenface = (strlenW(face_nameW) + 1) * sizeof(WCHAR);
The gdi32 family not always matches the real font family, as we match only LF_FACESIZE chars, so it can make traces confusing.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/gdi32/freetype.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index fad7143dd58..f9b989d9e90 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1572,10 +1572,7 @@ static inline int style_order(const Face *face) case NTM_BOLD | NTM_ITALIC: return 3; default: - WARN("Don't know how to order font %s %s with flags 0x%08x\n", - debugstr_w(face->family->FamilyName), - debugstr_w(face->StyleName), - face->ntmFlags); + WARN( "Don't know how to order face %s with flags 0x%08x\n", debugstr_w(face->full_name), face->ntmFlags ); return 9999; } } @@ -1588,9 +1585,9 @@ static BOOL insert_face_in_family_list( Face *face, Family *family ) { if (faces_equal( face, cursor )) { - TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n", - debugstr_w(family->FamilyName), debugstr_w(face->StyleName), - cursor->font_version, face->font_version); + TRACE( "Already loaded face %s in family %s, original version %lx, new version %lx\n", + debugstr_w(face->full_name), debugstr_w(family->FamilyName), + cursor->font_version, face->font_version );
if (face->file && face->dev == cursor->dev && face->ino == cursor->ino) { @@ -1621,7 +1618,8 @@ static BOOL insert_face_in_family_list( Face *face, Family *family ) if (style_order( face ) < style_order( cursor )) break; }
- TRACE("Adding new %s\n", debugstr_w(face->file)); + TRACE( "Adding face %s in family %s from %s\n", debugstr_w(face->full_name), + debugstr_w(family->FamilyName), debugstr_w(face->file) ); list_add_before( &cursor->entry, &face->entry ); face->family = family; family->refcount++; @@ -1742,7 +1740,7 @@ static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family, void *bu face->fs.fsUsb[2], face->fs.fsUsb[3]);
if (insert_face_in_family_list(face, family)) - TRACE("Added font %s %s\n", debugstr_w(family->FamilyName), debugstr_w(face->StyleName)); + TRACE( "Added face %s to family %s\n", debugstr_w(face->full_name), debugstr_w(family->FamilyName) );
release_face( face ); } @@ -2193,9 +2191,7 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr { if (flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face ); - - TRACE("Added font %s %s\n", debugstr_w(family->FamilyName), - debugstr_w(face->StyleName)); + TRACE( "Added face %s to family %s\n", debugstr_w(face->full_name), debugstr_w(family->FamilyName) ); } release_face( face ); release_family( family ); @@ -2389,7 +2385,8 @@ static void DumpFontList(void) LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { TRACE("Family: %s\n", debugstr_w(family->FamilyName)); LIST_FOR_EACH_ENTRY( face, &family->faces, Face, entry ) { - TRACE("\t%s\t%08x", debugstr_w(face->StyleName), face->fs.fsCsb[0]); + TRACE( "\t%s\t%s\t%08x", debugstr_w(face->StyleName), debugstr_w(face->full_name), + face->fs.fsCsb[0] ); if(!face->scalable) TRACE(" %d", face->size.height); TRACE("\n"); @@ -5906,8 +5903,8 @@ found_face: else ret->charset = get_nearest_charset(family->FamilyName, face, &ret->codepage);
- TRACE("Chosen: %s %s (%s/%p:%ld)\n", debugstr_w(family->FamilyName), - debugstr_w(face->StyleName), debugstr_w(face->file), face->font_data_ptr, face->face_index); + TRACE( "Chosen: %s (%s/%p:%ld)\n", debugstr_w(face->full_name), debugstr_w(face->file), + face->font_data_ptr, face->face_index );
ret->aveWidth = height ? lf.lfWidth : 0;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/gdi32/freetype.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index f9b989d9e90..faad39ed402 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -269,7 +269,7 @@ struct enum_data typedef struct tagFace { struct list entry; unsigned int refcount; - WCHAR *StyleName; + WCHAR *style_name; WCHAR *full_name; WCHAR *file; dev_t dev; @@ -1527,7 +1527,7 @@ static WCHAR *ft_face_get_full_name( FT_Face ft_face, LANGID langid )
static inline BOOL faces_equal( const Face *f1, const Face *f2 ) { - if (strcmpiW( f1->StyleName, f2->StyleName )) return FALSE; + if (strcmpiW( f1->style_name, f2->style_name )) return FALSE; if (f1->scalable) return TRUE; if (f1->size.y_ppem != f2->size.y_ppem) return FALSE; return !memcmp( &f1->fs, &f2->fs, sizeof(f1->fs) ); @@ -1553,7 +1553,7 @@ static void release_face( Face *face ) release_family( face->family ); } HeapFree( GetProcessHeap(), 0, face->file ); - HeapFree( GetProcessHeap(), 0, face->StyleName ); + HeapFree( GetProcessHeap(), 0, face->style_name ); HeapFree( GetProcessHeap(), 0, face->full_name ); HeapFree( GetProcessHeap(), 0, face->cached_enum_data ); HeapFree( GetProcessHeap(), 0, face ); @@ -1695,13 +1695,13 @@ static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family, void *bu
face->refcount = 1; face->file = strdupW( buffer ); - face->StyleName = strdupW(face_name); + face->style_name = strdupW( face_name );
needed = buffer_size; if (RegQueryValueExW( hkey_face, face_full_name_value, NULL, NULL, buffer, &needed ) != ERROR_SUCCESS) { ERR( "couldn't find full name for %s %s in cache\n", debugstr_w(family->FamilyName), - debugstr_w(face->StyleName) ); + debugstr_w(face->style_name) ); release_face( face ); return; } @@ -1876,13 +1876,12 @@ static void add_face_to_cache(Face *face) RegSetValueExW(hkey_family, english_name_value, 0, REG_SZ, (BYTE*)face->family->EnglishName, (strlenW(face->family->EnglishName) + 1) * sizeof(WCHAR));
- if(face->scalable) - face_key_name = face->StyleName; + if (face->scalable) face_key_name = face->style_name; else { static const WCHAR fmtW[] = {'%','s','\','%','d',0}; - face_key_name = HeapAlloc(GetProcessHeap(), 0, (strlenW(face->StyleName) + 10) * sizeof(WCHAR)); - sprintfW(face_key_name, fmtW, face->StyleName, face->size.y_ppem); + face_key_name = HeapAlloc( GetProcessHeap(), 0, (strlenW( face->style_name ) + 10) * sizeof(WCHAR) ); + sprintfW( face_key_name, fmtW, face->style_name, face->size.y_ppem ); } RegCreateKeyExW(hkey_family, face_key_name, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey_face, NULL); @@ -1917,18 +1916,19 @@ static void add_face_to_cache(Face *face) static void remove_face_from_cache( Face *face ) { HKEY hkey_family; + WCHAR *face_key_name;
RegOpenKeyExW( hkey_font_cache, face->family->FamilyName, 0, KEY_ALL_ACCESS, &hkey_family );
if (face->scalable) { - RegDeleteKeyW( hkey_family, face->StyleName ); + RegDeleteKeyW( hkey_family, face->style_name ); } else { static const WCHAR fmtW[] = {'%','s','\','%','d',0}; - WCHAR *face_key_name = HeapAlloc(GetProcessHeap(), 0, (strlenW(face->StyleName) + 10) * sizeof(WCHAR)); - sprintfW(face_key_name, fmtW, face->StyleName, face->size.y_ppem); + face_key_name = HeapAlloc( GetProcessHeap(), 0, (strlenW( face->style_name ) + 10) * sizeof(WCHAR) ); + sprintfW( face_key_name, fmtW, face->style_name, face->size.y_ppem ); RegDeleteKeyW( hkey_family, face_key_name ); HeapFree(GetProcessHeap(), 0, face_key_name); } @@ -2125,7 +2125,7 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file, Face *face = HeapAlloc( GetProcessHeap(), 0, sizeof(*face) );
face->refcount = 1; - face->StyleName = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() ); + face->style_name = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() ); face->full_name = ft_face_get_full_name( ft_face, GetSystemDefaultLangID() ); if (flags & ADDFONT_VERTICAL_FONT) face->full_name = get_vertical_name( face->full_name );
@@ -2385,7 +2385,7 @@ static void DumpFontList(void) LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { TRACE("Family: %s\n", debugstr_w(family->FamilyName)); LIST_FOR_EACH_ENTRY( face, &family->faces, Face, entry ) { - TRACE( "\t%s\t%s\t%08x", debugstr_w(face->StyleName), debugstr_w(face->full_name), + TRACE( "\t%s\t%s\t%08x", debugstr_w(face->style_name), debugstr_w(face->full_name), face->fs.fsCsb[0] ); if(!face->scalable) TRACE(" %d", face->size.height); @@ -6201,7 +6201,7 @@ static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEX
lstrcpynW(pelf->elfLogFont.lfFaceName, family_name, LF_FACESIZE); lstrcpynW( pelf->elfFullName, face->full_name, LF_FULLFACESIZE ); - lstrcpynW(pelf->elfStyle, face->StyleName, LF_FACESIZE); + lstrcpynW( pelf->elfStyle, face->style_name, LF_FACESIZE ); }
pntm->ntmTm.ntmFlags = face->ntmFlags;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/gdi32/freetype.c | 2 +- dlls/gdi32/tests/font.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index faad39ed402..36b11fa23ab 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1527,7 +1527,7 @@ static WCHAR *ft_face_get_full_name( FT_Face ft_face, LANGID langid )
static inline BOOL faces_equal( const Face *f1, const Face *f2 ) { - if (strcmpiW( f1->style_name, f2->style_name )) return FALSE; + if (strcmpiW( f1->full_name, f2->full_name )) return FALSE; if (f1->scalable) return TRUE; if (f1->size.y_ppem != f2->size.y_ppem) return FALSE; return !memcmp( &f1->fs, &f2->fs, sizeof(f1->fs) ); diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index b1848a43743..f5c8d4dac3b 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -6984,13 +6984,11 @@ static void test_ttf_names(void) strcpy(font.lfFaceName, "Wine TTF Names Long Family1 Ext"); memset(&efnd, 0, sizeof(efnd)); EnumFontFamiliesExA(dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0); - todo_wine ok(efnd.total == 2, "EnumFontFamiliesExA found %d fonts, expected 2.\n", efnd.total);
strcpy(font.lfFaceName, "Wine TTF Names Long Family1 Con"); memset(&efnd, 0, sizeof(efnd)); EnumFontFamiliesExA(dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0); - todo_wine ok(efnd.total == 2, "EnumFontFamiliesExA found %d fonts, expected 2.\n", efnd.total);
handle_font = CreateFontIndirectA(&font); @@ -6998,7 +6996,6 @@ static void test_ttf_names(void) DeleteObject(handle_font);
ret = RemoveFontResourceExA(ttf_name_bold, FR_PRIVATE, 0); - todo_wine ok(ret, "RemoveFontResourceEx() failed\n");
DeleteFileA(ttf_name_bold);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78125
Your paranoid android.
=== debiant (32 bit Japanese:Japan report) ===
gdi32: font.c:6378: Test failed: 0(2): expected height 13, got 18 font.c:6378: Test failed: 1(0): expected height 13, got 18 font.c:6378: Test failed: 4(0): expected height 13, got 18 font.c:1297: Test failed: got 88.000000 font.c:1299: Test failed: GetCharABCWidthsW should have succeeded font.c:1300: Test failed: got 2226320 font.c:1304: Test failed: GetCharABCWidthsW should have succeeded font.c:1312: Test failed: GetCharABCWidthsW should have succeeded font.c:1317: Test failed: got 8, expected 2226320 (B) font.c:1319: Test failed: got 0, expected 11246640 (C) font.c:1392: Test failed: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: LTR: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: LTR -1 compatible: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: LTR -1 advanced: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: LTR 1 compatible: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: LTR 1 advanced: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: RTL: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: RTL -1 compatible: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: RTL -1 advanced: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: RTL 1 compatible: GetCharABCWidthsW should have succeeded font.c:1125: Test failed: RTL 1 advanced: GetCharABCWidthsW should have succeeded font.c:2146: Test failed: expected 212, got 0, error 1400 font.c:2173: Test failed: got 0x7e4dbb20 font.c:2146: Test failed: expected 212, got 0, error 1400 font.c:2178: Test failed: got 0x8 font.c:2146: Test failed: expected 212, got 0, error 1400 font.c:2146: Test failed: expected 212, got 0, error 1400 font.c:2195: Test failed: got 0x7e4dbb20 font.c:2739: Test failed: Unexpected ranges count. font.c:4051: Test failed: expected MS Shell Dlg, got FixedSys font.c:4053: Test failed: expected ANSI_CHARSET, got 128 for font MS Shell Dlg font.c:4064: Test failed: expected MS Shell Dlg, got FixedSys font.c:4051: Test failed: expected MS Shell Dlg, got FixedSys font.c:4053: Test failed: expected ANSI_CHARSET, got 128 for font MS Shell Dlg font.c:4064: Test failed: expected MS Shell Dlg, got FixedSys font.c:4051: Test failed: expected MS Shell Dlg, got FixedSys font.c:4053: Test failed: expected ANSI_CHARSET, got 128 for font MS Shell Dlg font.c:4064: Test failed: expected MS Shell Dlg, got FixedSys font.c:4051: Test failed: expected MS Shell Dlg, got FixedSys font.c:4053: Test failed: expected ANSI_CHARSET, got 128 for font MS Shell Dlg font.c:4064: Test failed: expected MS Shell Dlg, got FixedSys font.c:4051: Test failed: expected MS Shell Dlg, got FixedSys font.c:4053: Test failed: expected ANSI_CHARSET, got 128 for font MS Shell Dlg font.c:4064: Test failed: expected MS Shell Dlg, got FixedSys font.c:5435: Test failed: MS Shell Dlg 2 should be enumerated font.c:5437: Test failed: MS Shell Dlg 2 should be enumerated as a TrueType font font.c:5470: Test failed: MS Shell Dlg 2 should be enumerated font.c:5471: Test failed: MS Shell Dlg 2 should be enumerated font.c:7073: Test failed: GetOutlineTextMetricsA failed font.c:7083: Test failed: got 4294967295 font.c:6445: Test failed: expected 1 ppem value (18), got 65538 font.c:6447: Test failed: expected 1 ppem value (8), got 29128 font.c:6445: Test failed: expected 1 ppem value (18), got 123444 font.c:6447: Test failed: expected 1 ppem value (8), got 54864 font.c:6445: Test failed: expected 1 ppem value (18), got 123444 font.c:6447: Test failed: expected 1 ppem value (8), got 54864 font.c:6629: Test failed: got 0 font.c:6629: Test failed: got 0 font.c:6650: Test failed: expected 0, got 1 font.c:6652: Test failed: expected 2076343486, got 2228233