diff options
author | Owen Taylor <otaylor@redhat.com> | 2003-08-03 02:35:20 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2003-08-03 02:35:20 +0000 |
commit | 94f39b93e929db7881070f4b5e1f5dc3c106e3fb (patch) | |
tree | 1fa92651d4e9d2c7c41d413468f37bdb8095cd52 /pango/pangofc-fontmap.cI | |
parent | e2ea77ce2f99c122a0087c28fcd9316be4d6e205 (diff) | |
download | pango-94f39b93e929db7881070f4b5e1f5dc3c106e3fb.tar.gz |
Make pangoxft depend on pangoft2.
Sat Aug 2 14:33:28 2003 Owen Taylor <otaylor@redhat.com>
* pango/Makefile.am (libpangoxft_1_0_la_LIBADD): Make
pangoxft depend on pangoft2.
* pango/pangofc-fontmap.[ch]: Make pangofc-fontmap.cI
into a real base class.
* pango/pangofc-font.[ch]: Move some of the pangoxft/
pangoft2 implementation here.
* pango/pangoft2.c pango/pangoft2-fontmap.c
pango/pangoft2-private.h pango/pangoxft-font.c
pango/pangoxft2-fontmap.c pango/pangoxft-private.h: Adapt
to the new scheme
* modules/*/Makefile.am Modules/*/*/*-fc.c: Don't build
separate FT2 and Xft shapers, just build one Fc shaper.
* docs/pango-sections.txt docs/pango-docs.sgml
docs/tmpl/pangofc-font{,map}.sgml: Basic docs for
the new stuff.
* configure.in: Up pango_module_version to 1.4.0.
Diffstat (limited to 'pango/pangofc-fontmap.cI')
-rw-r--r-- | pango/pangofc-fontmap.cI | 1138 |
1 files changed, 0 insertions, 1138 deletions
diff --git a/pango/pangofc-fontmap.cI b/pango/pangofc-fontmap.cI deleted file mode 100644 index 28d5fa20..00000000 --- a/pango/pangofc-fontmap.cI +++ /dev/null @@ -1,1138 +0,0 @@ -/* Pango - * pangofc-fontmap.cI: Common font handling between Xft and FT2 - * - * Copyright (C) 2000,2001,2002 Red Hat, Inc. - * - * 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. - */ - -/* - * This file is included by both pangoxft-fontmap.c and pangoft2-fontmap.c - * after making appropriate #defines for public symbols. - */ - -/* Size of fontset cache */ -#define FONTSET_CACHE_SIZE 16 - -typedef struct _PangoFcCoverageKey PangoFcCoverageKey; -typedef struct _PangoFcFace PangoFcFace; -typedef struct _PangoFcPatternSet PangoFcPatternSet; - -#define PANGO_FC_TYPE_FAMILY (pango_fc_family_get_type ()) -#define PANGO_FC_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FC_TYPE_FAMILY, PangoFcFamily)) -#define PANGO_FC_IS_FAMILY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_FC_TYPE_FAMILY)) - -#define PANGO_FC_TYPE_FACE (pango_fc_face_get_type ()) -#define PANGO_FC_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FC_TYPE_FACE, PangoFcFace)) -#define PANGO_FC_IS_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_FC_TYPE_FACE)) - -struct _PangoFcCoverageKey -{ - char *filename; - int id; /* needed to handle TTC files with multiple faces */ -}; - -struct _PangoFcFace -{ - PangoFontFace parent_instance; - - PangoFcFamily *family; - char *style; -}; - -struct _PangoFcFamily -{ - PangoFontFamily parent_instance; - - PangoFcFontMap *fontmap; - char *family_name; - - PangoFcFace **faces; - int n_faces; /* -1 == uninitialized */ -}; - -struct _PangoFcPatternSet -{ - int n_patterns; - FcPattern **patterns; - PangoFontset *fontset; - GList *cache_link; -}; - -GType pango_fc_font_map_get_type (void); -static GType pango_fc_family_get_type (void); -static GType pango_fc_face_get_type (void); - -static void pango_fc_font_map_init (PangoFcFontMap *fontmap); -static void pango_fc_font_map_class_init (PangoFontMapClass *class); -static void pango_fc_font_map_finalize (GObject *object); -static PangoFont * pango_fc_font_map_load_font (PangoFontMap *fontmap, - PangoContext *context, - const PangoFontDescription *description); -static PangoFontset *pango_fc_font_map_load_fontset (PangoFontMap *fontmap, - PangoContext *context, - const PangoFontDescription *desc, - PangoLanguage *language); -static void pango_fc_font_map_list_families (PangoFontMap *fontmap, - PangoFontFamily ***families, - int *n_families); - - -static void pango_fc_pattern_set_free (PangoFcPatternSet *patterns); - -static void pango_fc_font_map_cache_clear (PangoFcFontMap *fcfontmap); -static void pango_fc_default_substitute (PangoFcFontMap *fontmap, - FcPattern *pattern); -static void pango_fc_do_finalize (PangoFcFontMap *fontmap); - -static guint pango_fc_pattern_hash (FcPattern *pattern); -static gboolean pango_fc_pattern_equal (FcPattern *pattern1, - FcPattern *pattern2); -static guint pango_fc_coverage_key_hash (PangoFcCoverageKey *key); -static gboolean pango_fc_coverage_key_equal (PangoFcCoverageKey *key1, - PangoFcCoverageKey *key2); - -static PangoFontClass *parent_class; /* Parent class structure for PangoFcFontMap */ - -GType -pango_fc_font_map_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = - { - sizeof (PangoFontMapClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) pango_fc_font_map_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PangoFcFontMap), - 0, /* n_preallocs */ - (GInstanceInitFunc) pango_fc_font_map_init, - }; - - object_type = g_type_register_static (PANGO_TYPE_FONT_MAP, - PANGO_FC_NAME "FontMap", - &object_info, 0); - } - - return object_type; -} - -static void -pango_fc_font_map_init (PangoFcFontMap *fcfontmap) -{ - fcfontmap->n_families = -1; - - fcfontmap->fonts = g_hash_table_new ((GHashFunc)g_direct_hash, NULL); - fcfontmap->coverage_hash = g_hash_table_new_full ((GHashFunc)pango_fc_coverage_key_hash, - (GEqualFunc)pango_fc_coverage_key_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)pango_coverage_unref); - fcfontmap->fontset_cache = g_queue_new (); -} -static void -pango_fc_font_map_class_init (PangoFontMapClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - parent_class = g_type_class_peek_parent (class); - - object_class->finalize = pango_fc_font_map_finalize; - class->load_font = pango_fc_font_map_load_font; - class->load_fontset = pango_fc_font_map_load_fontset; - class->list_families = pango_fc_font_map_list_families; -} - -static GSList *fontmaps = NULL; - -static guint -pango_fc_pattern_hash (FcPattern *pattern) -{ -#if 1 - return FcPatternHash (pattern); -#else - /* Hashing only part of the pattern can improve speed a bit. - */ - char *str; - int i; - double d; - guint hash = 0; - - FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &str); - if (str) - hash = g_str_hash (str); - - if (FcPatternGetInteger (pattern, FC_INDEX, 0, &i) == FcResultMatch) - hash ^= i; - - if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &d) == FcResultMatch) - hash ^= (guint) (d*1000.0); - - return hash; -#endif -} - -static gboolean -pango_fc_pattern_equal (FcPattern *pattern1, - FcPattern *pattern2) -{ - if (pattern1 == pattern2) - return TRUE; - else - return FcPatternEqual (pattern1, pattern2); -} - -static guint -pango_fc_coverage_key_hash (PangoFcCoverageKey *key) -{ - return g_str_hash (key->filename) ^ key->id; -} - -static gboolean -pango_fc_coverage_key_equal (PangoFcCoverageKey *key1, - PangoFcCoverageKey *key2) -{ - return key1->id == key2->id && strcmp (key1->filename, key2->filename) == 0; -} - -typedef struct _FontsetHashListNode FontsetHashListNode; - -struct _FontsetHashListNode { - GHashTable *fontset_hash; - PangoLanguage *language; -}; - -/* Get the description => fontset map for a particular - * language tag. - */ -static GHashTable * -pango_fc_get_fontset_hash (PangoFcFontMap *fcfontmap, - PangoLanguage *language) -{ - /* We treat NULL as a distinct language tag, but - * we should actually determine the real language - * tag it corresponds to to avoid duplicate entries - * in the list. - */ - GList *tmp_list = fcfontmap->fontset_hash_list; - while (tmp_list) - { - FontsetHashListNode *node = tmp_list->data; - if (node->language == language) - { - if (tmp_list != fcfontmap->fontset_hash_list) - { - /* Put the found node at the beginning - */ - fcfontmap->fontset_hash_list = g_list_remove_link (fcfontmap->fontset_hash_list, tmp_list); - fcfontmap->fontset_hash_list->prev = tmp_list; - tmp_list->next = fcfontmap->fontset_hash_list; - fcfontmap->fontset_hash_list = tmp_list; - } - - return node->fontset_hash; - } - - tmp_list = tmp_list->next; - } - - { - FontsetHashListNode *node = g_new (FontsetHashListNode, 1); - fcfontmap->fontset_hash_list = g_list_prepend (fcfontmap->fontset_hash_list, node); - - node->fontset_hash = - g_hash_table_new_full ((GHashFunc)pango_font_description_hash, - (GEqualFunc)pango_font_description_equal, - (GDestroyNotify)pango_font_description_free, - (GDestroyNotify)pango_fc_pattern_set_free); - node->language = language; - - return node->fontset_hash; - } -} - -static void -pango_fc_clear_pattern_hashes (PangoFcFontMap *fcfontmap) -{ - GList *tmp_list; - - tmp_list = fcfontmap->fontset_hash_list; - while (tmp_list) - { - FontsetHashListNode *node = tmp_list->data; - - g_hash_table_destroy (node->fontset_hash); - g_free (node); - - tmp_list = tmp_list->next; - } - - g_list_free (fcfontmap->fontset_hash_list); - fcfontmap->fontset_hash_list = NULL; -} - -static void -pango_fc_font_map_finalize (GObject *object) -{ - PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (object); - - fontmaps = g_slist_remove (fontmaps, object); - - if (fcfontmap->substitute_destroy) - fcfontmap->substitute_destroy (fcfontmap->substitute_data); - - pango_fc_font_map_cache_clear (fcfontmap); - g_queue_free (fcfontmap->fontset_cache); - g_hash_table_destroy (fcfontmap->coverage_hash); - - if (fcfontmap->fonts) - g_hash_table_destroy (fcfontmap->fonts); - - if (fcfontmap->pattern_hash) - g_hash_table_destroy (fcfontmap->pattern_hash); - - pango_fc_do_finalize (fcfontmap); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - - -/* Add a mapping from xfont->font_pattern to xfont */ -void -_pango_fc_font_map_add (PangoFontMap *fontmap, - PangoFcFont *xfont) -{ - PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (fontmap); - - g_hash_table_insert (fcfontmap->fonts, - xfont->font_pattern, - xfont); -} - -/* Remove mapping from xfont->font_pattern to xfont */ -void -_pango_fc_font_map_remove (PangoFontMap *fontmap, - PangoFcFont *xfont) -{ - PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (fontmap); - - g_hash_table_remove (fcfontmap->fonts, - xfont->font_pattern); -} - -static PangoFcFamily * -create_family (PangoFcFontMap *fcfontmap, - const char *family_name) -{ - PangoFcFamily *family = g_object_new (PANGO_FC_TYPE_FAMILY, NULL); - family->fontmap = fcfontmap; - family->family_name = g_strdup (family_name); - - return family; -} - -static gboolean -is_alias_family (const char *family_name) -{ - switch (family_name[0]) - { - case 'm': - case 'M': - return (g_ascii_strcasecmp (family_name, "monospace") == 0); - case 's': - case 'S': - return (g_ascii_strcasecmp (family_name, "sans") == 0 || - g_ascii_strcasecmp (family_name, "serif") == 0); - } - - return FALSE; -} - -static void -pango_fc_font_map_list_families (PangoFontMap *fontmap, - PangoFontFamily ***families, - int *n_families) -{ - PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (fontmap); - FcFontSet *fontset; - int i; - int count; - - if (fcfontmap->closed) - { - if (families) - *families = NULL; - if (n_families) - n_families = 0; - - return; - } - - if (fcfontmap->n_families < 0) - { - FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, NULL); - FcPattern *pat = FcPatternCreate (); - - fontset = FcFontList (NULL, pat, os); - - FcPatternDestroy (pat); - FcObjectSetDestroy (os); - - fcfontmap->families = g_new (PangoFcFamily *, fontset->nfont + 3); /* 3 standard aliases */ - - count = 0; - for (i = 0; i < fontset->nfont; i++) - { - char *s; - FcResult res; - - res = FcPatternGetString (fontset->fonts[i], FC_FAMILY, 0, (FcChar8 **) &s); - g_assert (res == FcResultMatch); - - if (!is_alias_family (s)) - fcfontmap->families[count++] = create_family (fcfontmap, s); - } - - FcFontSetDestroy (fontset); - - fcfontmap->families[count++] = create_family (fcfontmap, "Sans"); - fcfontmap->families[count++] = create_family (fcfontmap, "Serif"); - fcfontmap->families[count++] = create_family (fcfontmap, "Monospace"); - - fcfontmap->n_families = count; - } - - if (n_families) - *n_families = fcfontmap->n_families; - - if (families) - *families = g_memdup (fcfontmap->families, fcfontmap->n_families * sizeof (PangoFontFamily *)); -} - -static int -pango_fc_convert_weight (PangoWeight pango_weight) -{ - int weight; - - if (pango_weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2) - weight = FC_WEIGHT_LIGHT; - else if (pango_weight < (PANGO_WEIGHT_NORMAL + 600) / 2) - weight = FC_WEIGHT_MEDIUM; - else if (pango_weight < (600 + PANGO_WEIGHT_BOLD) / 2) - weight = FC_WEIGHT_DEMIBOLD; - else if (pango_weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2) - weight = FC_WEIGHT_BOLD; - else - weight = FC_WEIGHT_BLACK; - - return weight; -} - -static int -pango_fc_convert_slant (PangoStyle pango_style) -{ - int slant; - - if (pango_style == PANGO_STYLE_ITALIC) - slant = FC_SLANT_ITALIC; - else if (pango_style == PANGO_STYLE_OBLIQUE) - slant = FC_SLANT_OBLIQUE; - else - slant = FC_SLANT_ROMAN; - - return slant; -} - - -static FcPattern * -pango_fc_make_pattern (const PangoFontDescription *description) -{ - FcPattern *pattern; - PangoStyle pango_style; - int slant; - int weight; - char **families; - int i; - - pango_style = pango_font_description_get_style (description); - - slant = pango_fc_convert_slant (pango_style); - weight = pango_fc_convert_weight (pango_font_description_get_weight (description)); - - pattern = FcPatternBuild (0, - FC_WEIGHT, FcTypeInteger, weight, - FC_SLANT, FcTypeInteger, slant, - FC_SIZE, FcTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE, - NULL); - - families = g_strsplit (pango_font_description_get_family (description), ",", -1); - - for (i = 0; families[i]; i++) - FcPatternAddString (pattern, FC_FAMILY, families[i]); - - g_strfreev (families); - - return pattern; -} - -static PangoFont * -pango_fc_font_map_new_font (PangoFontMap *fontmap, - FcPattern *match) -{ - PangoFcFontMap *fcfontmap = (PangoFcFontMap *)fontmap; - PangoFcFont *font; - - /* Returning NULL here actually violates a contract - * that loading load_font() will never return NULL. - * We probably should actually create a dummy - * font that doesn't draw anything and has empty - * metrics. - */ - if (fcfontmap->closed) - return NULL; - - /* Look up cache */ - font = g_hash_table_lookup (fcfontmap->fonts, match); - - if (font) - return g_object_ref (font); - - FcPatternReference (match); - return (PangoFont *)_pango_fc_font_new (fontmap, match); -} - -static FcPattern * -uniquify_pattern (PangoFcFontMap *fcfontmap, - FcPattern *pattern) -{ - FcPattern *old_pattern; - - if (!fcfontmap->pattern_hash) - fcfontmap->pattern_hash = - g_hash_table_new_full ((GHashFunc)pango_fc_pattern_hash, - (GEqualFunc)pango_fc_pattern_equal, - (GDestroyNotify)FcPatternDestroy, NULL); - - old_pattern = g_hash_table_lookup (fcfontmap->pattern_hash, pattern); - if (old_pattern) - { - FcPatternDestroy (pattern); - FcPatternReference (old_pattern); - return old_pattern; - } - else - { - FcPatternReference (pattern); - g_hash_table_insert (fcfontmap->pattern_hash, pattern, pattern); - return pattern; - } -} - -static PangoFcPatternSet * -pango_fc_font_map_get_patterns (PangoFontMap *fontmap, - PangoContext *context, - const PangoFontDescription *desc, - PangoLanguage *language) -{ - PangoFcFontMap *fcfontmap = (PangoFcFontMap *)fontmap; - FcPattern *pattern, *font_pattern; - FcResult res; - int f; - PangoFcPatternSet *patterns; - FcFontSet *font_patterns; - GHashTable *fontset_hash; - - if (!language && context) - language = pango_context_get_language (context); - - fontset_hash = pango_fc_get_fontset_hash (fcfontmap, language); - patterns = g_hash_table_lookup (fontset_hash, desc); - - if (patterns == NULL) - { - pattern = pango_fc_make_pattern (desc); - if (language) - FcPatternAddString (pattern, FC_LANG, (FcChar8 *) pango_language_to_string (language)); - - pango_fc_default_substitute (fcfontmap, pattern); - - font_patterns = FcFontSort (NULL, pattern, FcTrue, 0, &res); - - if (!font_patterns) - { - g_printerr ("No fonts found; this probably means that the fontconfig\n" - "library is not correctly configured. You may need to\n" - "edit the fonts.conf configuration file. More information\n" - "about fontconfig can be found in the fontconfig(3) manual\n" - "page and on http://fontconfig.org\n"); - - /* There is no point in proceeding; we'll just get a segfault later - * on, and a bunch more possibly confusing error messages in between. - */ - - /* return NULL; */ - exit (1); - } - - patterns = g_new (PangoFcPatternSet, 1); - patterns->patterns = g_new (FcPattern *, font_patterns->nfont); - patterns->n_patterns = 0; - patterns->fontset = NULL; - patterns->cache_link = NULL; - - for (f = 0; f < font_patterns->nfont; f++) - { - font_pattern = FcFontRenderPrepare (NULL, pattern, - font_patterns->fonts[f]); -#ifdef FC_PATTERN - /* The FC_PATTERN element, which points back to our the original patterm - * defeats our hash tables. - */ - FcPatternDel (font_pattern, FC_PATTERN); -#endif /* FC_PATTERN */ - - if (font_pattern) - patterns->patterns[patterns->n_patterns++] = uniquify_pattern (fcfontmap, font_pattern); - } - - FcPatternDestroy (pattern); - - FcFontSetSortDestroy (font_patterns); - - g_hash_table_insert (fontset_hash, - pango_font_description_copy (desc), - patterns); - } - - return patterns; -} - -static PangoFont * -pango_fc_font_map_load_font (PangoFontMap *fontmap, - PangoContext *context, - const PangoFontDescription *description) -{ - PangoFcPatternSet *patterns = pango_fc_font_map_get_patterns (fontmap, context, description, NULL); - if (!patterns) - return NULL; - - if (patterns->n_patterns > 0) - return pango_fc_font_map_new_font (fontmap, patterns->patterns[0]); - - return NULL; -} - -static void -pango_fc_pattern_set_free (PangoFcPatternSet *patterns) -{ - int i; - - if (patterns->fontset) - g_object_remove_weak_pointer (G_OBJECT (patterns->fontset), - (gpointer *)&patterns->fontset); - - for (i = 0; i < patterns->n_patterns; i++) - FcPatternDestroy (patterns->patterns[i]); - - g_free (patterns->patterns); - g_free (patterns); -} - -static void -pango_fc_font_map_cache_fontset (PangoFcFontMap *fcfontmap, - PangoFcPatternSet *patterns) -{ - GQueue *cache = fcfontmap->fontset_cache; - - if (patterns->cache_link) - { - /* Already in cache, move to head - */ - if (patterns->cache_link == cache->tail) - cache->tail = patterns->cache_link->prev; - - cache->head = g_list_remove_link (cache->head, patterns->cache_link); - cache->length--; - } - else - { - /* Add to cache initially - */ - if (cache->length == FONTSET_CACHE_SIZE) - { - PangoFcPatternSet *tmp_patterns = g_queue_pop_tail (cache); - tmp_patterns->cache_link = NULL; - g_object_unref (tmp_patterns->fontset); - } - - g_object_ref (patterns->fontset); - patterns->cache_link = g_list_prepend (NULL, patterns); - } - - g_queue_push_head_link (cache, patterns->cache_link); -} - -static PangoFontset * -pango_fc_font_map_load_fontset (PangoFontMap *fontmap, - PangoContext *context, - const PangoFontDescription *desc, - PangoLanguage *language) -{ - int i; - PangoFcPatternSet *patterns = pango_fc_font_map_get_patterns (fontmap, context, desc, language); - PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (fontmap); - if (!patterns) - return NULL; - - if (!patterns->fontset) - { - PangoFontsetSimple *simple; - simple = pango_fontset_simple_new (language); - - for (i = 0; i < patterns->n_patterns; i++) - { - PangoFont *font = pango_fc_font_map_new_font (fontmap, patterns->patterns[i]); - if (font) - pango_fontset_simple_append (simple, font); - } - - patterns->fontset = PANGO_FONTSET (simple); - g_object_add_weak_pointer (G_OBJECT (patterns->fontset), - (gpointer *)&patterns->fontset); - } - else - g_object_ref (patterns->fontset); - - if (!patterns->cache_link || - patterns->cache_link != fcfontmap->fontset_cache->head) - pango_fc_font_map_cache_fontset (fcfontmap, patterns); - - return patterns->fontset; -} - -static void -uncache_patterns (PangoFcPatternSet *patterns) -{ - g_object_unref (patterns->fontset); -} - -static void -pango_fc_font_map_clear_fontset_cache (PangoFcFontMap *fcfontmap) -{ - GQueue *cache = fcfontmap->fontset_cache; - - g_list_foreach (cache->head, (GFunc)uncache_patterns, NULL); - g_list_free (cache->head); - cache->head = NULL; - cache->tail = NULL; - cache->length = 0; -} - -static void -pango_fc_font_map_cache_clear (PangoFcFontMap *fcfontmap) -{ - /* Clear the fontset cache first, since any entries - * in the fontset_cache must also be in the pattern cache. - */ - pango_fc_font_map_clear_fontset_cache (fcfontmap); - pango_fc_clear_pattern_hashes (fcfontmap); -} - -static void -pango_fc_font_map_set_coverage (PangoFcFontMap *fcfontmap, - PangoFcCoverageKey *key, - PangoCoverage *coverage) -{ - PangoFcCoverageKey *key_dup; - - key_dup = g_malloc (sizeof (PangoFcCoverageKey) + strlen (key->filename) + 1); - key_dup->id = key->id; - key_dup->filename = (char *) (key_dup + 1); - strcpy (key_dup->filename, key->filename); - - g_hash_table_insert (fcfontmap->coverage_hash, - key_dup, pango_coverage_ref (coverage)); -} - -PangoCoverage * -_pango_fc_font_map_get_coverage (PangoFontMap *fontmap, - FcPattern *pattern) -{ - PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (fontmap); - PangoFcCoverageKey key; - PangoCoverage *coverage; - FcChar32 map[FC_CHARSET_MAP_SIZE]; - FcChar32 ucs4, pos; - FcCharSet *charset; - int i; - - /* - * Assume that coverage information is identified by - * a filename/index pair; there shouldn't be any reason - * this isn't true, but it's not specified anywhere - */ - if (FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &key.filename) != FcResultMatch) - return NULL; - - if (FcPatternGetInteger (pattern, FC_INDEX, 0, &key.id) != FcResultMatch) - return NULL; - - coverage = g_hash_table_lookup (fcfontmap->coverage_hash, &key); - if (coverage) - return pango_coverage_ref (coverage); - - /* - * Pull the coverage out of the pattern, this - * doesn't require loading the font - */ - if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) - return NULL; - - /* - * Convert an Fc CharSet into a pango coverage structure. Sure - * would be nice to just use the Fc structure in place... - */ - coverage = pango_coverage_new (); - for (ucs4 = FcCharSetFirstPage (charset, map, &pos); - ucs4 != FC_CHARSET_DONE; - ucs4 = FcCharSetNextPage (charset, map, &pos)) - { - for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) - { - FcChar32 bits = map[i]; - FcChar32 base = ucs4 + i * 32; - int b = 0; - bits = map[i]; - while (bits) - { - if (bits & 1) - pango_coverage_set (coverage, base + b, PANGO_COVERAGE_EXACT); - - bits >>= 1; - b++; - } - } - } - - /* Awful hack so Hangul Tone marks get rendered with the same - * font and in the same run as other Hangul characters. If a font - * covers the first composed Hangul glyph, then it is declared to cover - * the Hangul tone marks. This hack probably needs to be formalized - * by choosing fonts for scripts rather than individual code points. - */ - if (pango_coverage_get (coverage, 0xac00) == PANGO_COVERAGE_EXACT) - { - pango_coverage_set (coverage, 0x302e, PANGO_COVERAGE_EXACT); - pango_coverage_set (coverage, 0x302f, PANGO_COVERAGE_EXACT); - } - - pango_fc_font_map_set_coverage (fcfontmap, &key, coverage); - - return coverage; -} - -/* - * PangoFcFace - */ - -PangoFontDescription * -_pango_fc_font_desc_from_pattern (FcPattern *pattern, gboolean include_size) -{ - PangoFontDescription *desc; - PangoStyle style; - PangoWeight weight; - double size; - - char *s; - int i; - - desc = pango_font_description_new (); - - g_assert (FcPatternGetString (pattern, FC_FAMILY, 0, (FcChar8 **) &s) == FcResultMatch); - - pango_font_description_set_family (desc, s); - - if (FcPatternGetInteger (pattern, FC_SLANT, 0, &i) == FcResultMatch) - { - if (i == FC_SLANT_ROMAN) - style = PANGO_STYLE_NORMAL; - else if (i == FC_SLANT_OBLIQUE) - style = PANGO_STYLE_OBLIQUE; - else - style = PANGO_STYLE_ITALIC; - } - else - style = PANGO_STYLE_NORMAL; - - pango_font_description_set_style (desc, style); - - if (FcPatternGetInteger (pattern, FC_WEIGHT, 0, &i) == FcResultMatch) - { - if (i < FC_WEIGHT_LIGHT) - weight = PANGO_WEIGHT_ULTRALIGHT; - else if (i < (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2) - weight = PANGO_WEIGHT_LIGHT; - else if (i < (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2) - weight = PANGO_WEIGHT_NORMAL; - else if (i < (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2) - weight = 600; - else if (i < (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2) - weight = PANGO_WEIGHT_BOLD; - else - weight = PANGO_WEIGHT_ULTRABOLD; - } - else - weight = PANGO_WEIGHT_NORMAL; - - if (include_size && FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch) - pango_font_description_set_size (desc, size * PANGO_SCALE); - - pango_font_description_set_weight (desc, weight); - - pango_font_description_set_variant (desc, PANGO_VARIANT_NORMAL); - pango_font_description_set_stretch (desc, PANGO_STRETCH_NORMAL); - - return desc; -} - -static PangoFontDescription * -make_alias_description (PangoFcFamily *fcfamily, - gboolean bold, - gboolean italic) -{ - PangoFontDescription *desc = pango_font_description_new (); - - pango_font_description_set_family (desc, fcfamily->family_name); - pango_font_description_set_style (desc, italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); - pango_font_description_set_variant (desc, PANGO_VARIANT_NORMAL); - pango_font_description_set_weight (desc, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL); - pango_font_description_set_stretch (desc, PANGO_STRETCH_NORMAL); - - return desc; -} - -static PangoFontDescription * -pango_fc_face_describe (PangoFontFace *face) -{ - PangoFcFace *fcface = PANGO_FC_FACE (face); - PangoFcFamily *fcfamily = fcface->family; - PangoFontDescription *desc = NULL; - FcResult res; - FcPattern *match_pattern; - FcPattern *result_pattern; - - if (is_alias_family (fcfamily->family_name)) - { - if (strcmp (fcface->style, "Regular") == 0) - return make_alias_description (fcfamily, FALSE, FALSE); - else if (strcmp (fcface->style, "Bold") == 0) - return make_alias_description (fcfamily, TRUE, FALSE); - else if (strcmp (fcface->style, "Italic") == 0) - return make_alias_description (fcfamily, FALSE, TRUE); - else /* Bold Italic */ - return make_alias_description (fcfamily, TRUE, TRUE); - } - - match_pattern = FcPatternBuild (NULL, - FC_FAMILY, FcTypeString, fcfamily->family_name, - FC_STYLE, FcTypeString, fcface->style, - NULL); - - g_assert (match_pattern); - - result_pattern = FcFontMatch (NULL, match_pattern, &res); - if (result_pattern) - { - desc = _pango_fc_font_desc_from_pattern (result_pattern, FALSE); - FcPatternDestroy (result_pattern); - } - - FcPatternDestroy (match_pattern); - - return desc; -} - -static const char * -pango_fc_face_get_face_name (PangoFontFace *face) -{ - PangoFcFace *fcface = PANGO_FC_FACE (face); - - return fcface->style; -} - -static void -pango_fc_face_class_init (PangoFontFaceClass *class) -{ - class->describe = pango_fc_face_describe; - class->get_face_name = pango_fc_face_get_face_name; -} - -static GType -pango_fc_face_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = - { - sizeof (PangoFontFaceClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) pango_fc_face_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PangoFcFace), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, - PANGO_FC_NAME "Face", - &object_info, 0); - } - - return object_type; -} - -/* - * PangoFcFamily - */ -static PangoFcFace * -create_face (PangoFcFamily *fcfamily, - const char *style) -{ - PangoFcFace *face = g_object_new (PANGO_FC_TYPE_FACE, NULL); - face->style = g_strdup (style); - face->family = fcfamily; - - return face; -} - -static void -pango_fc_family_list_faces (PangoFontFamily *family, - PangoFontFace ***faces, - int *n_faces) -{ - PangoFcFamily *fcfamily = PANGO_FC_FAMILY (family); - PangoFcFontMap *fcfontmap = fcfamily->fontmap; - - if (fcfamily->n_faces < 0) - { - FcFontSet *fontset; - int i; - - if (is_alias_family (fcfamily->family_name) || fcfontmap->closed) - { - fcfamily->n_faces = 4; - fcfamily->faces = g_new (PangoFcFace *, fcfamily->n_faces); - - i = 0; - fcfamily->faces[i++] = create_face (fcfamily, "Regular"); - fcfamily->faces[i++] = create_face (fcfamily, "Bold"); - fcfamily->faces[i++] = create_face (fcfamily, "Italic"); - fcfamily->faces[i++] = create_face (fcfamily, "Bold Italic"); - } - else - { - FcObjectSet *os = FcObjectSetBuild (FC_STYLE, NULL); - FcPattern *pat = FcPatternBuild (NULL, - FC_FAMILY, FcTypeString, fcfamily->family_name, - NULL); - - fontset = FcFontList (NULL, pat, os); - - FcPatternDestroy (pat); - FcObjectSetDestroy (os); - - fcfamily->n_faces = fontset->nfont; - fcfamily->faces = g_new (PangoFcFace *, fcfamily->n_faces); - - for (i = 0; i < fontset->nfont; i++) - { - FcChar8 *s; - FcResult res; - - res = FcPatternGetString (fontset->fonts[i], FC_STYLE, 0, &s); - if (res != FcResultMatch) - s = "Regular"; - - fcfamily->faces[i] = create_face (fcfamily, s); - } - - FcFontSetDestroy (fontset); - } - } - - if (n_faces) - *n_faces = fcfamily->n_faces; - - if (faces) - *faces = g_memdup (fcfamily->faces, fcfamily->n_faces * sizeof (PangoFontFace *)); -} - -static const char * -pango_fc_family_get_name (PangoFontFamily *family) -{ - PangoFcFamily *fcfamily = PANGO_FC_FAMILY (family); - - return fcfamily->family_name; -} - -static void -pango_fc_family_class_init (PangoFontFamilyClass *class) -{ - class->list_faces = pango_fc_family_list_faces; - class->get_name = pango_fc_family_get_name; -} - -static void -pango_fc_family_init (PangoFcFamily *fcfamily) -{ - fcfamily->n_faces = -1; -} - -static GType -pango_fc_family_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = - { - sizeof (PangoFontFamilyClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) pango_fc_family_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PangoFcFamily), - 0, /* n_preallocs */ - (GInstanceInitFunc) pango_fc_family_init, - }; - - object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY, - PANGO_FC_NAME "Family", - &object_info, 0); - } - - return object_type; -} |