diff options
author | Christoph Reiter <reiter.christoph@gmail.com> | 2018-12-03 23:12:27 +0100 |
---|---|---|
committer | Christoph Reiter <reiter.christoph@gmail.com> | 2018-12-04 09:59:49 +0100 |
commit | f523c25c12cd19c59fbc3db4a4fe08bae5307802 (patch) | |
tree | 00bfa381d049ef9878d6c28dd520767902857600 /pango/pangowin32-fontmap.c | |
parent | 169044900b20cba827be72510396a52ecde9ed51 (diff) | |
download | pango-f523c25c12cd19c59fbc3db4a4fe08bae5307802.tar.gz |
pangowin32: Read the font fallback list from the registry instead of hardcoding it for some fonts.
We only had a fallback list for "Segoe UI" which is the default Windows font, but not on
Chinese or Korean Windows version which use "JhengHei UI" etc. and fall back to "Segoe UI".
Instead of hardcoding the fallbacks in the alias list read them from the registry
(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink)
This should allow us to use the default Windows font by default in gtk+ on Win8+,
see https://gitlab.gnome.org/GNOME/gtk/merge_requests/436 for details.
This also bumps the required Windows version to Vista for RegGetValueW().
Diffstat (limited to 'pango/pangowin32-fontmap.c')
-rw-r--r-- | pango/pangowin32-fontmap.c | 105 |
1 files changed, 103 insertions, 2 deletions
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index 12fa4f26..0cf8f5a0 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -449,8 +449,6 @@ handle_alias_line (GString *line_buffer, static const char * const builtin_aliases[] = { "courier = \"courier new\"", - "\"segoe ui\" = \"segoe ui,meiryo,malgun gothic,microsoft jhenghei,microsoft yahei,gisha,leelawadee,arial unicode ms,browallia new,mingliu,simhei,gulimche,ms gothic,sylfaen,kartika,latha,mangal,raavi\"", - "tahoma = \"tahoma,arial unicode ms,lucida sans unicode,browallia new,mingliu,simhei,gulimche,ms gothic,sylfaen,kartika,latha,mangal,raavi\"", /* It sucks to use the same GulimChe, MS Gothic, Sylfaen, Kartika, * Latha, Mangal and Raavi fonts for all three of sans, serif and * mono, but it isn't like there would be much choice. For most @@ -490,6 +488,108 @@ read_builtin_aliases (GHashTable *ht_aliases) g_string_free (line_buffer, TRUE); } + +#define MAX_VALUE_NAME 16383 + +static void +read_windows_fallbacks (GHashTable *ht_aliases) +{ + DWORD value_index; + HKEY hkey; + LSTATUS status; + GString *line_buffer; + + /* https://docs.microsoft.com/en-us/globalization/input/font-technology */ + status = RegOpenKeyExW (HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink", + 0, + KEY_READ, + &hkey); + if (status != ERROR_SUCCESS) + return; + + line_buffer = g_string_new (NULL); + status = ERROR_SUCCESS; + for (value_index = 0; status != ERROR_NO_MORE_ITEMS; value_index++) + { + wchar_t name[MAX_VALUE_NAME]; + DWORD name_length = MAX_VALUE_NAME, value_length = 0; + char *errstring = NULL; + gchar *utf8_name; + wchar_t *value_data, *entry; + size_t entry_len; + + status = RegEnumValueW (hkey, value_index, name, &name_length, + NULL, NULL, NULL, NULL); + + if (status != ERROR_SUCCESS) + continue; + + utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL); + if (utf8_name == NULL) + continue; + g_string_truncate (line_buffer, 0); + g_string_append_printf (line_buffer, + "\"%s\" = \"%s", + utf8_name, + utf8_name); + g_free (utf8_name); + + status = RegGetValueW (hkey, NULL, name, RRF_RT_REG_MULTI_SZ, + NULL, NULL, &value_length); + if (status != ERROR_SUCCESS) + continue; + + value_data = g_malloc (value_length); + status = RegGetValueW (hkey, NULL, name, RRF_RT_REG_MULTI_SZ, NULL, + value_data, &value_length); + if (status != ERROR_SUCCESS) + { + g_free (value_data); + continue; + } + + entry = value_data; + entry_len = wcslen (entry); + while (entry_len > 0) + { + wchar_t *comma; + gchar *entry_utf8; + + comma = wcsstr (entry, L","); + /* The value after the first comma, as long as it isn't followed + * by another comma with a font scale */ + if (comma && wcsstr (comma + 1, L",") == NULL) + { + g_string_append (line_buffer, ","); + entry_utf8 = g_utf16_to_utf8 (comma + 1, -1, NULL, NULL, NULL); + if (entry_utf8 != NULL) + { + g_string_append (line_buffer, entry_utf8); + g_free (entry_utf8); + } + } + + entry += entry_len + 1; + entry_len = wcslen (entry); + } + g_free (value_data); + g_string_append (line_buffer, "\""); + + handle_alias_line (line_buffer, &errstring, ht_aliases); + if (errstring != NULL) + { + g_warning ("error in windows fallback: %s (%s)\n", + errstring, line_buffer->str); + g_free (errstring); + errstring = NULL; + } + } + + RegCloseKey (hkey); + g_string_free (line_buffer, TRUE); +} + #endif @@ -502,6 +602,7 @@ load_aliases (void) NULL); #ifdef HAVE_CAIRO_WIN32 + read_windows_fallbacks (ht_aliases); read_builtin_aliases (ht_aliases); #endif |