the patch can resolve the issue: https://bugs.winehq.org/show_bug.cgi?id=54483
and can also solve many crashed issue related to font(MS Shell Dlg etc.)
-- v6: add a skip log when there is no simsun font in test env.
From: Keming Liang liangkeming@kylinos.cn
--- dlls/win32u/font.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 742a31b59a4..56509938cb4 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -983,7 +983,7 @@ static void dump_gdi_font_list(void)
WINE_RB_FOR_EACH_ENTRY( family, &family_name_tree, struct gdi_font_family, name_entry ) { - TRACE( "Family: %s\n", debugstr_w(family->family_name) ); + TRACE( "Family: %s, Second name: %s\n", debugstr_w(family->family_name),debugstr_w(family->second_name) ); LIST_FOR_EACH_ENTRY( face, &family->faces, struct gdi_font_face, entry ) { TRACE( "\t%s\t%s\t%08x", debugstr_w(face->style_name), debugstr_w(face->full_name), @@ -3441,18 +3441,19 @@ static BOOL family_matches( struct gdi_font_family *family, const WCHAR *face_na { struct gdi_font_face *face;
- if (!facename_compare( face_name, family->family_name, LF_FACESIZE - 1 )) return TRUE; + if (!facename_compare( face_name, family->family_name, LF_FACESIZE - 1 ) || !facename_compare( face_name, family->second_name, LF_FACESIZE - 1 )) return TRUE; LIST_FOR_EACH_ENTRY( face, get_family_face_list(family), struct gdi_font_face, entry ) if (!facename_compare( face_name, face->full_name, LF_FACESIZE - 1 )) return TRUE; return FALSE; }
-static BOOL face_matches( const WCHAR *family_name, struct gdi_font_face *face, const WCHAR *face_name ) +static BOOL face_matches( struct gdi_font_family *family, struct gdi_font_face *face, const WCHAR *face_name ) { - if (!facename_compare( face_name, family_name, LF_FACESIZE - 1)) return TRUE; + if (!facename_compare( face_name, family->family_name, LF_FACESIZE - 1) || !facename_compare( face_name, family->second_name, LF_FACESIZE - 1 ) ) return TRUE; return !facename_compare( face_name, face->full_name, LF_FACESIZE - 1 ); }
+ static BOOL enum_face_charsets( const struct gdi_font_family *family, struct gdi_font_face *face, struct enum_charset *list, DWORD count, FONTENUMPROCW proc, LPARAM lparam, const WCHAR *subst ) @@ -3549,7 +3550,7 @@ static BOOL CDECL font_EnumFonts( PHYSDEV dev, LOGFONTW *lf, FONTENUMPROCW proc, if (!family_matches(family, face_name)) continue; LIST_FOR_EACH_ENTRY( face, get_family_face_list(family), struct gdi_font_face, entry ) { - if (!face_matches( family->family_name, face, face_name )) continue; + if (!face_matches( family, face, face_name )) continue; if (!enum_face_charsets( family, face, enum_charsets, count, proc, lparam, orig_name )) return FALSE; /* enum_face_charsets() unlocked font_lock */ }
From: Keming Liang liangkeming@kylinos.cn
--- dlls/gdi32/tests/font.c | 56 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 7be8d6f2c66..f887c98f41f 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -89,6 +89,12 @@ static INT CALLBACK is_truetype_font_installed_proc(const LOGFONTA *elf, const T return 0; }
+static INT CALLBACK is_truetype_font_installed_procW(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lParam) +{ + if (type != TRUETYPE_FONTTYPE) return 1; + + return 0; +} static BOOL is_truetype_font_installed(const char *name) { HDC hdc = GetDC(0); @@ -101,6 +107,18 @@ static BOOL is_truetype_font_installed(const char *name) return ret; }
+static BOOL is_truetype_font_installedW(const WCHAR *name) +{ + HDC hdc = GetDC(0); + BOOL ret = FALSE; + + if (!EnumFontFamiliesW(hdc, name, is_truetype_font_installed_procW, 0)) + ret = TRUE; + + ReleaseDC(0, hdc); + return ret; +} + static INT CALLBACK is_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam) { return 0; @@ -2957,6 +2975,33 @@ static void get_charset_statsW(struct enum_font_dataW *efd, } }
+ +static void test_EnumFontFamiliesW(const WCHAR *font_nameW, INT font_charset) +{ + struct enum_font_dataW efdw; + HDC hdc; + int ret; + + if (!font_nameW ) + { + skip("font_name is NULL\n"); + return; + } + memset( &efdw, 0, sizeof(efdw) ); + + hdc = GetDC(0); + + efdw.total = 0; + SetLastError(0xdeadbeef); + ret = EnumFontFamiliesW(hdc, font_nameW, arial_enum_procw, (LPARAM)&efdw); + ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "EnumFontFamiliesW error %lu\n", GetLastError()); + if(ret) + { + ok(efdw.total > 0, "fonts %s enumerated: NULL\n",debugstr_w(font_nameW)); + } +} + + static void test_EnumFontFamilies(const char *font_name, INT font_charset) { struct enum_font_data efd; @@ -7808,6 +7853,16 @@ START_TEST(font) test_EnumFonts(); test_EnumFonts_subst();
+ /* test SimSun and MS Shell Dlg font when the language is Chinese Simplified.*/ + if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_CHINESE_SIMPLIFIED) + { + if(is_truetype_font_installedW(L"SimSun")) + { + test_EnumFontFamiliesW(L"SimSun", DEFAULT_CHARSET); + test_EnumFontFamiliesW(L"MS Shell Dlg", DEFAULT_CHARSET); + } + } + /* On Windows Arial has a lot of default charset aliases such as Arial Cyr, * I'd like to avoid them in this test. */ @@ -7822,6 +7877,7 @@ START_TEST(font) } else skip("Arial Black or Symbol/Wingdings is not installed\n"); + test_EnumFontFamiliesEx_default_charset(); test_GetTextMetrics(); test_RealizationInfo();
From: Keming Liang liangkeming@kylinos.cn
--- dlls/gdi32/tests/font.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index f887c98f41f..447bf12f42e 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -7861,6 +7861,8 @@ START_TEST(font) test_EnumFontFamiliesW(L"SimSun", DEFAULT_CHARSET); test_EnumFontFamiliesW(L"MS Shell Dlg", DEFAULT_CHARSET); } + else + skip("SimSun is not installed\n"); }
/* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
On Mon Mar 6 06:59:54 2023 +0000, Akihiro Sagawa wrote:
As seen in another merge request, our preference is to add test cases with `todo_wine` first. Then change the main part and remove `todo_wine`. In general, a locale-specific test case is not a good idea. I think the test case will pass in another locale if we have SimSun typeface. If SimSun is not available in the test environment, it is good practice to add a `skip` message indicating that the test is not run.
I added a skip message indicating if SimSun is not available.
The problem I met is, when there is SimSun typeface,but still can't enum MS Shell Dlg, because the family name is Chinese "宋体",not SimSun. the second name is SimSun(english).
So I write this test case. I have tested it , with my patch and SimSun typeface, the test is OK
What else needs to be done here, to merge it into master branch?