diff --git a/demos/gtk-demo/font_features.c b/demos/gtk-demo/font_features.c index 4c3af558e7ff49329647aaea7e98a05afb5c1a77..074e604ed1df4083099e730f0e3ad4ee0b92d4b4 100644 --- a/demos/gtk-demo/font_features.c +++ b/demos/gtk-demo/font_features.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/demos/gtk-demo/language-names.c b/demos/gtk-demo/language-names.c index 51d994ad15dd450a8139f2e1ea257c2a10887db6..7e0cbf20df1f3e31ba3c0f3f8c05a1af5f86f261 100644 --- a/demos/gtk-demo/language-names.c +++ b/demos/gtk-demo/language-names.c @@ -18,15 +18,81 @@ #include "language-names.h" +#ifdef G_OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else + #ifndef ISO_CODES_PREFIX #define ISO_CODES_PREFIX "/usr" #endif #define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes" #define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale" +#endif static GHashTable *language_map; +#ifdef G_OS_WIN32 +/* if we are using native Windows use native Windows API for language names */ +static BOOL CALLBACK +get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param) +{ + wchar_t *langname_w = NULL; + wchar_t locale_abbrev_w[9]; + gchar *langname, *locale_abbrev, *locale, *p; + gint i; + const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 }; + GHashTable *ht_scripts_langs = (GHashTable *) param; + PangoLanguage *lang; + + gint langname_size, locale_abbrev_size; + langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0); + if (langname_size == 0) + return FALSE; + + langname_w = g_new0 (wchar_t, langname_size); + + if (langname_size == 0) + return FALSE; + + GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size); + langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL); + locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL); + p = strchr (locale, '-'); + lang = pango_language_from_string (locale); + if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL) + g_hash_table_insert (ht_scripts_langs, lang, langname); + + /* + * Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL) + * ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME + * ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2 + */ + for (i = 0; i < 2; i++) + { + locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0); + if (locale_abbrev_size > 0) + { + GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size); + + locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL); + lang = pango_language_from_string (locale_abbrev); + if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL) + g_hash_table_insert (ht_scripts_langs, lang, langname); + + g_free (locale_abbrev); + } + } + + g_free (locale); + g_free (langname_w); + + return TRUE; +} + +#else /* non-Windows */ + static char * get_first_item_in_semicolon_list (const char *list) { @@ -210,6 +276,7 @@ languages_variant_init (const char *variant) g_free (filename); g_free (buf); } +#endif static void languages_init (void) @@ -218,8 +285,13 @@ languages_init (void) return; language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free); + +#ifdef G_OS_WIN32 + g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL)); +#else languages_variant_init ("iso_639"); languages_variant_init ("iso_639_3"); +#endif } const char * diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index 5b79dfad5f2cf746befa0062bd7b812f690348a3..5c84a0121d33b7d73a18cca26b28a310d5e59972 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -98,6 +98,7 @@ demos = files([ 'transparent.c', 'tree_store.c', 'video_player.c', + 'font_features.c', ]) gtkdemo_deps = [ libgtk_dep, ] @@ -128,14 +129,9 @@ extra_demo_sources = files([ 'script-names.c', 'unicode-names.c', 'suggestionentry.c', + 'language-names.c', ]) -if harfbuzz_dep.found() and pangoft_dep.found() - demos += files(['font_features.c']) - extra_demo_sources += files(['language-names.c']) - gtkdemo_deps += [ harfbuzz_dep, epoxy_dep ] -endif - if os_unix demos += files('pagesetup.c') endif diff --git a/gtk/language-names.c b/gtk/language-names.c index 16deef3bea725e3609875c7c40448fa900300c69..6dd2f22ec4813ec1ffa0ae68fff355dc7449c102 100644 --- a/gtk/language-names.c +++ b/gtk/language-names.c @@ -19,15 +19,80 @@ #include "language-names.h" +#ifdef G_OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else #ifndef ISO_CODES_PREFIX #define ISO_CODES_PREFIX "/usr" #endif #define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes" #define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale" +#endif static GHashTable *language_map; +#ifdef G_OS_WIN32 +/* if we are using native Windows use native Windows API for language names */ +static BOOL CALLBACK +get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param) +{ + wchar_t *langname_w = NULL; + wchar_t locale_abbrev_w[9]; + gchar *langname, *locale_abbrev, *locale, *p; + gint i; + const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 }; + GHashTable *ht_scripts_langs = (GHashTable *) param; + PangoLanguage *lang; + + gint langname_size, locale_abbrev_size; + langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0); + if (langname_size == 0) + return FALSE; + + langname_w = g_new0 (wchar_t, langname_size); + + if (langname_size == 0) + return FALSE; + + GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size); + langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL); + locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL); + p = strchr (locale, '-'); + lang = pango_language_from_string (locale); + if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL) + g_hash_table_insert (ht_scripts_langs, lang, langname); + + /* + * Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL) + * ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME + * ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2 + */ + for (i = 0; i < 2; i++) + { + locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0); + if (locale_abbrev_size > 0) + { + GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size); + + locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL); + lang = pango_language_from_string (locale_abbrev); + if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL) + g_hash_table_insert (ht_scripts_langs, lang, langname); + + g_free (locale_abbrev); + } + } + + g_free (locale); + g_free (langname_w); + + return TRUE; +} + +#else /* non-Windows */ + static char * get_first_item_in_semicolon_list (const char *list) { @@ -232,6 +297,8 @@ languages_variant_init (const char *variant) g_free (buf); } +#endif + static void languages_init (void) { @@ -239,8 +306,13 @@ languages_init (void) return; language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free); + +#ifdef G_OS_WIN32 + g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL)); +#else languages_variant_init ("iso_639"); languages_variant_init ("iso_639_3"); +#endif } const char * diff --git a/gtk/meson.build b/gtk/meson.build index 09a6e0bc84a08df7be18c2933b31f5342a0e3e61..9e012015227bcfeb8db3b575830a0415d5a26d60 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -1072,6 +1072,10 @@ gtk_gen_headers = [ gtkversion, ] +font_script_language_sources = files([ + 'language-names.c', +]) + gtk_sources += [ gtk_a11y_src, gtk_dbus_src, @@ -1081,6 +1085,7 @@ gtk_sources += [ gtkmarshalers, gtkprivatetypebuiltins, gtktypebuiltins, + font_script_language_sources, ] gtk_deps = [ @@ -1097,13 +1102,6 @@ gtk_deps = [ graphene_dep, ] -if harfbuzz_dep.found() and pangoft_dep.found() - gtk_deps += [ harfbuzz_dep, pangoft_dep ] - gtk_sources += files([ - 'language-names.c', - ]) -endif - if x11_enabled x11_data_prefix = dependency('x11').get_variable(pkgconfig: 'prefix') @@ -1151,6 +1149,9 @@ endif # So we don't add these twice if x11_enabled or wayland_enabled gtk_sources += gtk_use_wayland_or_x11_c_sources +endif + +if pangoft_dep.found() gtk_deps += pangoft_dep endif diff --git a/meson.build b/meson.build index 90619713d52de7524e580a172ef55ea0d360efcc..a40473c12add929f7fd9a87ce9b1e7256983b6b7 100644 --- a/meson.build +++ b/meson.build @@ -455,10 +455,12 @@ cdata.set('HAVE_TRACKER3', tracker3_dep.found()) colord_dep = dependency('colord', version: '>= 0.1.9', required: get_option('colord')) cdata.set('HAVE_COLORD', colord_dep.found()) -if iso_codes_dep.found() - cdata.set_quoted('ISO_CODES_PREFIX', iso_codes_dep.get_variable(pkgconfig: 'prefix')) -else - cdata.set_quoted('ISO_CODES_PREFIX', '/usr') +if not os_win32 + if iso_codes_dep.found() + cdata.set_quoted('ISO_CODES_PREFIX', iso_codes_dep.get_variable(pkgconfig: 'prefix')) + else + cdata.set_quoted('ISO_CODES_PREFIX', '/usr') + endif endif