[PATCH v2 0/2] MR10672: win32u: Initialize Uniscribe fallback registry keys on startup.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=27641 @aricstewart I thought about the trade-offs between the two approaches (this and https://gitlab.winehq.org/wine/wine/-/merge_requests/10630) and finally decided to go through with this, because this would allow for a more better UX. How does this look? If it looks better, we can close the previous MR. Also I will open a separate MR for the script tag, which will hopefully have a better solution than just using one script tag for a script. -- v2: win32u: Initialize Uniscribe fallback registry keys on startup. win32u: Implement fontconfig_get_default_font_for_char(). https://gitlab.winehq.org/wine/wine/-/merge_requests/10672
From: समीर सिंह Sameer Singh <lumarzeli30@gmail.com> This would allow Uniscribe to dynamically populate script based fallback mappings in the registry based on the system's available fonts. --- dlls/win32u/freetype.c | 45 +++++++++++++++++++++++++++++++++++++ dlls/win32u/ntgdi_private.h | 1 + 2 files changed, 46 insertions(+) diff --git a/dlls/win32u/freetype.c b/dlls/win32u/freetype.c index a660b166a0f..b5238ab337c 100644 --- a/dlls/win32u/freetype.c +++ b/dlls/win32u/freetype.c @@ -131,6 +131,10 @@ MAKE_FUNCPTR(FcDefaultSubstitute); MAKE_FUNCPTR(FcFontList); MAKE_FUNCPTR(FcFontMatch); MAKE_FUNCPTR(FcFontSetDestroy); +MAKE_FUNCPTR(FcCharSetAddChar); +MAKE_FUNCPTR(FcCharSetCreate); +MAKE_FUNCPTR(FcCharSetDestroy); +MAKE_FUNCPTR(FcPatternAddCharSet); MAKE_FUNCPTR(FcInit); MAKE_FUNCPTR(FcPatternAddString); MAKE_FUNCPTR(FcPatternCreate); @@ -1249,6 +1253,10 @@ static void init_fontconfig(void) LOAD_FUNCPTR(FcFontList); LOAD_FUNCPTR(FcFontMatch); LOAD_FUNCPTR(FcFontSetDestroy); + LOAD_FUNCPTR(FcCharSetAddChar); + LOAD_FUNCPTR(FcCharSetCreate); + LOAD_FUNCPTR(FcCharSetDestroy); + LOAD_FUNCPTR(FcPatternAddCharSet); LOAD_FUNCPTR(FcInit); LOAD_FUNCPTR(FcPatternAddString); LOAD_FUNCPTR(FcPatternCreate); @@ -2027,6 +2035,42 @@ static BOOL fontconfig_enum_family_fallbacks( UINT pitch_and_family, int index, return FALSE; } +/************************************************************* + * fontconfig_get_default_font_for_char + */ +static void fontconfig_get_default_font_for_char( DWORD ch, WCHAR *font_name ) +{ +#ifdef SONAME_LIBFONTCONFIG + FcPattern *pattern, *match; + FcResult result; + const char *name = NULL; + FcCharSet *charset; + DWORD len; + + *font_name = 0; + + pattern = pFcPatternCreate(); + charset = pFcCharSetCreate(); + pFcCharSetAddChar( charset, ch ); + pFcPatternAddCharSet( pattern, FC_CHARSET, charset ); + pFcCharSetDestroy( charset ); + + pFcConfigSubstitute( NULL, pattern, FcMatchPattern ); + pFcDefaultSubstitute( pattern ); + match = pFcFontMatch( NULL, pattern, &result ); + if (match) + { + if (pFcPatternGetString( match, FC_FAMILY, 0, (FcChar8 **)&name ) == FcResultMatch && name) + { + RtlUTF8ToUnicodeN( font_name, (LF_FACESIZE - 1) * sizeof(WCHAR), &len, name, strlen(name) ); + font_name[len / sizeof(WCHAR)] = 0; + } + pFcPatternDestroy( match ); + } + pFcPatternDestroy( pattern ); +#endif +} + static DWORD get_ttc_offset( FT_Face ft_face, UINT face_index ) { FT_ULong len; @@ -3873,6 +3917,7 @@ static UINT freetype_get_kerning_pairs( struct gdi_font *font, KERNINGPAIR **pai static const struct font_backend_funcs font_funcs = { freetype_load_fonts, + fontconfig_get_default_font_for_char, fontconfig_enum_family_fallbacks, freetype_add_font, freetype_add_mem_font, diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index fcfbce58fea..ac77d2aa6ed 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -320,6 +320,7 @@ struct gdi_font struct font_backend_funcs { void (*load_fonts)(void); + void (*get_default_font_for_char)( DWORD ch, WCHAR *font_name ); BOOL (*enum_family_fallbacks)( UINT pitch_and_family, int index, WCHAR buffer[LF_FACESIZE] ); INT (*add_font)( const WCHAR *file, UINT flags ); INT (*add_mem_font)( void *ptr, SIZE_T size, UINT flags ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10672
From: समीर सिंह Sameer Singh <lumarzeli30@gmail.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=27641 --- dlls/win32u/font.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index e34cb13d0e5..e921f2f4ffd 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -6700,6 +6700,83 @@ static void load_registry_fonts(void) NtClose( hkey ); } +static void init_uniscribe_fallbacks(void) +{ + HKEY hkey; + DWORD disp; + WCHAR font_name[LF_FACESIZE]; + int i; + + /* Table kept in sync with scriptInformation[] in dlls/gdi32/uniscribe/usp10.c */ + static const struct + { + DWORD ch; + DWORD tag; + } + fallbacks[] = + { + {0x0531, MS_MAKE_TAG('a', 'r', 'm', 'n')}, + {0x05d0, MS_MAKE_TAG('h', 'e', 'b', 'r')}, + {0x0627, MS_MAKE_TAG('a', 'r', 'a', 'b')}, + {0x0710, MS_MAKE_TAG('s', 'y', 'r', 'c')}, + {0x0780, MS_MAKE_TAG('t', 'h', 'a', 'a')}, + {0x07c0, MS_MAKE_TAG('n', 'k', 'o', ' ')}, + {0x0905, MS_MAKE_TAG('d', 'e', 'v', 'a')}, + {0x0985, MS_MAKE_TAG('b', 'e', 'n', 'g')}, + {0x0a05, MS_MAKE_TAG('g', 'u', 'r', 'u')}, + {0x0a85, MS_MAKE_TAG('g', 'u', 'j', 'r')}, + {0x0b05, MS_MAKE_TAG('o', 'r', 'y', 'a')}, + {0x0b85, MS_MAKE_TAG('t', 'a', 'm', 'l')}, + {0x0c05, MS_MAKE_TAG('t', 'e', 'l', 'u')}, + {0x0c85, MS_MAKE_TAG('k', 'n', 'd', 'a')}, + {0x0d05, MS_MAKE_TAG('m', 'l', 'y', 'm')}, + {0x0d85, MS_MAKE_TAG('s', 'i', 'n', 'h')}, + {0x0e01, MS_MAKE_TAG('t', 'h', 'a', 'i')}, + {0x0e81, MS_MAKE_TAG('l', 'a', 'o', ' ')}, + {0x0f40, MS_MAKE_TAG('t', 'i', 'b', 't')}, + {0x10a0, MS_MAKE_TAG('g', 'e', 'o', 'r')}, + {0x1000, MS_MAKE_TAG('m', 'y', 'm', 'r')}, + {0x1200, MS_MAKE_TAG('e', 't', 'h', 'i')}, + {0x13a0, MS_MAKE_TAG('c', 'h', 'e', 'r')}, + {0x1401, MS_MAKE_TAG('c', 'a', 'n', 's')}, + {0x1681, MS_MAKE_TAG('o', 'g', 'a', 'm')}, + {0x16a0, MS_MAKE_TAG('r', 'u', 'n', 'r')}, + {0x1780, MS_MAKE_TAG('k', 'h', 'm', 'r')}, + {0x1820, MS_MAKE_TAG('m', 'o', 'n', 'g')}, + {0x1950, MS_MAKE_TAG('t', 'a', 'l', 'o')}, + {0x1980, MS_MAKE_TAG('t', 'a', 'l', 'u')}, + {0x2801, MS_MAKE_TAG('b', 'r', 'a', 'i')}, + {0x2d30, MS_MAKE_TAG('t', 'f', 'n', 'g')}, + {0x3041, MS_MAKE_TAG('k', 'a', 'n', 'a')}, + {0x3105, MS_MAKE_TAG('b', 'o', 'p', 'o')}, + {0x4e00, MS_MAKE_TAG('h', 'a', 'n', 'i')}, + {0xa840, MS_MAKE_TAG('p', 'h', 'a', 'g')}, + {0xac00, MS_MAKE_TAG('h', 'a', 'n', 'g')}, + {0xa000, MS_MAKE_TAG('y', 'i', ' ', ' ')}, + {0xa500, MS_MAKE_TAG('v', 'a', 'i', ' ')}, + {0x10400, MS_MAKE_TAG('d', 's', 'r', 't')}, + {0x10480, MS_MAKE_TAG('o', 's', 'm', 'a')}, + {0x1d400, MS_MAKE_TAG('m', 'a', 't', 'h')}, + }; + + hkey = reg_create_ascii_key(hkcu_key, "Software\\Wine\\Uniscribe\\Fallback", 0, &disp); + if (!hkey) return; + + for (i = 0; i < ARRAY_SIZE(fallbacks); i++) + { + font_funcs->get_default_font_for_char(fallbacks[i].ch, font_name); + if (font_name[0]) + { + WCHAR nameW[9]; + char tag_str[9]; + sprintf(tag_str, "%x", fallbacks[i].tag); + ascii_to_unicode(nameW, tag_str, strlen(tag_str) + 1); + set_reg_value(hkey, nameW, REG_SZ, font_name, (lstrlenW(font_name) + 1) * sizeof(WCHAR)); + } + } + NtClose(hkey); +} + static HKEY open_hkcu(void) { char buffer[256]; @@ -6781,6 +6858,7 @@ UINT font_init(void) reorder_font_list(); load_gdi_font_subst(); load_gdi_font_replacements(); + init_uniscribe_fallbacks(); load_system_links(); dump_gdi_font_list(); dump_gdi_font_subst(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10672
participants (2)
-
समीर सिंह Sameer Singh -
समीरसिंह Sameer Singh (@ss141309)