diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2007-05-08 22:07:48 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2007-05-08 22:07:48 +0000 |
commit | 739f958f32661239d6a90914e3c1a8d0b3d54183 (patch) | |
tree | 8f83fff3acdb1ccc4b0f0634cd39fe95a1744c6c | |
parent | 6614ce538cdd6fa4f1c6423b9b27edb8220c205c (diff) | |
download | pango-739f958f32661239d6a90914e3c1a8d0b3d54183.tar.gz |
Move PangoLanguage stuff into pango-language.[ch]
2007-05-08 Behdad Esfahbod <behdad@gnome.org>
* pango/Makefile.am:
* pango/pango-script.h:
* pango/pango-types.h:
* pango/pango-utils.c:
* pango/pango-language.c:
* pango/pango-language.h:
Move PangoLanguage stuff into pango-language.[ch]
svn path=/trunk/; revision=2268
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | pango/Makefile.am | 2 | ||||
-rw-r--r-- | pango/pango-language.c | 382 | ||||
-rw-r--r-- | pango/pango-language.h | 48 | ||||
-rw-r--r-- | pango/pango-script.h | 4 | ||||
-rw-r--r-- | pango/pango-types.h | 21 | ||||
-rw-r--r-- | pango/pango-utils.c | 352 |
7 files changed, 446 insertions, 373 deletions
@@ -1,5 +1,15 @@ 2007-05-08 Behdad Esfahbod <behdad@gnome.org> + * pango/Makefile.am: + * pango/pango-script.h: + * pango/pango-types.h: + * pango/pango-utils.c: + * pango/pango-language.c: + * pango/pango-language.h: + Move PangoLanguage stuff into pango-language.[ch] + +2007-05-08 Behdad Esfahbod <behdad@gnome.org> + Bug 436988 – Adding PangoScript to PangoAnalysis * pango/pango-item.h: diff --git a/pango/Makefile.am b/pango/Makefile.am index fb97369e..78765a0c 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -80,6 +80,7 @@ libpango_1_0_la_SOURCES = \ pango-gravity.c \ pango-impl-utils.h \ pango-item.c \ + pango-language.c \ pango-layout.c \ pango-layout-private.h \ pango-markup.c \ @@ -109,6 +110,7 @@ pango_headers = \ pango-glyph-item.h \ pango-gravity.h \ pango-item.h \ + pango-language.h \ pango-layout.h \ pango-matrix.h \ pango-modules.h \ diff --git a/pango/pango-language.c b/pango/pango-language.c new file mode 100644 index 00000000..a5e32369 --- /dev/null +++ b/pango/pango-language.c @@ -0,0 +1,382 @@ +/* Pango + * pango-language.c: Language handling routines + * + * Copyright (C) 2000 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <config.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <locale.h> + +#include "pango-language.h" +#include "pango-impl-utils.h" + +static const char canon_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0, + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-', + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 +}; + +static gboolean +lang_equal (gconstpointer v1, + gconstpointer v2) +{ + const guchar *p1 = v1; + const guchar *p2 = v2; + + while (canon_map[*p1] && canon_map[*p1] == canon_map[*p2]) + { + p1++, p2++; + } + + return (canon_map[*p1] == canon_map[*p2]); +} + +static guint +lang_hash (gconstpointer key) +{ + const guchar *p = key; + guint h = 0; + while (canon_map[*p]) + { + h = (h << 5) - h + canon_map[*p]; + p++; + } + + return h; +} + +static PangoLanguage * +pango_language_copy (PangoLanguage *language) +{ + return language; /* language tags are const */ +} + +static void +pango_language_free (PangoLanguage *language) +{ + return; /* nothing */ +} + +GType +pango_language_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (I_("PangoLanguage"), + (GBoxedCopyFunc)pango_language_copy, + (GBoxedFreeFunc)pango_language_free); + return our_type; +} + +/** + * _pango_get_lc_ctype: + * + * Return the Unix-style locale string for the language currently in + * effect. On Unix systems, this is the return value from + * <literal>setlocale(LC_CTYPE, NULL)</literal>, and the user can + * affect this through the environment variables LC_ALL, LC_CTYPE or + * LANG (checked in that order). The locale strings typically is in + * the form lang_COUNTRY, where lang is an ISO-639 language code, and + * COUNTRY is an ISO-3166 country code. For instance, sv_FI for + * Swedish as written in Finland or pt_BR for Portuguese as written in + * Brazil. + * + * On Windows, the C library doesn't use any such environment + * variables, and setting them won't affect the behavior of functions + * like ctime(). The user sets the locale through the Regional Options + * in the Control Panel. The C library (in the setlocale() function) + * does not use country and language codes, but country and language + * names spelled out in English. + * However, this function does check the above environment + * variables, and does return a Unix-style locale string based on + * either said environment variables or the thread's current locale. + * + * Return value: a dynamically allocated string, free with g_free(). + */ +static gchar * +_pango_get_lc_ctype (void) +{ +#ifdef G_OS_WIN32 + /* Somebody might try to set the locale for this process using the + * LANG or LC_ environment variables. The Microsoft C library + * doesn't know anything about them. You set the locale in the + * Control Panel. Setting these env vars won't have any affect on + * locale-dependent C library functions like ctime(). But just for + * kicks, do obey LC_ALL, LC_CTYPE and LANG in Pango. (This also makes + * it easier to test GTK and Pango in various default languages, you + * don't have to clickety-click in the Control Panel, you can simply + * start the program with LC_ALL=something on the command line.) + */ + + gchar *p; + + p = getenv ("LC_ALL"); + if (p != NULL) + return g_strdup (p); + + p = getenv ("LC_CTYPE"); + if (p != NULL) + return g_strdup (p); + + p = getenv ("LANG"); + if (p != NULL) + return g_strdup (p); + + return g_win32_getlocale (); +#else + return g_strdup (setlocale (LC_CTYPE, NULL)); +#endif +} + +/** + * pango_language_get_default: + * + * Returns the #PangoLanguage for the current locale of the process. + * Note that this can change over the life of an application. + * + * On Unix systems, this is the return value is derived from + * <literal>setlocale(LC_CTYPE, NULL)</literal>, and the user can + * affect this through the environment variables LC_ALL, LC_CTYPE or + * LANG (checked in that order). The locale string typically is in + * the form lang_COUNTRY, where lang is an ISO-639 language code, and + * COUNTRY is an ISO-3166 country code. For instance, sv_FI for + * Swedish as written in Finland or pt_BR for Portuguese as written in + * Brazil. + * + * On Windows, the C library does not use any such environment + * variables, and setting them won't affect the behavior of functions + * like ctime(). The user sets the locale through the Regional Options + * in the Control Panel. The C library (in the setlocale() function) + * does not use country and language codes, but country and language + * names spelled out in English. + * However, this function does check the above environment + * variables, and does return a Unix-style locale string based on + * either said environment variables or the thread's current locale. + * + * Your application should call <literal>setlocale(LC_ALL, "");</literal> + * for the user settings to take effect. Gtk+ does this in its initialization + * functions automatically (by calling gtk_set_locale()). + * See <literal>man setlocale</literal> for more details. + * + * Return value: the default language as a #PangoLanguage, must not be + * freed. + * + * Since: 1.16 + **/ +PangoLanguage * +pango_language_get_default (void) +{ + gchar *lang; + PangoLanguage *result; + + lang = _pango_get_lc_ctype (); + + result = pango_language_from_string (lang); + g_free (lang); + + return result; +} + +/** + * pango_language_from_string: + * @language: a string representing a language tag + * + * Take a RFC-3066 format language tag as a string and convert it to a + * #PangoLanguage pointer that can be efficiently copied (copy the + * pointer) and compared with other language tags (compare the + * pointer.) + * + * This function first canonicalizes the string by converting it to + * lowercase, mapping '_' to '-', and stripping all characters other + * than letters and '-'. + * + * Use pango_language_get_default() if you want to get the #PangoLanguage for + * the current locale of the process. + * + * Return value: an opaque pointer to a #PangoLanguage structure. + * this will be valid forever after. + **/ +PangoLanguage * +pango_language_from_string (const char *language) +{ + static GHashTable *hash = NULL; + char *result; + int len; + char *p; + + if (G_UNLIKELY (!hash)) + hash = g_hash_table_new (lang_hash, lang_equal); + else + { + result = g_hash_table_lookup (hash, language); + if (result) + return (PangoLanguage *)result; + } + + len = strlen (language); + result = g_malloc (len + 1); + + p = result; + while ((*(p++) = canon_map[*(guchar *)language++])) + ; + + g_hash_table_insert (hash, result, result); + + return (PangoLanguage *)result; +} + +/** + * pango_language_matches: + * @language: a language tag (see pango_language_from_string()), + * %NULL is allowed and matches nothing but '*' + * @range_list: a list of language ranges, separated by ';', ':', + * ',', or space characters. + * Each element must either be '*', or a RFC 3066 language range + * canonicalized as by pango_language_from_string() + * + * Checks if a language tag matches one of the elements in a list of + * language ranges. A language tag is considered to match a range + * in the list if the range is '*', the range is exactly the tag, + * or the range is a prefix of the tag, and the character after it + * in the tag is '-'. + * + * Return value: %TRUE if a match was found. + **/ +gboolean +pango_language_matches (PangoLanguage *language, + const char *range_list) +{ + const char *lang_str = pango_language_to_string (language); + const char *p = range_list; + gboolean done = FALSE; + + while (!done) + { + const char *end = strpbrk (p, ";:, \t"); + if (!end) + { + end = p + strlen (p); + done = TRUE; + } + + if (strncmp (p, "*", 1) == 0 || + (lang_str && strncmp (lang_str, p, end - p) == 0 && + (lang_str[end - p] == '\0' || lang_str[end - p] == '-'))) + return TRUE; + + if (!done) + p = end + 1; + } + + return FALSE; +} + +typedef struct { + const char lang[4]; + const char *str; +} LangInfo; + +static int +lang_info_compare (const void *key, const void *val) +{ + const LangInfo *lang_info = val; + + return strncmp (key, lang_info->lang, 2); +} + +/* The following array is supposed to contain enough text to tickle all necessary fonts for each + * of the languages in the following. Yes, it's pretty lame. Not all of the languages + * in the following have sufficient text to exercise all the accents for the language, and + * there are obviously many more languages to include as well. + */ +static const LangInfo lang_texts[] = { + { "ar", "Arabic \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205" }, + { "cs", "Czech (\304\215esky) Dobr\303\275 den" }, + { "da", "Danish (Dansk) Hej, Goddag" }, + { "el", "Greek (\316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254) \316\223\316\265\316\271\316\254 \317\203\316\261\317\202" }, + { "en", "English Hello" }, + { "eo", "Esperanto Saluton" }, + { "es", "Spanish (Espa\303\261ol) \302\241Hola!" }, + { "et", "Estonian Tere, Tervist" }, + { "fi", "Finnish (Suomi) Hei, Hyv\303\244\303\244 p\303\244iv\303\244\303\244" }, + { "fr", "French (Fran\303\247ais)" }, + { "de", "German Gr\303\274\303\237 Gott" }, + { "he", "Hebrew \327\251\327\234\327\225\327\235" }, + { "it", "Italiano Ciao, Buon giorno" }, + { "ja", "Japanese (\346\227\245\346\234\254\350\252\236) \343\201\223\343\202\223\343\201\253\343\201\241\343\201\257, \357\275\272\357\276\235\357\276\206\357\276\201\357\276\212" }, + { "ko", "Korean (\355\225\234\352\270\200) \354\225\210\353\205\225\355\225\230\354\204\270\354\232\224, \354\225\210\353\205\225\355\225\230\354\213\255\353\213\210\352\271\214" }, + { "mt", "Maltese \304\212aw, Sa\304\247\304\247a" }, + { "nl", "Nederlands, Vlaams Hallo, Dag" }, + { "no", "Norwegian (Norsk) Hei, God dag" }, + { "pl", "Polish Dzie\305\204 dobry, Hej" }, + { "ru", "Russian (\320\240\321\203\321\201\321\201\320\272\320\270\320\271)" }, + { "sk", "Slovak Dobr\303\275 de\305\210" }, + { "sv", "Swedish (Svenska) Hej p\303\245 dej, Goddag" }, + { "tr", "Turkish (T\303\274rk\303\247e) Merhaba" }, + { "zh", "Chinese (\344\270\255\346\226\207,\346\231\256\351\200\232\350\257\235,\346\261\211\350\257\255)" } +}; + +/** + * pango_language_get_sample_string: + * @language: a #PangoLanguage + * + * Get a string that is representative of the characters needed to + * render a particular language. This function is a bad hack for + * internal use by renderers and Pango. + * + * Return value: the sample string. This value is owned by Pango + * and must not be freed. + **/ +G_CONST_RETURN char * +pango_language_get_sample_string (PangoLanguage *language) +{ + const char *result; + + if (language) + { + const char *lang_str = pango_language_to_string (language); + + LangInfo *lang_info = bsearch (lang_str, lang_texts, + G_N_ELEMENTS (lang_texts), sizeof (LangInfo), + lang_info_compare); + + if (lang_info) + result = lang_info->str; + else + result = "French (Fran\303\247ais)"; /* Assume iso-8859-1 */ + } + else + { + /* Complete junk + */ + + result = "\330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \304\215esky \316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254 Fran\303\247ais \346\227\245\346\234\254\350\252\236 \355\225\234\352\270\200 \320\240\321\203\321\201\321\201\320\272\320\270\320\271 \344\270\255\346\226\207,\346\231\256\351\200\232\350\257\235,\346\261\211\350\257\255 T\303\274rk\303\247e"; + } + + return result; +} diff --git a/pango/pango-language.h b/pango/pango-language.h new file mode 100644 index 00000000..afd50452 --- /dev/null +++ b/pango/pango-language.h @@ -0,0 +1,48 @@ +/* Pango + * pango-language.h: Language handling routines + * + * Copyright (C) 1999 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGO_LANGUAGE_H__ +#define __PANGO_LANGUAGE_H__ + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +/* Dummy typedef - internally it's a 'const char *' */ +typedef struct _PangoLanguage PangoLanguage; + +#define PANGO_TYPE_LANGUAGE (pango_language_get_type ()) + +GType pango_language_get_type (void); +PangoLanguage *pango_language_from_string (const char *language); + +#define pango_language_to_string(language) ((const char *)language) + +G_CONST_RETURN char *pango_language_get_sample_string (PangoLanguage *language); +PangoLanguage *pango_language_get_default (void); + +gboolean pango_language_matches (PangoLanguage *language, + const char *range_list); + +G_END_DECLS + +#endif /* __PANGO_LANGUAGE_H__ */ diff --git a/pango/pango-script.h b/pango/pango-script.h index 394354b5..7068b55c 100644 --- a/pango/pango-script.h +++ b/pango/pango-script.h @@ -24,6 +24,8 @@ #include <glib.h> +#include <pango/pango-language.h> + G_BEGIN_DECLS /** @@ -111,8 +113,6 @@ typedef enum { /* ISO 15924 code */ PANGO_SCRIPT_NKO /* Nkoo */ } PangoScript; -#include <pango/pango-types.h> - PangoScript pango_script_for_unichar (gunichar ch); PangoScriptIter *pango_script_iter_new (const char *text, diff --git a/pango/pango-types.h b/pango/pango-types.h index 1b08f8ff..642a06c6 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -65,23 +65,6 @@ int pango_units_from_double (double d) G_GNUC_CONST; double pango_units_to_double (int i) G_GNUC_CONST; -/* Dummy typedef - internally it's a 'const char *' */ -typedef struct _PangoLanguage PangoLanguage; - -#define PANGO_TYPE_LANGUAGE (pango_language_get_type ()) - -GType pango_language_get_type (void); -PangoLanguage *pango_language_from_string (const char *language); - -#define pango_language_to_string(language) ((const char *)language) - -G_CONST_RETURN char *pango_language_get_sample_string (PangoLanguage *language); -PangoLanguage *pango_language_get_default (void); - -gboolean pango_language_matches (PangoLanguage *language, - const char *range_list); - - /* A rectangle. Used to store logical and physical extents of glyphs, * runs, strings, etc. @@ -152,12 +135,12 @@ gboolean pango_get_mirror_char (gunichar ch, #endif +#include <pango/pango-gravity.h> +#include <pango/pango-language.h> #include <pango/pango-matrix.h> #include <pango/pango-script.h> -#include <pango/pango-gravity.h> G_END_DECLS #endif /* __PANGO_TYPES_H__ */ - diff --git a/pango/pango-utils.c b/pango/pango-utils.c index 46c18e52..39ade732 100644 --- a/pango/pango-utils.c +++ b/pango/pango-utils.c @@ -1090,358 +1090,6 @@ pango_parse_stretch (const char *str, return FALSE; } -static const char canon_map[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0, - 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-', - 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 -}; - -static gboolean -lang_equal (gconstpointer v1, - gconstpointer v2) -{ - const guchar *p1 = v1; - const guchar *p2 = v2; - - while (canon_map[*p1] && canon_map[*p1] == canon_map[*p2]) - { - p1++, p2++; - } - - return (canon_map[*p1] == canon_map[*p2]); -} - -static guint -lang_hash (gconstpointer key) -{ - const guchar *p = key; - guint h = 0; - while (canon_map[*p]) - { - h = (h << 5) - h + canon_map[*p]; - p++; - } - - return h; -} - -static PangoLanguage * -pango_language_copy (PangoLanguage *language) -{ - return language; /* language tags are const */ -} - -static void -pango_language_free (PangoLanguage *language) -{ - return; /* nothing */ -} - -GType -pango_language_get_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static (I_("PangoLanguage"), - (GBoxedCopyFunc)pango_language_copy, - (GBoxedFreeFunc)pango_language_free); - return our_type; -} - -/** - * _pango_get_lc_ctype: - * - * Return the Unix-style locale string for the language currently in - * effect. On Unix systems, this is the return value from - * <literal>setlocale(LC_CTYPE, NULL)</literal>, and the user can - * affect this through the environment variables LC_ALL, LC_CTYPE or - * LANG (checked in that order). The locale strings typically is in - * the form lang_COUNTRY, where lang is an ISO-639 language code, and - * COUNTRY is an ISO-3166 country code. For instance, sv_FI for - * Swedish as written in Finland or pt_BR for Portuguese as written in - * Brazil. - * - * On Windows, the C library doesn't use any such environment - * variables, and setting them won't affect the behavior of functions - * like ctime(). The user sets the locale through the Regional Options - * in the Control Panel. The C library (in the setlocale() function) - * does not use country and language codes, but country and language - * names spelled out in English. - * However, this function does check the above environment - * variables, and does return a Unix-style locale string based on - * either said environment variables or the thread's current locale. - * - * Return value: a dynamically allocated string, free with g_free(). - */ -static gchar * -_pango_get_lc_ctype (void) -{ -#ifdef G_OS_WIN32 - /* Somebody might try to set the locale for this process using the - * LANG or LC_ environment variables. The Microsoft C library - * doesn't know anything about them. You set the locale in the - * Control Panel. Setting these env vars won't have any affect on - * locale-dependent C library functions like ctime(). But just for - * kicks, do obey LC_ALL, LC_CTYPE and LANG in Pango. (This also makes - * it easier to test GTK and Pango in various default languages, you - * don't have to clickety-click in the Control Panel, you can simply - * start the program with LC_ALL=something on the command line.) - */ - - gchar *p; - - p = getenv ("LC_ALL"); - if (p != NULL) - return g_strdup (p); - - p = getenv ("LC_CTYPE"); - if (p != NULL) - return g_strdup (p); - - p = getenv ("LANG"); - if (p != NULL) - return g_strdup (p); - - return g_win32_getlocale (); -#else - return g_strdup (setlocale (LC_CTYPE, NULL)); -#endif -} - -/** - * pango_language_get_default: - * - * Returns the #PangoLanguage for the current locale of the process. - * Note that this can change over the life of an application. - * - * On Unix systems, this is the return value is derived from - * <literal>setlocale(LC_CTYPE, NULL)</literal>, and the user can - * affect this through the environment variables LC_ALL, LC_CTYPE or - * LANG (checked in that order). The locale string typically is in - * the form lang_COUNTRY, where lang is an ISO-639 language code, and - * COUNTRY is an ISO-3166 country code. For instance, sv_FI for - * Swedish as written in Finland or pt_BR for Portuguese as written in - * Brazil. - * - * On Windows, the C library does not use any such environment - * variables, and setting them won't affect the behavior of functions - * like ctime(). The user sets the locale through the Regional Options - * in the Control Panel. The C library (in the setlocale() function) - * does not use country and language codes, but country and language - * names spelled out in English. - * However, this function does check the above environment - * variables, and does return a Unix-style locale string based on - * either said environment variables or the thread's current locale. - * - * Your application should call <literal>setlocale(LC_ALL, "");</literal> - * for the user settings to take effect. Gtk+ does this in its initialization - * functions automatically (by calling gtk_set_locale()). - * See <literal>man setlocale</literal> for more details. - * - * Return value: the default language as a #PangoLanguage, must not be - * freed. - * - * Since: 1.16 - **/ -PangoLanguage * -pango_language_get_default (void) -{ - gchar *lang; - PangoLanguage *result; - - lang = _pango_get_lc_ctype (); - - result = pango_language_from_string (lang); - g_free (lang); - - return result; -} - -/** - * pango_language_from_string: - * @language: a string representing a language tag - * - * Take a RFC-3066 format language tag as a string and convert it to a - * #PangoLanguage pointer that can be efficiently copied (copy the - * pointer) and compared with other language tags (compare the - * pointer.) - * - * This function first canonicalizes the string by converting it to - * lowercase, mapping '_' to '-', and stripping all characters other - * than letters and '-'. - * - * Use pango_language_get_default() if you want to get the #PangoLanguage for - * the current locale of the process. - * - * Return value: an opaque pointer to a #PangoLanguage structure. - * this will be valid forever after. - **/ -PangoLanguage * -pango_language_from_string (const char *language) -{ - static GHashTable *hash = NULL; - char *result; - int len; - char *p; - - if (G_UNLIKELY (!hash)) - hash = g_hash_table_new (lang_hash, lang_equal); - else - { - result = g_hash_table_lookup (hash, language); - if (result) - return (PangoLanguage *)result; - } - - len = strlen (language); - result = g_malloc (len + 1); - - p = result; - while ((*(p++) = canon_map[*(guchar *)language++])) - ; - - g_hash_table_insert (hash, result, result); - - return (PangoLanguage *)result; -} - -/** - * pango_language_matches: - * @language: a language tag (see pango_language_from_string()), - * %NULL is allowed and matches nothing but '*' - * @range_list: a list of language ranges, separated by ';', ':', - * ',', or space characters. - * Each element must either be '*', or a RFC 3066 language range - * canonicalized as by pango_language_from_string() - * - * Checks if a language tag matches one of the elements in a list of - * language ranges. A language tag is considered to match a range - * in the list if the range is '*', the range is exactly the tag, - * or the range is a prefix of the tag, and the character after it - * in the tag is '-'. - * - * Return value: %TRUE if a match was found. - **/ -gboolean -pango_language_matches (PangoLanguage *language, - const char *range_list) -{ - const char *lang_str = pango_language_to_string (language); - const char *p = range_list; - gboolean done = FALSE; - - while (!done) - { - const char *end = strpbrk (p, ";:, \t"); - if (!end) - { - end = p + strlen (p); - done = TRUE; - } - - if (strncmp (p, "*", 1) == 0 || - (lang_str && strncmp (lang_str, p, end - p) == 0 && - (lang_str[end - p] == '\0' || lang_str[end - p] == '-'))) - return TRUE; - - if (!done) - p = end + 1; - } - - return FALSE; -} - -typedef struct { - const char lang[4]; - const char *str; -} LangInfo; - -static int -lang_info_compare (const void *key, const void *val) -{ - const LangInfo *lang_info = val; - - return strncmp (key, lang_info->lang, 2); -} - -/* The following array is supposed to contain enough text to tickle all necessary fonts for each - * of the languages in the following. Yes, it's pretty lame. Not all of the languages - * in the following have sufficient text to exercise all the accents for the language, and - * there are obviously many more languages to include as well. - */ -static const LangInfo lang_texts[] = { - { "ar", "Arabic \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205" }, - { "cs", "Czech (\304\215esky) Dobr\303\275 den" }, - { "da", "Danish (Dansk) Hej, Goddag" }, - { "el", "Greek (\316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254) \316\223\316\265\316\271\316\254 \317\203\316\261\317\202" }, - { "en", "English Hello" }, - { "eo", "Esperanto Saluton" }, - { "es", "Spanish (Espa\303\261ol) \302\241Hola!" }, - { "et", "Estonian Tere, Tervist" }, - { "fi", "Finnish (Suomi) Hei, Hyv\303\244\303\244 p\303\244iv\303\244\303\244" }, - { "fr", "French (Fran\303\247ais)" }, - { "de", "German Gr\303\274\303\237 Gott" }, - { "he", "Hebrew \327\251\327\234\327\225\327\235" }, - { "it", "Italiano Ciao, Buon giorno" }, - { "ja", "Japanese (\346\227\245\346\234\254\350\252\236) \343\201\223\343\202\223\343\201\253\343\201\241\343\201\257, \357\275\272\357\276\235\357\276\206\357\276\201\357\276\212" }, - { "ko", "Korean (\355\225\234\352\270\200) \354\225\210\353\205\225\355\225\230\354\204\270\354\232\224, \354\225\210\353\205\225\355\225\230\354\213\255\353\213\210\352\271\214" }, - { "mt", "Maltese \304\212aw, Sa\304\247\304\247a" }, - { "nl", "Nederlands, Vlaams Hallo, Dag" }, - { "no", "Norwegian (Norsk) Hei, God dag" }, - { "pl", "Polish Dzie\305\204 dobry, Hej" }, - { "ru", "Russian (\320\240\321\203\321\201\321\201\320\272\320\270\320\271)" }, - { "sk", "Slovak Dobr\303\275 de\305\210" }, - { "sv", "Swedish (Svenska) Hej p\303\245 dej, Goddag" }, - { "tr", "Turkish (T\303\274rk\303\247e) Merhaba" }, - { "zh", "Chinese (\344\270\255\346\226\207,\346\231\256\351\200\232\350\257\235,\346\261\211\350\257\255)" } -}; - -/** - * pango_language_get_sample_string: - * @language: a #PangoLanguage - * - * Get a string that is representative of the characters needed to - * render a particular language. This function is a bad hack for - * internal use by renderers and Pango. - * - * Return value: the sample string. This value is owned by Pango - * and must not be freed. - **/ -G_CONST_RETURN char * -pango_language_get_sample_string (PangoLanguage *language) -{ - const char *result; - - if (language) - { - const char *lang_str = pango_language_to_string (language); - - LangInfo *lang_info = bsearch (lang_str, lang_texts, - G_N_ELEMENTS (lang_texts), sizeof (LangInfo), - lang_info_compare); - - if (lang_info) - result = lang_info->str; - else - result = "French (Fran\303\247ais)"; /* Assume iso-8859-1 */ - } - else - { - /* Complete junk - */ - - result = "\330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \304\215esky \316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254 Fran\303\247ais \346\227\245\346\234\254\350\252\236 \355\225\234\352\270\200 \320\240\321\203\321\201\321\201\320\272\320\270\320\271 \344\270\255\346\226\207,\346\231\256\351\200\232\350\257\235,\346\261\211\350\257\255 T\303\274rk\303\247e"; - } - - return result; -} - /** * pango_log2vis_get_embedding_levels: * @text: the text to itemize. |