diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/break.c | 4 | ||||
-rw-r--r-- | pango/fonts.c | 31 | ||||
-rw-r--r-- | pango/itemize.c | 232 | ||||
-rw-r--r-- | pango/modules.c | 29 | ||||
-rw-r--r-- | pango/pango-attributes.c | 85 | ||||
-rw-r--r-- | pango/pango-attributes.h | 12 | ||||
-rw-r--r-- | pango/pango-break.h | 2 | ||||
-rw-r--r-- | pango/pango-context.c | 167 | ||||
-rw-r--r-- | pango/pango-context.h | 19 | ||||
-rw-r--r-- | pango/pango-engine.h | 2 | ||||
-rw-r--r-- | pango/pango-font.h | 12 | ||||
-rw-r--r-- | pango/pango-item.c | 20 | ||||
-rw-r--r-- | pango/pango-item.h | 5 | ||||
-rw-r--r-- | pango/pango-layout.c | 22 | ||||
-rw-r--r-- | pango/pango-markup.c | 3 | ||||
-rw-r--r-- | pango/pango-modules.h | 2 | ||||
-rw-r--r-- | pango/pango-types.h | 16 | ||||
-rw-r--r-- | pango/pango-utils.c | 143 | ||||
-rw-r--r-- | pango/pango-utils.h | 2 | ||||
-rw-r--r-- | pango/pangoft2-fontmap.c | 13 | ||||
-rw-r--r-- | pango/pangoft2-private.h | 4 | ||||
-rw-r--r-- | pango/pangoft2.c | 60 | ||||
-rw-r--r-- | pango/pangoft2.h | 18 | ||||
-rw-r--r-- | pango/pangox-fontmap.c | 10 | ||||
-rw-r--r-- | pango/pangox-private.h | 4 | ||||
-rw-r--r-- | pango/pangox.c | 55 |
26 files changed, 456 insertions, 516 deletions
diff --git a/pango/break.c b/pango/break.c index baf1ed86..de898895 100644 --- a/pango/break.c +++ b/pango/break.c @@ -1376,7 +1376,7 @@ pango_find_paragraph_boundary (const gchar *text, * @text: text to process * @length: length in bytes of @text * @level: embedding level, or -1 if unknown - * @language: language code + * @language: language tag * @log_attrs: array with one PangoLogAttr per character in @text, to be filled in * * Computes a PangoLogAttr for each character in @text @@ -1385,7 +1385,7 @@ void pango_get_log_attrs (const char *text, int length, int level, - const char *language, + PangoLanguage *language, PangoLogAttr *log_attrs) { int n_chars; diff --git a/pango/fonts.c b/pango/fonts.c index c8d58201..606da183 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -27,6 +27,7 @@ #include "pango-types.h" #include "pango-font.h" #include "pango-fontmap.h" +#include "pango-utils.h" /** * pango_font_description_copy: @@ -443,25 +444,25 @@ pango_font_describe (PangoFont *font) /** * pango_font_get_coverage: * @font: a #PangoFont - * @lang: the language tag (in the form of "en_US") + * @lang: the language tag * * Compute the coverage map for a given font and language tag. * * Return value: a newly allocated #PangoContext object. **/ PangoCoverage * -pango_font_get_coverage (PangoFont *font, - const char *lang) +pango_font_get_coverage (PangoFont *font, + PangoLanguage *language) { g_return_val_if_fail (font != NULL, NULL); - return PANGO_FONT_GET_CLASS (font)->get_coverage (font, lang); + return PANGO_FONT_GET_CLASS (font)->get_coverage (font, language); } /** * pango_font_find_shaper: * @font: a #PangoFont - * @lang: the language tag (in the form of "en_US") + * @language: the language tag * @ch: the ISO-10646 character code. * * Find the best matching shaper for a font for a particular @@ -470,15 +471,15 @@ pango_font_get_coverage (PangoFont *font, * Return value: the best matching shaper. **/ PangoEngineShape * -pango_font_find_shaper (PangoFont *font, - const char *lang, - guint32 ch) +pango_font_find_shaper (PangoFont *font, + PangoLanguage *language, + guint32 ch) { PangoEngineShape* shaper; g_return_val_if_fail (font != NULL, NULL); - shaper = PANGO_FONT_GET_CLASS (font)->find_shaper (font, lang, ch); + shaper = PANGO_FONT_GET_CLASS (font)->find_shaper (font, language, ch); return shaper; } @@ -514,9 +515,9 @@ pango_font_get_glyph_extents (PangoFont *font, /** * pango_font_get_metrics: * @font: a #PangoFont - * @lang: language tag used to determine which script to get the metrics - * for, or %NULL to indicate to get the metrics for the entire - * font. + * @language: language tag used to determine which script to get the metrics + * for, or %NULL to indicate to get the metrics for the entire + * font. * @metrics: Structure to fill in with the metrics of the font * * Get overall metric information for a font. Since the metrics may be @@ -527,10 +528,8 @@ pango_font_get_glyph_extents (PangoFont *font, void pango_font_get_metrics (PangoFont *font, - const gchar *lang, + PangoLanguage *language, PangoFontMetrics *metrics) { - g_return_if_fail (font != NULL); - - PANGO_FONT_GET_CLASS (font)->get_metrics (font, lang, metrics); + PANGO_FONT_GET_CLASS (font)->get_metrics (font, language, metrics); } diff --git a/pango/itemize.c b/pango/itemize.c deleted file mode 100644 index b50101c4..00000000 --- a/pango/itemize.c +++ /dev/null @@ -1,232 +0,0 @@ -/* Pango - * itemize.c: - * - * 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. - */ - -#include "pango-context.h" -#include "modules.h" - -static void add_engines (PangoContext *context, - gchar *text, - gint length, - PangoLangRange *lang_info, - gint n_langs, - gboolean force_exact, - PangoEngineInfo **shape_engines, - PangoEngineInfo **lang_engines); - -/** - * pango_itemize: - * @context: a structure holding information that affects - the itemization process. - * @text: the text to itemize. - * @length: the number of bytes (not characters) in text. - * This must be >= 0. - * @lang_info: an array of language tagging information. - * @n_langs: the number of elements in @lang_info. - * - * Breaks a piece of text into segments with consistent - * directional level and shaping engine. - * - * Returns a GList of PangoItem structures. - */ -GList * -pango_itemize (PangoContext *context, - gchar *text, - gint length, - PangoLangRange *lang_info, - gint n_langs) -{ - guint16 *text_ucs2; - gint n_chars; - guint8 *embedding_levels; - FriBidiCharType base_dir; - gint i; - PangoItem *item; - char *p, *next; - GList *result = NULL; - - PangoEngineInfo **shape_engines; - PangoEngineInfo **lang_engines; - - g_return_val_if_fail (context != NULL, NULL); - g_return_val_if_fail (length == 0 || text != NULL, NULL); - - if (length == 0) - return NULL; - - if (context->direction == PANGO_DIRECTION_RTL) - base_dir = FRIBIDI_TYPE_RTL; - else - base_dir = FRIBIDI_TYPE_LTR; - - if (length == 0) - return NULL; - - /* First, apply the bidirectional algorithm to break - * the text into directional runs. - */ - text_ucs2 = _pango_utf8_to_ucs2 (text, length); - if (!text_ucs2) - return NULL; - - n_chars = g_utf8_strlen (text, length); - embedding_levels = g_new (guint8, n_chars); - - /* Storing these as ranges would be a lot more efficient, - * but also more complicated... we take the simple - * approach for now. - */ - shape_engines = g_new0 (PangoEngineInfo *, n_chars); - lang_engines = g_new0 (PangoEngineInfo *, n_chars); - - pango_log2vis_get_embedding_levels (text_ucs2, n_chars, &base_dir, - embedding_levels); - - /* Now, make shaping-engine affilitations for characters in - * each run that have high-affinity. This means that there - * is a shaping engine specific to the current - * language/character pair. - */ - - add_engines (context, text, length, lang_info, n_langs, - TRUE, shape_engines, lang_engines); - - /* Fill in low-affinity shaping-engine affiliations for - * remainder of characters. - */ - - add_engines (context, text, length, lang_info, n_langs, - FALSE, shape_engines, lang_engines); - - /* Make a GList of PangoItems out of the above results - */ - - item = NULL; - p = text; - for (i=0; i<n_chars; i++) - { - next = g_utf8_next_char (p); - - if (i == 0 || - embedding_levels[i] != embedding_levels[i-1] || - shape_engines[i] != shape_engines[i-1] || - lang_engines[i] != lang_engines[i-1]) - { - if (item) - result = g_list_prepend (result, item); - item = pango_item_new (); - item->offset = p - text; - item->num_chars = 0; - item->analysis.level = embedding_levels[i]; - - if (shape_engines[i]) - item->analysis.shape_engine = (PangoEngineShape *)_pango_load_engine (shape_engines[i]->id); - else - item->analysis.shape_engine = NULL; - - if (lang_engines[i]) - item->analysis.lang_engine = (PangoEngineLang *)_pango_load_engine (lang_engines[i]->id); - else - item->analysis.lang_engine = NULL; - } - - item->length = (next - text) - item->offset; - item->num_chars++; - p = next; - } - - if (item) - result = g_list_prepend (result, item); - - g_free (text_ucs2); - - return g_list_reverse (result); -} - -static void -add_engines (PangoContext *context, - gchar *text, - gint length, - PangoLangRange *lang_info, - gint n_langs, - gboolean force_exact, - PangoEngineInfo **shape_engines, - PangoEngineInfo **lang_engines) -{ - char *pos; - char *last_lang = NULL; - gint n_chars; - PangoMap *shape_map = NULL; - PangoMap *lang_map = NULL; - GUChar4 wc; - int i, j; - - n_chars = g_utf8_strlen (text, length); - - pos = text; - last_lang = NULL; - for (i=0, j=0; i<n_chars; i++) - { - char *lang; - PangoSubmap *submap; - PangoMapEntry *entry; - - while (j < n_langs && lang_info[j].start < pos - text) - j++; - - if (j < n_langs && (pos - text) < lang_info[j].start + lang_info[j].length) - lang = lang_info[j].lang; - else - lang = context->lang; - - if (last_lang != lang && - (last_lang == 0 || lang == 0 || - strcmp (lang, last_lang) != 0)) - { - lang_map = pango_find_map (lang, PANGO_ENGINE_TYPE_LANG, - PANGO_RENDER_TYPE_NONE); - shape_map = pango_find_map (lang, PANGO_ENGINE_TYPE_SHAPE, - context->render_type); - last_lang = lang; - } - - wc = g_utf8_get_char (pos); - pos = g_utf8_next_char (pos); - - if (!lang_engines[i]) - { - submap = &lang_map->submaps[wc / 256]; - entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256]; - - if (entry->info && (!force_exact || entry->is_exact)) - lang_engines[i] = entry->info; - } - - if (!shape_engines[i]) - { - submap = &shape_map->submaps[wc / 256]; - entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256]; - - if (entry->info && (!force_exact || entry->is_exact)) - shape_engines[i] = entry->info; - } - } -} - diff --git a/pango/modules.c b/pango/modules.c index 3b2daba1..4f235452 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -53,7 +53,7 @@ struct _PangoMap struct _PangoMapInfo { - const gchar *lang; + PangoLanguage *language; guint engine_type_id; guint render_type_id; PangoMap *map; @@ -78,8 +78,7 @@ static void init_modules (void); /** * pango_find_map: - * @lang: the language tag for which to find the map (in the form - * en or en_US) + * @language: the language tag for which to find the map * @engine_type_id: the render type for the map to find * @render_type_id: the engine type for the map to find * @@ -90,9 +89,9 @@ static void init_modules (void); * Return value: **/ PangoMap * -pango_find_map (const char *lang, - guint engine_type_id, - guint render_type_id) +pango_find_map (PangoLanguage *language, + guint engine_type_id, + guint render_type_id) { GList *tmp_list = maps; PangoMapInfo *map_info = NULL; @@ -104,7 +103,7 @@ pango_find_map (const char *lang, if (map_info->engine_type_id == engine_type_id && map_info->render_type_id == render_type_id) { - if (strcmp (map_info->lang, lang) == 0) + if (map_info->language == language) break; else found_earlier = TRUE; @@ -116,7 +115,7 @@ pango_find_map (const char *lang, if (!tmp_list) { map_info = g_new (PangoMapInfo, 1); - map_info->lang = g_strdup (lang); + map_info->language = language; map_info->engine_type_id = engine_type_id; map_info->render_type_id = render_type_id; @@ -394,20 +393,12 @@ map_add_engine (PangoMapInfo *info, for (i=0; i<pair->info.n_ranges; i++) { - gchar **langs; gboolean is_exact = FALSE; - + if (pair->info.ranges[i].langs) { - langs = g_strsplit (pair->info.ranges[i].langs, ";", -1); - for (j=0; langs[j]; j++) - if (strcmp (langs[j], "*") == 0 || - strcmp (langs[j], info->lang) == 0) - { - is_exact = TRUE; - break; - } - g_strfreev (langs); + if (pango_language_matches (info->language, pair->info.ranges[i].langs)) + is_exact = TRUE; } for (submap = pair->info.ranges[i].start / 256; diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 6d5d5b90..b1748b88 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -1,4 +1,4 @@ -/* Pango +/* pango * pango-attributes.c: Attributed text * * Copyright (C) 2000 Red Hat Software @@ -21,7 +21,8 @@ #include <string.h> -#include <pango/pango-attributes.h> +#include "pango-attributes.h" +#include "pango-utils.h" struct _PangoAttrList { @@ -159,49 +160,75 @@ pango_attr_string_new (const PangoAttrClass *klass, } /** - * pango_attr_lang_new: - * @lang: language tag (in the form "en_US") + * pango_attr_family_new: + * @family: the family or comma separated list of families * - * Create a new language tag attribute. + * Create a new font family attribute. * * Return value: the new #PangoAttribute. **/ PangoAttribute * -pango_attr_lang_new (const char *lang) +pango_attr_family_new (const char *family) { static const PangoAttrClass klass = { - PANGO_ATTR_LANG, + PANGO_ATTR_FAMILY, pango_attr_string_copy, pango_attr_string_destroy, pango_attr_string_equal }; - g_return_val_if_fail (lang != NULL, NULL); + g_return_val_if_fail (family != NULL, NULL); - return pango_attr_string_new (&klass, lang); + return pango_attr_string_new (&klass, family); +} + +static PangoAttribute * +pango_attr_language_copy (const PangoAttribute *attr) +{ + return g_memdup (attr, sizeof (PangoAttrLanguage)); +} + +static void +pango_attr_language_destroy (PangoAttribute *attr) +{ + g_free (attr); +} + +static gboolean +pango_attr_language_equal (const PangoAttribute *attr1, + const PangoAttribute *attr2) +{ + return ((PangoAttrLanguage *)attr1)->value == ((PangoAttrLanguage *)attr2)->value; } /** - * pango_attr_family_new: - * @family: the family or comma separated list of families + * pango_attr_language_new: + * @language: language tag * - * Create a new font family attribute. + * Create a new language tag attribute. * * Return value: the new #PangoAttribute. **/ PangoAttribute * -pango_attr_family_new (const char *family) +pango_attr_language_new (PangoLanguage *language) { + PangoAttrLanguage *result; + static const PangoAttrClass klass = { - PANGO_ATTR_FAMILY, - pango_attr_string_copy, - pango_attr_string_destroy, - pango_attr_string_equal + PANGO_ATTR_LANGUAGE, + pango_attr_language_copy, + pango_attr_language_destroy, + pango_attr_language_equal }; - g_return_val_if_fail (family != NULL, NULL); + g_return_val_if_fail (language != NULL, NULL); - return pango_attr_string_new (&klass, family); + result = g_new (PangoAttrLanguage, 1); + + result->attr.klass = &klass; + result->value = language; + + return (PangoAttribute *)result; } static PangoAttribute * @@ -1346,18 +1373,21 @@ pango_attr_iterator_get (PangoAttrIterator *iterator, * an attribute in the #PangoAttrList associated with the structure, * or with @base. If you want to save this value, you should * allocate it on the stack and then use pango_font_description_copy(). + * @language: if non-%NULl, location to store language tag for item, or %NULL + * if non is found. * @extra_attrs: if non-%NULL, location in which to store a list of non-font * attributes at the the current position; only the highest priority * value of each attribute will be added to this list. In order * to free this value, you must call pango_attribute_destroy() on * each member. * - * Get the font + * Get the font and other attributes at the current iterator position. **/ void pango_attr_iterator_get_font (PangoAttrIterator *iterator, PangoFontDescription *base, PangoFontDescription *current, + PangoLanguage **language, GSList **extra_attrs) { GList *tmp_list1; @@ -1369,6 +1399,7 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator, gboolean have_weight = FALSE; gboolean have_stretch = FALSE; gboolean have_size = FALSE; + gboolean have_language = FALSE; g_return_if_fail (iterator != NULL); g_return_if_fail (base != NULL); @@ -1376,6 +1407,9 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator, *current = *base; + if (language) + *language = NULL; + if (extra_attrs) *extra_attrs = NULL; @@ -1471,7 +1505,16 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator, current->size = ((PangoAttrFloat *)attr)->value * base->size; } break; - + case PANGO_ATTR_LANGUAGE: + if (language) + { + if (!have_language) + { + have_language = TRUE; + *language = ((PangoAttrLanguage *)attr)->value; + } + } + break; default: if (extra_attrs) { diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index dc1d887a..ffdbdb2a 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -52,6 +52,7 @@ typedef struct _PangoAttribute PangoAttribute; typedef struct _PangoAttrClass PangoAttrClass; typedef struct _PangoAttrString PangoAttrString; +typedef struct _PangoAttrLanguage PangoAttrLanguage; typedef struct _PangoAttrInt PangoAttrInt; typedef struct _PangoAttrFloat PangoAttrFloat; typedef struct _PangoAttrColor PangoAttrColor; @@ -65,7 +66,7 @@ typedef struct _PangoAttrIterator PangoAttrIterator; typedef enum { PANGO_ATTR_INVALID, /* 0 is an invalid attribute type */ - PANGO_ATTR_LANG, /* PangoAttrString */ + PANGO_ATTR_LANGUAGE, /* PangoAttrLanguage */ PANGO_ATTR_FAMILY, /* PangoAttrString */ PANGO_ATTR_STYLE, /* PangoAttrInt */ PANGO_ATTR_WEIGHT, /* PangoAttrInt */ @@ -110,6 +111,12 @@ struct _PangoAttrString char *value; }; +struct _PangoAttrLanguage +{ + PangoAttribute attr; + PangoLanguage *value; +}; + struct _PangoAttrInt { PangoAttribute attr; @@ -148,7 +155,7 @@ void pango_attribute_destroy (PangoAttribute *attr); gboolean pango_attribute_equal (const PangoAttribute *attr1, const PangoAttribute *attr2); -PangoAttribute *pango_attr_lang_new (const char *lang); +PangoAttribute *pango_attr_language_new (PangoLanguage *language); PangoAttribute *pango_attr_family_new (const char *family); PangoAttribute *pango_attr_foreground_new (guint16 red, guint16 green, @@ -197,6 +204,7 @@ PangoAttribute * pango_attr_iterator_get (PangoAttrIterator *iterator void pango_attr_iterator_get_font (PangoAttrIterator *iterator, PangoFontDescription *base, PangoFontDescription *current, + PangoLanguage **language, GSList **extra_attrs); diff --git a/pango/pango-break.h b/pango/pango-break.h index 527a7cf5..d72ba0da 100644 --- a/pango/pango-break.h +++ b/pango/pango-break.h @@ -84,7 +84,7 @@ void pango_find_paragraph_boundary (const gchar *text, void pango_get_log_attrs (const char *text, int length, int level, - const char *language, + PangoLanguage *language, PangoLogAttr *log_attrs); /* This is the default break algorithm, used if no language diff --git a/pango/pango-context.c b/pango/pango-context.c index 95a96e85..056e4c32 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -31,7 +31,7 @@ struct _PangoContext { GObject parent_instance; - char *lang; + PangoLanguage *language; PangoDirection base_dir; PangoFontDescription *font_desc; @@ -51,10 +51,7 @@ static void add_engines (PangoContext *context, PangoAttrList *attrs, PangoAttrIterator *cached_iter, gint n_chars, - PangoEngineShape **shape_engines, - PangoEngineLang **lang_engines, - PangoFont **fonts, - GSList **extra_attr_lists); + PangoAnalysis *analyses); static void pango_context_init (PangoContext *context); static void pango_context_class_init (PangoContextClass *klass); @@ -96,7 +93,7 @@ pango_context_init (PangoContext *context) PangoFontDescription desc; context->base_dir = PANGO_DIRECTION_LTR; - context->lang = NULL; + context->language = NULL; context->font_maps = NULL; desc.family_name = "serif"; @@ -126,9 +123,6 @@ pango_context_finalize (GObject *object) context = PANGO_CONTEXT (object); - if (context->lang) - g_free (context->lang); - g_slist_foreach (context->font_maps, (GFunc)g_object_unref, NULL); g_slist_free (context->font_maps); @@ -429,38 +423,35 @@ pango_context_get_font_description (PangoContext *context) } /** - * pango_context_set_lang: + * pango_context_set_language: * @context: a #PangoContext - * @lang: the new language tag. + * @language: the new language tag. * * Sets the global language tag for the context. **/ void -pango_context_set_lang (PangoContext *context, - const char *lang) +pango_context_set_language (PangoContext *context, + PangoLanguage *language) { g_return_if_fail (context != NULL); - if (context->lang) - g_free (context->lang); - - context->lang = g_strdup (lang); + context->language = language; } /** - * pango_context_get_lang: + * pango_context_get_language: * @context: a #PangoContext * * Retrieves the global language tag for the context. * - * Return value: the global language tag. This value must be freed with g_free(). + * Return value: the global language tag. **/ -char * -pango_context_get_lang (PangoContext *context) +PangoLanguage * +pango_context_get_language (PangoContext *context) { g_return_val_if_fail (context != NULL, NULL); - return g_strdup (context->lang); + return context->language; } /** @@ -536,11 +527,8 @@ pango_itemize (PangoContext *context, const char *p; const char *next; GList *result = NULL; - - PangoEngineShape **shape_engines; - PangoEngineLang **lang_engines; - GSList **extra_attr_lists; - PangoFont **fonts; + + PangoAnalysis *analyses; g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (start_index >= 0, NULL); @@ -565,14 +553,11 @@ pango_itemize (PangoContext *context, pango_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir, embedding_levels); - /* Storing these as ranges would be a lot more efficient, - * but also more complicated... we take the simple - * approach for now. + /* Storing ranges would be more efficient, but also more + * complicated... we take the simple approach for now. */ - shape_engines = g_new0 (PangoEngineShape *, n_chars); - lang_engines = g_new0 (PangoEngineLang *, n_chars); - fonts = g_new0 (PangoFont *, n_chars); - extra_attr_lists = g_new0 (GSList *, n_chars); + + analyses = g_new0 (PangoAnalysis, n_chars); /* Now, fill in the appropriate shapers, language engines and fonts for * each character. @@ -581,8 +566,7 @@ pango_itemize (PangoContext *context, add_engines (context, text, start_index, length, attrs, cached_iter, n_chars, - shape_engines, lang_engines, fonts, - extra_attr_lists); + analyses); /* Make a GList of PangoItems out of the above results */ @@ -591,15 +575,19 @@ pango_itemize (PangoContext *context, p = text + start_index; for (i=0; i<n_chars; i++) { + PangoAnalysis *analysis = &analyses[i]; + PangoAnalysis *last_analysis = i > 0 ? &analyses[i-1] : 0; + next = g_utf8_next_char (p); if (i == 0 || text_ucs4[i] == '\t' || text_ucs4[i-1] == '\t' || embedding_levels[i] != embedding_levels[i-1] || - shape_engines[i] != shape_engines[i-1] || - lang_engines[i] != lang_engines[i-1] || - fonts[i] != fonts[i-1] || - extra_attr_lists[i] != extra_attr_lists[i-1]) + analysis->shape_engine != last_analysis->shape_engine || + analysis->lang_engine != last_analysis->lang_engine || + analysis->font != last_analysis->font || + analysis->language != last_analysis->language || + analysis->extra_attrs != last_analysis->extra_attrs) { /* assert that previous item got at least one char */ g_assert (item == NULL || item->length > 0); @@ -610,15 +598,16 @@ pango_itemize (PangoContext *context, item->num_chars = 0; item->analysis.level = embedding_levels[i]; - item->analysis.shape_engine = shape_engines[i]; - item->analysis.lang_engine = lang_engines[i]; + item->analysis.shape_engine = analysis->shape_engine; + item->analysis.lang_engine = analysis->lang_engine; - item->analysis.font = fonts[i]; + item->analysis.font = analysis->font; + item->analysis.language = analysis->language; /* Copy the extra attribute list if necessary */ - if (extra_attr_lists[i] && i != 0 && extra_attr_lists[i] == extra_attr_lists[i-1]) + if (analysis->extra_attrs && i != 0 && analysis->extra_attrs == last_analysis->extra_attrs) { - GSList *tmp_list = extra_attr_lists[i]; + GSList *tmp_list = analysis->extra_attrs; GSList *new_list = NULL; while (tmp_list) { @@ -626,27 +615,23 @@ pango_itemize (PangoContext *context, pango_attribute_copy (tmp_list->data)); tmp_list = tmp_list->next; } - item->extra_attrs = g_slist_reverse (new_list); + item->analysis.extra_attrs = g_slist_reverse (new_list); } else - item->extra_attrs = extra_attr_lists[i]; + item->analysis.extra_attrs = analysis->extra_attrs; result = g_list_prepend (result, item); } else - g_object_unref (G_OBJECT (fonts[i])); + g_object_unref (analysis->font); item->length = (next - text) - item->offset; item->num_chars++; p = next; } + g_free (analyses); g_free (embedding_levels); - g_free (shape_engines); - g_free (lang_engines); - g_free (fonts); - g_free (extra_attr_lists); - g_free (text_ucs4); return g_list_reverse (result); @@ -689,8 +674,8 @@ fallback_engine_shape (PangoFont *font, } static PangoCoverage* -fallback_engine_get_coverage (PangoFont *font, - const char *lang) +fallback_engine_get_coverage (PangoFont *font, + PangoLanguage *lang) { PangoCoverage *result = pango_coverage_new (); @@ -738,7 +723,7 @@ get_font (PangoFont **fonts, } if (result) - g_object_ref (G_OBJECT (result)); + g_object_ref (result); return result; } @@ -748,7 +733,7 @@ get_font (PangoFont **fonts, static void load_font (PangoContext *context, - char *lang, + PangoLanguage *language, PangoFontDescription *desc, PangoFont **current_fonts, PangoCoverage **current_coverages, @@ -762,7 +747,7 @@ load_font (PangoContext *context, { if (current_fonts[j]) { - g_object_unref (G_OBJECT (current_fonts[j])); + g_object_unref (current_fonts[j]); pango_coverage_unref (current_coverages[j]); } } @@ -778,7 +763,7 @@ load_font (PangoContext *context, if (current_fonts[*n_families]) { - current_coverages[*n_families] = pango_font_get_coverage (current_fonts[*n_families], lang); + current_coverages[*n_families] = pango_font_get_coverage (current_fonts[*n_families], language); (*n_families)++; } } @@ -807,7 +792,7 @@ load_font (PangoContext *context, current_fonts[0] = pango_context_load_font (context, desc); if (current_fonts[0]) { - current_coverages[0] = pango_font_get_coverage (current_fonts[0], lang); + current_coverages[0] = pango_font_get_coverage (current_fonts[0], language); *n_families = 1; } } @@ -832,7 +817,7 @@ load_font (PangoContext *context, current_fonts[0] = pango_context_load_font (context, desc); if (current_fonts[0]) { - current_coverages[0] = pango_font_get_coverage (current_fonts[0], lang); + current_coverages[0] = pango_font_get_coverage (current_fonts[0], language); *n_families = 1; } } @@ -876,13 +861,10 @@ add_engines (PangoContext *context, PangoAttrList *attrs, PangoAttrIterator *cached_iter, gint n_chars, - PangoEngineShape **shape_engines, - PangoEngineLang **lang_engines, - PangoFont **fonts, - GSList **extra_attr_lists) + PangoAnalysis *analyses) { const char *pos; - char *lang = NULL; + PangoLanguage *language = NULL; int next_index; GSList *extra_attrs = NULL; PangoMap *lang_map = NULL; @@ -891,7 +873,6 @@ add_engines (PangoContext *context, PangoFont *current_fonts[MAX_FAMILIES]; PangoCoverage *current_coverages[MAX_FAMILIES]; PangoAttrIterator *iterator; - PangoAttribute *attr; gboolean first_iteration = TRUE; gunichar wc; int i = 0, j; @@ -908,9 +889,11 @@ add_engines (PangoContext *context, pos = text + start_index; for (i=0; i<n_chars; i++) { + PangoAnalysis *analysis = &analyses[i]; + if (first_iteration || pos - text == next_index) { - char *next_lang; + PangoLanguage *next_language; PangoFontDescription next_desc; first_iteration = FALSE; @@ -924,20 +907,18 @@ add_engines (PangoContext *context, pango_attr_iterator_range (iterator, NULL, &next_index); } - attr = pango_attr_iterator_get (iterator, PANGO_ATTR_LANG); - if (attr) - next_lang = ((PangoAttrString *)attr)->value; - else - next_lang = context->lang; + pango_attr_iterator_get_font (iterator, context->font_desc, + &next_desc, &next_language, &extra_attrs); - if (i == 0 || - (lang != next_lang && - (lang == NULL || next_lang == NULL || strcmp (lang, next_lang) != 0))) + if (!next_language) + next_language = context->language; + + if (i == 0 || language != next_language) { static guint engine_type_id = 0; static guint render_type_id = 0; - lang = next_lang; + language = next_language; if (engine_type_id == 0) { @@ -945,39 +926,37 @@ add_engines (PangoContext *context, render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_NONE); } - lang_map = pango_find_map (next_lang, + lang_map = pango_find_map (next_language, engine_type_id, render_type_id); } - pango_attr_iterator_get_font (iterator, context->font_desc, - &next_desc, &extra_attrs); - if (i == 0 || !pango_font_description_equal (¤t_desc, &next_desc)) { current_desc = next_desc; - load_font (context, lang, ¤t_desc, + load_font (context, language, ¤t_desc, current_fonts, current_coverages, &n_families); } } wc = g_utf8_get_char (pos); pos = g_utf8_next_char (pos); - - lang_engines[i] = (PangoEngineLang *)pango_map_get_engine (lang_map, wc); - fonts[i] = get_font (current_fonts, current_coverages, n_families, wc); - + + analysis->lang_engine = (PangoEngineLang *)pango_map_get_engine (lang_map, wc); + analysis->font = get_font (current_fonts, current_coverages, n_families, wc); + analysis->language = language; + /* FIXME: handle reference counting properly on the shapers */ - if (fonts[i]) - shape_engines[i] = pango_font_find_shaper (fonts[i], lang, wc); + if (analysis->font) + analysis->shape_engine = pango_font_find_shaper (analysis->font, language, wc); else - shape_engines[i] = NULL; - - if (shape_engines[i] == NULL) - shape_engines[i] = &fallback_shaper; + analysis->shape_engine = NULL; + + if (analysis->shape_engine == NULL) + analysis->shape_engine = &fallback_shaper; - extra_attr_lists[i] = extra_attrs; + analysis->extra_attrs = extra_attrs; } g_assert (pos - text == start_index + length); @@ -986,7 +965,7 @@ add_engines (PangoContext *context, { if (current_fonts[j]) { - g_object_unref (G_OBJECT (current_fonts[j])); + g_object_unref (current_fonts[j]); pango_coverage_unref (current_coverages[j]); } } diff --git a/pango/pango-context.h b/pango/pango-context.h index 732c22ef..82ad982f 100644 --- a/pango/pango-context.h +++ b/pango/pango-context.h @@ -62,16 +62,15 @@ void pango_context_list_families (PangoContext *context PangoFont * pango_context_load_font (PangoContext *context, const PangoFontDescription *desc); -void pango_context_set_font_description (PangoContext *context, - const PangoFontDescription *desc); -PangoFontDescription *pango_context_get_font_description (PangoContext *context); -char * pango_context_get_lang (PangoContext *context); -void pango_context_set_lang (PangoContext *context, - const char *lang); -void pango_context_set_base_dir (PangoContext *context, - PangoDirection direction); -PangoDirection pango_context_get_base_dir (PangoContext *context); - +void pango_context_set_font_description (PangoContext *context, + const PangoFontDescription *desc); +PangoFontDescription * pango_context_get_font_description (PangoContext *context); +PangoLanguage *pango_context_get_language (PangoContext *context); +void pango_context_set_language (PangoContext *context, + PangoLanguage *language); +void pango_context_set_base_dir (PangoContext *context, + PangoDirection direction); +PangoDirection pango_context_get_base_dir (PangoContext *context); /* Break a string of Unicode characters into segments with * consistent shaping/language engine and bidrectional level. diff --git a/pango/pango-engine.h b/pango/pango-engine.h index 4673f360..447e0ee9 100644 --- a/pango/pango-engine.h +++ b/pango/pango-engine.h @@ -83,7 +83,7 @@ struct _PangoEngineShape PangoAnalysis *analysis, PangoGlyphString *glyphs); PangoCoverage *(*get_coverage) (PangoFont *font, - const char *lang); + PangoLanguage *language); }; /* A module should export the following functions */ diff --git a/pango/pango-font.h b/pango/pango-font.h index 0354d2be..cbbf4bcb 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -139,16 +139,16 @@ struct _PangoFontClass PangoFontDescription *(*describe) (PangoFont *font); PangoCoverage * (*get_coverage) (PangoFont *font, - const char *lang); + PangoLanguage *lang); PangoEngineShape * (*find_shaper) (PangoFont *font, - const char *lang, + PangoLanguage *lang, guint32 ch); void (*get_glyph_extents) (PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect); void (*get_metrics) (PangoFont *font, - const gchar *lang, + PangoLanguage *language, PangoFontMetrics *metrics); }; @@ -156,12 +156,12 @@ GType pango_font_get_type (void) G_GNUC_CONST; PangoFontDescription *pango_font_describe (PangoFont *font); PangoCoverage * pango_font_get_coverage (PangoFont *font, - const char *lang); + PangoLanguage *language); PangoEngineShape * pango_font_find_shaper (PangoFont *font, - const char *lang, + PangoLanguage *language, guint32 ch); void pango_font_get_metrics (PangoFont *font, - const gchar *lang, + PangoLanguage *language, PangoFontMetrics *metrics); void pango_font_get_glyph_extents (PangoFont *font, PangoGlyph glyph, diff --git a/pango/pango-item.c b/pango/pango-item.c index 73f96d2b..e090fe57 100644 --- a/pango/pango-item.c +++ b/pango/pango-item.c @@ -55,18 +55,18 @@ pango_item_copy (PangoItem *item) result->length = item->length; result->num_chars = item->num_chars; + result->analysis = item->analysis; + g_object_ref (result->analysis.font); + extra_attrs = NULL; - tmp_list = item->extra_attrs; + tmp_list = item->analysis.extra_attrs; while (tmp_list) { extra_attrs = g_slist_prepend (extra_attrs, pango_attribute_copy (tmp_list->data)); tmp_list = tmp_list->next; } - result->extra_attrs = g_slist_reverse (extra_attrs); - - result->analysis = item->analysis; - g_object_ref (G_OBJECT (result->analysis.font)); + result->analysis.extra_attrs = g_slist_reverse (extra_attrs); return result; } @@ -80,13 +80,13 @@ pango_item_copy (PangoItem *item) void pango_item_free (PangoItem *item) { - if (item->extra_attrs) + if (item->analysis.extra_attrs) { - g_slist_foreach (item->extra_attrs, (GFunc)pango_attribute_destroy, NULL); - g_slist_free (item->extra_attrs); + g_slist_foreach (item->analysis.extra_attrs, (GFunc)pango_attribute_destroy, NULL); + g_slist_free (item->analysis.extra_attrs); } - - g_object_unref (G_OBJECT (item->analysis.font)); + + g_object_unref (item->analysis.font); g_free (item); } diff --git a/pango/pango-item.h b/pango/pango-item.h index d4b067eb..59e67945 100644 --- a/pango/pango-item.h +++ b/pango/pango-item.h @@ -36,8 +36,10 @@ struct _PangoAnalysis { PangoEngineShape *shape_engine; PangoEngineLang *lang_engine; - PangoFont *font; + PangoFont *font; guint8 level; + PangoLanguage *language; + GSList *extra_attrs; }; struct _PangoItem @@ -45,7 +47,6 @@ struct _PangoItem gint offset; gint length; gint num_chars; - GSList *extra_attrs; PangoAnalysis analysis; }; diff --git a/pango/pango-layout.c b/pango/pango-layout.c index f0424b26..a1990190 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -2274,20 +2274,29 @@ ensure_tab_width (PangoLayout *layout) PangoAttrList *tmp_attrs; PangoAttrIterator *iter; PangoFontDescription font_desc; + PangoLanguage *language; int i; layout_attrs = pango_layout_get_effective_attributes (layout); iter = pango_attr_list_get_iterator (layout_attrs); pango_attr_iterator_get_font (iter, pango_context_get_font_description (layout->context), - &font_desc, NULL); + &font_desc, &language, NULL); tmp_attrs = pango_attr_list_new (); + attr = pango_attr_font_desc_new (&font_desc); attr->start_index = 0; attr->end_index = 1; - pango_attr_list_insert_before (tmp_attrs, attr); + if (language) + { + attr = pango_attr_language_new (language); + attr->start_index = 0; + attr->end_index = 1; + pango_attr_list_insert_before (tmp_attrs, attr); + } + items = pango_itemize (layout->context, " ", 0, 1, tmp_attrs, NULL); pango_attr_iterator_destroy (iter); @@ -3345,6 +3354,7 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line, pango_attr_iterator_get_font (iter, base_font_desc, &font_desc, + NULL, NULL); break; } @@ -3365,9 +3375,9 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line, font = pango_context_load_font (layout->context, &font_desc); if (font) { - char *lang = pango_context_get_lang (layout->context); - pango_font_get_metrics (font, lang, &metrics); - g_free (lang); + pango_font_get_metrics (font, + pango_context_get_language (layout->context), + &metrics); logical_rect->y = - metrics.ascent; logical_rect->height = metrics.ascent + metrics.descent; @@ -3701,7 +3711,7 @@ pango_layout_get_item_properties (PangoItem *item, PangoRectangle *logical_rect, gboolean *shape_set) { - GSList *tmp_list = item->extra_attrs; + GSList *tmp_list = item->analysis.extra_attrs; if (shape_set) *shape_set = FALSE; diff --git a/pango/pango-markup.c b/pango/pango-markup.c index 9e6acd27..b408fc26 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -1193,7 +1193,8 @@ span_parse_func (MarkupData *md, if (lang) { - add_attribute (tag, pango_attr_lang_new (lang)); + add_attribute (tag, + pango_attr_language_new (pango_language_from_string (lang))); } return TRUE; diff --git a/pango/pango-modules.h b/pango/pango-modules.h index f76a1246..28863083 100644 --- a/pango/pango-modules.h +++ b/pango/pango-modules.h @@ -46,7 +46,7 @@ struct _PangoIncludedModule void (*unload) (PangoEngine *engine); }; -PangoMap * pango_find_map (const char *lang, +PangoMap * pango_find_map (PangoLanguage *language, guint engine_type_id, guint render_type_id); PangoMapEntry *pango_map_get_entry (PangoMap *map, diff --git a/pango/pango-types.h b/pango/pango-types.h index 91e21ba8..bc6beba9 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -33,6 +33,9 @@ typedef struct _PangoEngineShape PangoEngineShape; typedef struct _PangoFont PangoFont; typedef struct _PangoRectangle PangoRectangle; +/* Dummy typedef - internally it's a 'const char *' */ +typedef struct _PangoLanguage PangoLanguage; + /* A index of a glyph into a font. Rendering system dependent */ typedef guint32 PangoGlyph; @@ -71,14 +74,11 @@ typedef enum { PANGO_DIRECTION_TTB_RTL } PangoDirection; -/* Language tagging information - */ -struct _PangoLangRange -{ - gint start; - gint length; - gchar *lang; -}; +PangoLanguage *pango_language_from_string (const char *language); +#define pango_language_to_string(language) ((const char *)language) + +gboolean pango_language_matches (PangoLanguage *language, + const char *range_list); #ifdef __cplusplus extern "C" { diff --git a/pango/pango-utils.c b/pango/pango-utils.c index f0a5aafd..b5c6c511 100644 --- a/pango/pango-utils.c +++ b/pango/pango-utils.c @@ -570,7 +570,8 @@ read_config () if (!config_hash) { char *filename; - char *home; + const char *home; + const char *envvar; config_hash = g_hash_table_new (g_str_hash, g_str_equal); filename = g_strconcat (pango_get_sysconf_subdirectory (), @@ -589,9 +590,9 @@ read_config () g_free (filename); } - filename = g_getenv ("PANGO_RC_FILE"); - if (filename) - read_config_file (filename, TRUE); + envvar = g_getenv ("PANGO_RC_FILE"); + if (envvar) + read_config_file (envvar, TRUE); } } @@ -888,6 +889,140 @@ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 (*p2) + { + guchar value = canon_map[*p2]; + if (value && value != *p1++) + return FALSE; + p2++; + } + + return (*p1 == '\0'); +} + +static guint +lang_hash (gconstpointer key) +{ + const guchar *p = key; + guint h = 0; + while (*p) + { + guchar value = canon_map[*p]; + if (value) + h = (h << 5) - h + value; + p++; + } + + return h; +} + +/** + * pang_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 + * #PangoLang 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 by converting it to + * lowercase, mapping '_' to '-', and stripping all characters other + * than letters and '-'. + * + * Return value: an opaque pointer to a PangoLang 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 (!hash) + hash = g_hash_table_new (lang_hash, lang_equal); + + result = g_hash_table_lookup (hash, language); + if (result) + return (PangoLanguage *)result; + + len = strlen (language); + result = g_malloc (len + 1); + + p = result; + while (*language) + { + char value = canon_map[*(guchar *)language++]; + if (value) + *(p++) = value; + } + *p++ = '\0'; + + g_hash_table_insert (hash, result, result); + + return (PangoLanguage *)result; +} + +/** + * pango_language_matches: + * @language: a language tag (see pango_language_from_string()) + * @range_list: a list of language ranges, separated by ';' characters. + * each element must either be '*', or a RFC 3066 language range + * canonicalized as by pango_lang_canonicalize(). + * + * 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 the + * tag is '-'. + **/ +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 = strchr (p, ';'); + if (!end) + { + end = p + strlen (p); + done = TRUE; + } + + if (strncmp (p, "*", 1) == 0 || + (strncmp (lang_str, p, end - p) == 0 && + (lang_str[end - p] == '\0' || lang_str[end - p] == '-'))) + return TRUE; + + p = end; + } + + return FALSE; +} + #ifdef HAVE_FRIBIDI void diff --git a/pango/pango-utils.h b/pango/pango-utils.h index e404daa6..00c31a57 100644 --- a/pango/pango-utils.h +++ b/pango/pango-utils.h @@ -73,7 +73,6 @@ G_CONST_RETURN char * pango_get_sysconf_subdirectory (void); */ G_CONST_RETURN char * pango_get_lib_subdirectory (void); - /* A couple of routines from fribidi that we either wrap or * provide ourselves. */ @@ -82,4 +81,5 @@ gboolean pango_log2vis_get_embedding_levels (gunichar *str, PangoDirection *pbase_dir, guint8 *embedding_level_list); gboolean pango_get_mirror_char (gunichar ch, + gunichar *mirrored_ch); diff --git a/pango/pangoft2-fontmap.c b/pango/pangoft2-fontmap.c index e42a3c15..e796732c 100644 --- a/pango/pangoft2-fontmap.c +++ b/pango/pangoft2-fontmap.c @@ -750,14 +750,13 @@ pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap) { char **files; char *files_str = pango_config_key_get ("PangoFT2/AliasFiles"); - char *home; char *tmp_str; int n; gboolean read_aliasfile; if (!files_str) { - home = g_get_home_dir (); + const char *home = g_get_home_dir (); if (home && *home) files_str = g_strconcat (home, @@ -955,7 +954,7 @@ free_coverages_foreach (gpointer key, PangoCoverage * pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, PangoFont *font, - const char *lang) + PangoLanguage *language) { guint32 ch; PangoMap *shape_map; @@ -984,14 +983,14 @@ pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, G_DIR_SEPARATOR_S "cache.ft2" G_DIR_SEPARATOR_S, font_as_filename, ".", - lang ? lang : "", + language ? pango_language_to_string (language) : "", NULL); g_free (font_as_filename); pango_font_description_free (description); PING (("trying to load %s", cache_file_name)); result = NULL; - if (g_file_get_contents (cache_file_name, &buf, &buflen, NULL)) + if (g_file_get_contents (cache_file_name, (char **)&buf, &buflen, NULL)) { result = pango_coverage_from_bytes (buf, buflen); g_free (buf); @@ -1003,7 +1002,7 @@ pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); - shape_map = pango_ft2_get_shaper_map (lang); + shape_map = pango_ft2_get_shaper_map (language); for (ch = 0; ch < 65536; ch++) { @@ -1014,7 +1013,7 @@ pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, if (!coverage) { PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, ch); - coverage = engine->get_coverage (font, lang); + coverage = engine->get_coverage (font, language); g_hash_table_insert (coverage_hash, map_entry->info->id, coverage); } diff --git a/pango/pangoft2-private.h b/pango/pangoft2-private.h index 460f993d..ff53c4ef 100644 --- a/pango/pangoft2-private.h +++ b/pango/pangoft2-private.h @@ -110,10 +110,10 @@ struct _PangoFT2FontEntry GSList *cached_fonts; }; -PangoMap *pango_ft2_get_shaper_map (const char *lang); +PangoMap *pango_ft2_get_shaper_map (PangoLanguage *language); PangoCoverage *pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, PangoFont *font, - const char *lang); + PangoLanguage *language); void pango_ft2_font_entry_remove (PangoFT2FontEntry *entry, PangoFont *font); FT_Library *pango_ft2_fontmap_get_library (PangoFontMap *fontmap); diff --git a/pango/pangoft2.c b/pango/pangoft2.c index 6c59ce79..f50ff43c 100644 --- a/pango/pangoft2.c +++ b/pango/pangoft2.c @@ -48,7 +48,7 @@ typedef struct _PangoFT2ContextInfo PangoFT2ContextInfo; struct _PangoFT2MetricsInfo { - const char *lang; + PangoLanguage *language; PangoFontMetrics metrics; }; @@ -67,10 +67,10 @@ static void pango_ft2_font_finalize (GObject *object); static PangoFontDescription *pango_ft2_font_describe (PangoFont *font); static PangoCoverage * pango_ft2_font_get_coverage (PangoFont *font, - const char *lang); + PangoLanguage *language); static PangoEngineShape * pango_ft2_font_find_shaper (PangoFont *font, - const char *lang, + PangoLanguage *language, guint32 ch); static void pango_ft2_font_get_glyph_extents (PangoFont *font, @@ -79,7 +79,7 @@ static void pango_ft2_font_get_glyph_extents (PangoFont PangoRectangle *logical_rect); static void pango_ft2_font_get_metrics (PangoFont *font, - const gchar *lang, + PangoLanguage *language, PangoFontMetrics *metrics); static void pango_ft2_get_item_properties (PangoItem *item, @@ -553,7 +553,7 @@ get_font_metrics_from_subfonts (PangoFont *font, */ static void get_font_metrics_from_string (PangoFont *font, - const char *lang, + PangoLanguage *language, const char *str, PangoFontMetrics *metrics) { @@ -586,7 +586,7 @@ get_font_metrics_from_string (PangoFont *font, gunichar wc = g_utf8_get_char (p); p = g_utf8_next_char (p); - shaper = pango_font_find_shaper (font, lang, wc); + shaper = pango_font_find_shaper (font, language, wc); if (p > start && (shaper != last_shaper || last_level != embedding_levels[i])) { @@ -670,36 +670,38 @@ LangInfo lang_texts[] = { static void pango_ft2_font_get_metrics (PangoFont *font, - const gchar *lang, + PangoLanguage *language, PangoFontMetrics *metrics) { - PangoFT2MetricsInfo *info; + PangoFT2MetricsInfo *info = NULL; /* Quiet GCC */ PangoFT2Font *ft2font = (PangoFT2Font *)font; GSList *tmp_list; - const char *lookup_lang; + PangoLanguage *lookup_lang; const char *str; - if (lang) + if (language) { - LangInfo *lang_info = bsearch (lang, lang_texts, + 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) { - lookup_lang = lang_info->lang; + lookup_lang = pango_language_from_string (lang_info->lang); str = lang_info->str; } else { - lookup_lang = "UNKNOWN"; + lookup_lang = pango_language_from_string ("UNKNOWN"); str = "French (Français)"; /* Assume iso-8859-1 */ } } else { - lookup_lang = "NONE"; + lookup_lang = pango_language_from_string ("NONE"); /* Complete junk */ @@ -711,7 +713,7 @@ pango_ft2_font_get_metrics (PangoFont *font, { info = tmp_list->data; - if (info->lang == lookup_lang) /* We _don't_ need strcmp */ + if (info->language == lookup_lang) /* We _don't_ need strcmp */ break; tmp_list = tmp_list->next; @@ -720,11 +722,11 @@ pango_ft2_font_get_metrics (PangoFont *font, if (!tmp_list) { info = g_new (PangoFT2MetricsInfo, 1); - info->lang = lookup_lang; + info->language = lookup_lang; ft2font->metrics_by_lang = g_slist_prepend (ft2font->metrics_by_lang, info); - get_font_metrics_from_string (font, lang, str, &info->metrics); + get_font_metrics_from_string (font, language, str, &info->metrics); } *metrics = info->metrics; @@ -749,8 +751,8 @@ pango_ft2_n_subfonts (PangoFont *font) } PangoCoverage * -pango_ft2_get_coverage (PangoFont *font, - const char *lang) +pango_ft2_get_coverage (PangoFont *font, + PangoLanguage *language) { PangoFT2Font *ft2font = (PangoFT2Font *)font; PangoCoverage *result = pango_coverage_new (); @@ -878,7 +880,7 @@ pango_ft2_font_describe (PangoFont *font) } PangoMap * -pango_ft2_get_shaper_map (const char *lang) +pango_ft2_get_shaper_map (PangoLanguage *language) { static guint engine_type_id = 0; static guint render_type_id = 0; @@ -889,26 +891,26 @@ pango_ft2_get_shaper_map (const char *lang) render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_FT2); } - return pango_find_map (lang, engine_type_id, render_type_id); + return pango_find_map (language, engine_type_id, render_type_id); } static PangoCoverage * -pango_ft2_font_get_coverage (PangoFont *font, - const char *lang) +pango_ft2_font_get_coverage (PangoFont *font, + PangoLanguage *language) { PangoFT2Font *ft2font = (PangoFT2Font *)font; - return pango_ft2_font_entry_get_coverage (ft2font->entry, font, lang); + return pango_ft2_font_entry_get_coverage (ft2font->entry, font, language); } static PangoEngineShape * -pango_ft2_font_find_shaper (PangoFont *font, - const gchar *lang, - guint32 ch) +pango_ft2_font_find_shaper (PangoFont *font, + PangoLanguage *language, + guint32 ch) { PangoMap *shape_map = NULL; - shape_map = pango_ft2_get_shaper_map (lang); + shape_map = pango_ft2_get_shaper_map (language); return (PangoEngineShape *)pango_map_get_engine (shape_map, ch); } @@ -1107,7 +1109,7 @@ pango_ft2_get_item_properties (PangoItem *item, PangoAttrColor *bg_color, gboolean *bg_set) { - GSList *tmp_list = item->extra_attrs; + GSList *tmp_list = item->analysis.extra_attrs; if (fg_set) *fg_set = FALSE; diff --git a/pango/pangoft2.h b/pango/pangoft2.h index 77c3667d..0613d2da 100644 --- a/pango/pangoft2.h +++ b/pango/pangoft2.h @@ -65,15 +65,15 @@ typedef guint16 PangoFT2Subfont; #define PANGO_FT2_GLYPH_SUBFONT(glyph) ((glyph)>>16) #define PANGO_FT2_GLYPH_INDEX(glyph) ((glyph) & 0xFFFF) -int pango_ft2_n_subfonts (PangoFont *font); -PangoGlyph pango_ft2_get_unknown_glyph (PangoFont *font); -int pango_ft2_font_get_kerning (PangoFont *font, - PangoGlyph left, - PangoGlyph right); -PangoCoverage *pango_ft2_get_coverage (PangoFont *font, - const char *lang); -FT_Face pango_ft2_get_face (PangoFont *font, - PangoFT2Subfont subfont_index); +int pango_ft2_n_subfonts (PangoFont *font); +PangoGlyph pango_ft2_get_unknown_glyph (PangoFont *font); +int pango_ft2_font_get_kerning (PangoFont *font, + PangoGlyph left, + PangoGlyph right); +PangoCoverage *pango_ft2_get_coverage (PangoFont *font, + PangoLanguage *language); +FT_Face pango_ft2_get_face (PangoFont *font, + PangoFT2Subfont subfont_index); /* API for libraries that want to use PangoFT2 mixed with classic * FT2 fonts. diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c index 631591f4..f95eb5d7 100644 --- a/pango/pangox-fontmap.c +++ b/pango/pangox-fontmap.c @@ -1349,7 +1349,7 @@ free_coverages_foreach (gpointer key, PangoCoverage * pango_x_font_entry_get_coverage (PangoXFontEntry *entry, PangoFont *font, - const char *lang) + PangoLanguage *language) { PangoXFont *xfont; PangoXFontMap *xfontmap = NULL; /* Quiet gcc */ @@ -1370,7 +1370,9 @@ pango_x_font_entry_get_coverage (PangoXFontEntry *entry, xfontmap = (PangoXFontMap *)pango_x_font_map_for_display (xfont->display); if (entry->xlfd) { - char *str = g_strconcat (lang ? lang : "*", "|", entry->xlfd, NULL); + const char *lang_str = language ? pango_language_to_string (language) : "*"; + + char *str = g_strconcat (lang_str, "|", entry->xlfd, NULL); result = pango_x_get_cached_coverage (xfontmap, str, &atom); g_free (str); } @@ -1388,7 +1390,7 @@ pango_x_font_entry_get_coverage (PangoXFontEntry *entry, coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); - shape_map = pango_x_get_shaper_map (lang); + shape_map = pango_x_get_shaper_map (language); for (ch = 0; ch < 65536; ch++) { @@ -1399,7 +1401,7 @@ pango_x_font_entry_get_coverage (PangoXFontEntry *entry, if (!coverage) { PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, ch); - coverage = engine->get_coverage (font, lang); + coverage = engine->get_coverage (font, language); g_hash_table_insert (coverage_hash, map_entry->info->id, coverage); } diff --git a/pango/pangox-private.h b/pango/pangox-private.h index 1549d03e..aa36d6f9 100644 --- a/pango/pangox-private.h +++ b/pango/pangox-private.h @@ -98,14 +98,14 @@ GType pango_x_font_map_get_type (void); PangoXFont * pango_x_font_new (PangoFontMap *fontmap, const char *spec, int size); -PangoMap * pango_x_get_shaper_map (const char *lang); +PangoMap * pango_x_get_shaper_map (PangoLanguage *language); char * pango_x_make_matching_xlfd (PangoFontMap *fontmap, char *xlfd, const char *charset, int size); PangoCoverage *pango_x_font_entry_get_coverage (PangoXFontEntry *entry, PangoFont *font, - const char *lang); + PangoLanguage *language); void pango_x_font_entry_remove (PangoXFontEntry *entry, PangoFont *font); diff --git a/pango/pangox.c b/pango/pangox.c index d1aef739..d5909883 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -116,7 +116,7 @@ struct _PangoXSubfontInfo struct _PangoXMetricsInfo { - const char *lang; + PangoLanguage *language; PangoFontMetrics metrics; }; @@ -158,16 +158,16 @@ static void pango_x_font_finalize (GObject *object); static PangoFontDescription *pango_x_font_describe (PangoFont *font); static PangoCoverage * pango_x_font_get_coverage (PangoFont *font, - const char *lang); + PangoLanguage *language); static PangoEngineShape * pango_x_font_find_shaper (PangoFont *font, - const char *lang, + PangoLanguage *language, guint32 ch); static void pango_x_font_get_glyph_extents (PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect); static void pango_x_font_get_metrics (PangoFont *font, - const gchar *lang, + PangoLanguage *language, PangoFontMetrics *metrics); static PangoXSubfontInfo * pango_x_find_subfont (PangoFont *font, @@ -770,7 +770,7 @@ get_font_metrics_from_subfonts (PangoFont *font, */ static void get_font_metrics_from_string (PangoFont *font, - const char *lang, + PangoLanguage *language, const char *str, PangoFontMetrics *metrics) { @@ -806,7 +806,7 @@ get_font_metrics_from_string (PangoFont *font, if (*p) { wc = g_utf8_get_char (p); - shaper = pango_font_find_shaper (font, lang, wc); + shaper = pango_font_find_shaper (font, language, wc); } else { @@ -824,7 +824,9 @@ get_font_metrics_from_string (PangoFont *font, analysis.shape_engine = last_shaper; analysis.lang_engine = NULL; analysis.font = font; + analysis.language = language; analysis.level = last_level; + analysis.extra_attrs = NULL; pango_shape (start, p - start, &analysis, glyph_str); @@ -900,36 +902,37 @@ LangInfo lang_texts[] = { static void pango_x_font_get_metrics (PangoFont *font, - const gchar *lang, + PangoLanguage *language, PangoFontMetrics *metrics) { PangoXMetricsInfo *info = NULL; /* Quiet gcc */ PangoXFont *xfont = (PangoXFont *)font; GSList *tmp_list; + const char *lang_str = pango_language_to_string (language); - const char *lookup_lang; + PangoLanguage *lookup_lang; const char *str; - if (lang) + if (language) { - LangInfo *lang_info = bsearch (lang, lang_texts, + LangInfo *lang_info = bsearch (lang_str, lang_texts, G_N_ELEMENTS (lang_texts), sizeof (LangInfo), lang_info_compare); if (lang_info) { - lookup_lang = lang_info->lang; + lookup_lang = pango_language_from_string (lang_info->lang); str = lang_info->str; } else { - lookup_lang = "UNKNOWN"; + lookup_lang = pango_language_from_string ("UNKNOWN"); str = "French (Français)"; /* Assume iso-8859-1 */ } } else { - lookup_lang = "NONE"; + lookup_lang = pango_language_from_string ("NONE"); /* Complete junk */ @@ -941,7 +944,7 @@ pango_x_font_get_metrics (PangoFont *font, { info = tmp_list->data; - if (info->lang == lookup_lang) /* We _don't_ need strcmp */ + if (info->language == lookup_lang) /* We _don't_ need strcmp */ break; tmp_list = tmp_list->next; @@ -954,7 +957,7 @@ pango_x_font_get_metrics (PangoFont *font, PangoContext *context; info = g_new (PangoXMetricsInfo, 1); - info->lang = lookup_lang; + info->language = lookup_lang; xfont->metrics_by_lang = g_slist_prepend (xfont->metrics_by_lang, info); @@ -965,7 +968,7 @@ pango_x_font_get_metrics (PangoFont *font, * chars in "0123456789" */ context = pango_x_get_context (pango_x_fontmap_get_display (xfont->fontmap)); - pango_context_set_lang (context, lookup_lang); + pango_context_set_language (context, lookup_lang); layout = pango_layout_new (context); pango_layout_set_text (layout, "0123456789", -1); @@ -1326,7 +1329,7 @@ pango_x_font_describe (PangoFont *font) } PangoMap * -pango_x_get_shaper_map (const char *lang) +pango_x_get_shaper_map (PangoLanguage *language) { static guint engine_type_id = 0; static guint render_type_id = 0; @@ -1337,26 +1340,26 @@ pango_x_get_shaper_map (const char *lang) render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_X); } - return pango_find_map (lang, engine_type_id, render_type_id); + return pango_find_map (language, engine_type_id, render_type_id); } static PangoCoverage * -pango_x_font_get_coverage (PangoFont *font, - const char *lang) +pango_x_font_get_coverage (PangoFont *font, + PangoLanguage *language) { PangoXFont *xfont = (PangoXFont *)font; - return pango_x_font_entry_get_coverage (xfont->entry, font, lang); + return pango_x_font_entry_get_coverage (xfont->entry, font, language); } static PangoEngineShape * -pango_x_font_find_shaper (PangoFont *font, - const gchar *lang, - guint32 ch) +pango_x_font_find_shaper (PangoFont *font, + PangoLanguage *language, + guint32 ch) { PangoMap *shape_map = NULL; - shape_map = pango_x_get_shaper_map (lang); + shape_map = pango_x_get_shaper_map (language); return (PangoEngineShape *)pango_map_get_engine (shape_map, ch); } @@ -1675,7 +1678,7 @@ pango_x_get_item_properties (PangoItem *item, PangoAttrColor *bg_color, gboolean *bg_set) { - GSList *tmp_list = item->extra_attrs; + GSList *tmp_list = item->analysis.extra_attrs; if (fg_set) *fg_set = FALSE; |