If the font is not found in Family_name_tree, but in Family_second_name_tree, then it must exist in the font_subst_list.
From: Haoyang Chen chenhaoyang@kylinos.cn
--- dlls/win32u/font.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 7e70cccf568..159cb89a05a 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -3552,6 +3552,9 @@ static BOOL font_EnumFonts( PHYSDEV dev, LOGFONTW *lf, font_enum_proc proc, LPAR if (face_name) { orig_name = lf->lfFaceName; + if (!find_family_from_name(face_name) && find_family_from_any_name(face_name)) + face_name = get_gdi_font_subst( face_name, charset, NULL ); + TRACE( "substituting %s -> %s\n", debugstr_w(lf->lfFaceName), debugstr_w(face_name) ); } else face_name = lf->lfFaceName;
From: Haoyang Chen chenhaoyang@kylinos.cn
--- dlls/gdi32/tests/Makefile.in | 1 + dlls/gdi32/tests/font.c | 127 +++++++++++++++++++++++++++ dlls/gdi32/tests/resource.rc | 3 + dlls/gdi32/tests/wine_secondname.sfd | 76 ++++++++++++++++ dlls/gdi32/tests/wine_secondname.ttf | Bin 0 -> 3952 bytes 5 files changed, 207 insertions(+) create mode 100644 dlls/gdi32/tests/wine_secondname.sfd create mode 100644 dlls/gdi32/tests/wine_secondname.ttf
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in index d6f33ee087d..482e12928cd 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_secondname.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..c39e3a2998d 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -28,6 +28,8 @@ #include "wingdi.h" #include "winuser.h" #include "winnls.h" +#include "winternl.h" +#include "winreg.h"
#include "wine/test.h"
@@ -51,6 +53,17 @@ static HMODULE hgdi32 = 0; static const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} }; static WORD system_lang_id;
+static const WCHAR font_substitutes_keyW[] = +{ + '\','R','e','g','i','s','t','r','y', + '\','M','a','c','h','i','n','e', + '\','S','o','f','t','w','a','r','e', + '\','M','i','c','r','o','s','o','f','t', + '\','W','i','n','d','o','w','s',' ','N','T', + '\','C','u','r','r','e','n','t','V','e','r','s','i','o','n', + '\','F','o','n','t','S','u','b','s','t','i','t','u','t','e','s' +}; + #ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) #define GET_BE_DWORD(x) (x) @@ -7767,11 +7780,115 @@ static void test_GetOutlineTextMetrics_subst(void) ReleaseDC(0, hdc); }
+static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len ) +{ + UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name }; + OBJECT_ATTRIBUTES attr; + HANDLE ret; + + attr.Length = sizeof(attr); + attr.RootDirectory = root; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + if (NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 )) return 0; + return ret; +} + +static inline UINT asciiz_to_unicode( WCHAR *dst, const char *src ) +{ + WCHAR *p = dst; + while ((*p++ = *src++)); + return (p - dst) * sizeof(WCHAR); +} + +static BOOL set_reg_value( HKEY hkey, const WCHAR *name, UINT type, const void *value, DWORD count ) +{ + unsigned int name_size = name ? lstrlenW( name ) * sizeof(WCHAR) : 0; + UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name }; + return !NtSetValueKey( hkey, &nameW, 0, type, value, count ); +} + +static void set_reg_ascii_value( HKEY hkey, const char *name, const char *value ) +{ + WCHAR nameW[64], valueW[128]; + asciiz_to_unicode( nameW, name ); + set_reg_value( hkey, nameW, REG_SZ, valueW, asciiz_to_unicode( valueW, value )); +} + +static void reg_delete_value( HKEY hkey, const WCHAR *name ) +{ + unsigned int name_size = lstrlenW( name ) * sizeof(WCHAR); + UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name }; + + NtDeleteValueKey( hkey, &nameW ); +} + +static void test_second_name(void) +{ + char ttf_name[MAX_PATH]; + LOGFONTA font = {0}; + BOOL found_font; + int ret; + HDC dc; + HKEY hkey; + BOOL is_wine = !strcmp(winetest_platform, "wine"); + + if (!write_ttf_file("wine_secondname.ttf", ttf_name)) + { + skip("Failed to create ttf file for testing\n"); + return; + } + + if (is_wine) + { + hkey = reg_open_key(NULL, font_substitutes_keyW, sizeof(font_substitutes_keyW)); + ok(!!hkey, "open register key for FontSubstitutes failed.\n"); + } + + dc = GetDC(NULL); + + ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "AddFontResourceEx() failed\n"); + + strcpy(font.lfFaceName, "wine_this_is_first_name"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find wine_this_is_first_name font.\n"); + + strcpy(font.lfFaceName, "wine_this_is_second_name"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find wine_this_is_second_name font.\n"); + + if (is_wine) + { + strcpy(font.lfFaceName, "wine_this_is_second_name_subst"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find wine_this_is_second_name font.\n"); + } + + ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "RemoveFontResourceEx() failed\n"); + + DeleteFileA(ttf_name); + ReleaseDC(NULL, dc); + if (is_wine) + { + reg_delete_value( hkey, L"wine_this_is_second_name_subst"); + NtClose( hkey ); + } +} + START_TEST(font) { static const char *test_names[] = { "AddFontMemResource", + "test_second_name", }; char path_name[MAX_PATH]; STARTUPINFOA startup; @@ -7785,6 +7902,8 @@ START_TEST(font) { if (!strcmp(argv[2], "AddFontMemResource")) test_AddFontMemResource(); + if (!strcmp(argv[2], "test_second_name")) + test_second_name(); return; }
@@ -7868,6 +7987,14 @@ START_TEST(font) { PROCESS_INFORMATION info;
+ if (!strcmp(winetest_platform, "wine") && !strcmp(test_names[i], "test_second_name")) + { + HKEY hkey; + hkey = reg_open_key(NULL, font_substitutes_keyW, sizeof(font_substitutes_keyW)); + set_reg_ascii_value( hkey, "wine_this_is_second_name_subst", "wine_this_is_second_name"); + NtClose( hkey ); + } + memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); sprintf(path_name, "%s font %s", argv[0], test_names[i]); diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc index 784d8602a9a..acfaa106632 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_secondname.ttf */ +wine_secondname.ttf RCDATA wine_secondname.ttf diff --git a/dlls/gdi32/tests/wine_secondname.sfd b/dlls/gdi32/tests/wine_secondname.sfd new file mode 100644 index 00000000000..5c0237cbfcb --- /dev/null +++ b/dlls/gdi32/tests/wine_secondname.sfd @@ -0,0 +1,76 @@ +SplineFontDB: 3.2 +FontName: wine_this_is_second_name +FullName: wine_this_is_second_name +FamilyName: wine_this_is_second_name +Weight: Regular +Copyright: Copyright (c) 2023, Haoyang Chen +UComments: "2023-12-18: Created with FontForge (http://fontforge.org)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -100 +UnderlineWidth: 50 +Ascent: 800 +Descent: 200 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "+gMxmbwAA" 1 +Layer: 1 0 "+Uk1mbwAA" 0 +XUID: [1021 296 1263752128 9813898] +FSType: 0 +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1702866398 +ModificationTime: 1702877141 +PfmFamily: 17 +TTFWeight: 400 +TTFWidth: 5 +LineGap: 90 +VLineGap: 0 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 90 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +LangName: 2052 "Copyright (c) 2023, Haoyang Chen" "wine_this_is_first_name" "Regular" "wine_this_is_first_name" "wine_this_is_first_name" "+ckhnLAAA 001.000" +LangName: 1033 "" "" "" "wine_this_is_second_name" +Encoding: ISO8859-1 +UnicodeInterp: simpchinese +NameList: Adobe Glyph List +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 64 16 4 +BeginPrivate: 0 +EndPrivate +TeXData: 1 0 0 346030 173015 115343 0 1048576 115343 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144 +BeginChars: 256 1 + +StartChar: at +Encoding: 64 64 0 +Width: 1000 +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 +Validated: 1 +EndChar +EndChars +EndSplineFont diff --git a/dlls/gdi32/tests/wine_secondname.ttf b/dlls/gdi32/tests/wine_secondname.ttf new file mode 100644 index 0000000000000000000000000000000000000000..35b135da7eee34cad7c1881a331854c44a71a21f GIT binary patch literal 3952 zcmeH~UuaWT9LImZb8p(H-E5(ob?d_|7FMOJF?CX*8)0?QhserSrAV=jNty)OG&FIx zAmW3AvX!l%V@2F>!+{Sn+ESsgP8^fjF$WHOkWsb{+~|ga4;}NNTlYOTU;peuhEouR zH@)}s{r%24zkB}V<oqfsB2UO6aineg_VyhgZ+`!2k=5<+R=@iC#_-P1Vg(WHfZZMM zi{*O4N4|zVD-zruf1}_@jTsVIS&niy70c(Amk~);M_~t3y+b{pzx`nt<sR%@IvGpU zj%<J}bGWyp;c)+Ot|MM0?Aml+VQ|&7*212KUEbRtkI7y^Usl@km3^_noV3bTlsCcl zva!D8k+OqbC>q7<-^umo3(G&s3wXbW@(p6ghWneXJGOMKZvI_XIScT}PoM1BQ{?bY zsSz>89D^McW4*Z0#`o+l);GqFR4gk#UEky0Zev@j?~6!-U&VD6bW{R}^p=@{XQW7- zmraV=Mgl8}q5PJ&rAS-PD+xI#5s5h7a+B=#d*b)$b|p^~Jwwk$Y!C4!%(;D+oqMS- z_O>(vu7w?i7bAk-@yny)iU-@p$ND2!Gyl2#WwE80l0|qPUk^G1K`ECi%ypfFqzNn9 zDs9ps-IA7^3}Vj>%czXW2{|R>GL1E#l}mC(=4C-{$W45mf?BRs>S>*Zv`Hh{s%_e# z-I~^%4(cHt)=?eP6M9O=bz0BqtX|S9I<E_QLvI=}K~rw3jA!ah$TXRVX*F%8!*rXp z$(ccO$PAlNGiFYhQ)b*un{#H?TryY8yzzGl2LBPhr@!He-Qw1g)np}EM!H2hOXMPX zjl4?Ek(bGf<au(2oFY$?C&}aFQF4SlOdcQ$WG|T@JIQu3N^T>Y$<1UvSxZ)vm1G&| z7HO8qMe-VXm7F6llNZVJ<P14Qo+eL{$H}AQ2zi)1Ko-beGC_8d?PQePMmCe1$$GMu ztR^eTGSV$lm&ir(8hMqRBQKK|$@An4IYpi(Pm;&UqvQyAm^?rh$X+r*c9QL6l-%~9 zoBe^?+u!cT*CU$&ExB{Z+7nvrefMS0%73~32TSPZbI6_S$7Wf^<{7#HS%@R0(lDX2 zv3au8mFwY&lE7T^q+=ju!m;jvbx)R-=u-0}rto^Wv7)BpxyFihHM(Nq!Uc2e&z>67 zfpF?*6j|4ponw6#=64Mm)#zVSc7C7HmzakL&d!&q6({L?xAGJ8<SexV|4nLFs<eeV zAmw_Hx&;0&px632lV_@_Ro0k3Y9pn_#<z7G_`jugWsUO`bwJ9T7L=-MbGHcYqE?*m zacUz^%BR#0{9jSK64DClfOy(TT>}5RRtH@hQ@^KHX)rHRBc^$i+JXNAY8U!v>VQ-_ z&r6H+Bexim0m(=Tc}4*<Sckr?2gB%1SQ?QBddNg#s5yjZ7WF)|OG^@3TKaQC1DRC1 z;MK*~d*M*HvEFNq^$*3eDX%4+M2-Cjokis?1W!Zfp^DEuym5rhN&>ztg7?8A`!m^O zS0SCrci}IejQ3{~T{d+Wc@4!W*(bfIIsh}7+SeO{c!;lfh@p0&w*we%#vh`G*$l}h zWc!vO%%SW`4&*caSuYgY)DQ}V;CYB|f21qhgF)M&7w);PJ(+=g;Xg0y{l&lctln3g zf!37W3jbV28UJPC?5!2VhP1y>_F6uJy>sV)@O}Qn?pj5yb-tzeU&^*nYyI%+_+HDq H|KI!@i=z@Q
literal 0 HcmV?d00001
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146263
Your paranoid android.
=== debian11 (32 bit ar:MA report) ===
gdi32: font.c:7859: Test failed: EnumFontFamiliesExA didn't find wine_this_is_first_name font.
=== debian11 (32 bit de report) ===
gdi32: font.c:7859: Test failed: EnumFontFamiliesExA didn't find wine_this_is_first_name font.
=== debian11 (32 bit fr report) ===
gdi32: font.c:7859: Test failed: EnumFontFamiliesExA didn't find wine_this_is_first_name font.
=== debian11 (32 bit he:IL report) ===
gdi32: font.c:7859: Test failed: EnumFontFamiliesExA didn't find wine_this_is_first_name font.
=== debian11 (32 bit hi:IN report) ===
gdi32: font.c:7859: Test failed: EnumFontFamiliesExA didn't find wine_this_is_first_name font.
=== debian11 (32 bit ja:JP report) ===
gdi32: font.c:7859: Test failed: EnumFontFamiliesExA didn't find wine_this_is_first_name font.