summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2009-01-28 22:08:18 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2009-01-28 22:08:18 +0000
commitb977724d2b8ed77829b3c7cd988b45db9b12090f (patch)
treefde725224adc157e1ccc3b072bf6737572f3360f
parent042b6e674a82f7749c9762170aef4b5fb52a4f05 (diff)
downloadpango-b977724d2b8ed77829b3c7cd988b45db9b12090f.tar.gz
Bug 566727 – PangoFontsetLazy
2009-01-27 Behdad Esfahbod <behdad@gnome.org> Bug 566727 – PangoFontsetLazy * pango/pangofc-fontmap.c: Rework caching. Cache FcFontSort results separately from PangoFontset's. Add PangoFcFontset which is lazy and does not create fonts until it really needs to. Use FcFontMatch() and only do FcFontSort() if fallback fonts are needed. svn path=/trunk/; revision=2809
-rw-r--r--ChangeLog14
-rw-r--r--pango/pango-fontset.c3
-rw-r--r--pango/pangofc-font.c3
-rw-r--r--pango/pangofc-fontmap.c1097
-rw-r--r--pango/pangofc-fontmap.h8
5 files changed, 671 insertions, 454 deletions
diff --git a/ChangeLog b/ChangeLog
index 8cd6d03e..34dd195e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2009-01-27 Behdad Esfahbod <behdad@gnome.org>
+
+ Bug 566727 – PangoFontsetLazy
+
+ * pango/pangofc-fontmap.c: Rework caching.
+
+ Cache FcFontSort results separately from PangoFontset's.
+
+ Add PangoFcFontset which is lazy and does not create fonts until it
+ really needs to.
+
+ Use FcFontMatch() and only do FcFontSort() if fallback fonts are
+ needed.
+
2009-01-16 Behdad Esfahbod <behdad@gnome.org>
* docs/pango-sections.txt:
diff --git a/pango/pango-fontset.c b/pango/pango-fontset.c
index 62b27aed..ce1eb33d 100644
--- a/pango/pango-fontset.c
+++ b/pango/pango-fontset.c
@@ -382,6 +382,9 @@ pango_fontset_simple_get_font (PangoFontset *fontset,
}
}
+ if (G_UNLIKELY (result == -1))
+ return NULL;
+
font = g_ptr_array_index(simple->fonts, result);
return g_object_ref (font);
}
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 64199239..133a4df4 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -754,6 +754,9 @@ _pango_fc_font_shutdown (PangoFcFont *font)
if (PANGO_FC_FONT_GET_CLASS (font)->shutdown)
PANGO_FC_FONT_GET_CLASS (font)->shutdown (font);
+
+ if (font->fontmap)
+ _pango_fc_font_map_remove (PANGO_FC_FONT_MAP (font->fontmap), font);
}
/**
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 07ede5ee..cc742392 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -19,7 +19,6 @@
* Boston, MA 02111-1307, USA.
*/
-/* Size of fontset cache */
#define FONTSET_CACHE_SIZE 64
#include "config.h"
@@ -35,30 +34,37 @@
typedef struct _PangoFcCoverageKey PangoFcCoverageKey;
typedef struct _PangoFcFace PangoFcFace;
typedef struct _PangoFcFamily PangoFcFamily;
-typedef struct _PangoFcPatternSet PangoFcPatternSet;
typedef struct _PangoFcFindFuncInfo PangoFcFindFuncInfo;
+typedef struct _PangoFcPatterns PangoFcPatterns;
+typedef struct _PangoFcFontset PangoFcFontset;
-#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_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))
+#define PANGO_FC_TYPE_FONTSET (pango_fc_fontset_get_type ())
+#define PANGO_FC_FONTSET(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FC_TYPE_FONTSET, PangoFcFontset))
+#define PANGO_FC_IS_FONTSET(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_FC_TYPE_FONTSET))
+
struct _PangoFcFontMapPrivate
{
- GHashTable *fontset_hash; /* Maps PangoFontDescription -> PangoFcPatternSet */
+ GHashTable *fontset_hash; /* Maps PangoFcFontsetKey -> PangoFcFontset */
+ GQueue *fontset_cache; /* Recently used fontsets */
+
+ GHashTable *font_hash; /* Maps PangoFcFontKey -> PangoFcFont */
+
+ GHashTable *patterns_hash; /* Maps FcPattern -> PangoFcPatterns */
/* pattern_hash is used to make sure we only store one copy of
* each identical pattern. (Speeds up lookup).
*/
GHashTable *pattern_hash;
- GHashTable *coverage_hash; /* Maps font file name/id -> PangoCoverage */
-
- GHashTable *font_hash; /* Maps FcPattern -> PangoFcFont */
- GQueue *fontset_cache; /* Recently used fontsets */
+ GHashTable *coverage_hash; /* Maps font file name/id -> PangoCoverage */
/* List of all families availible */
PangoFcFamily **families;
@@ -101,16 +107,6 @@ struct _PangoFcFamily
int spacing; /* FC_SPACING */
};
-struct _PangoFcPatternSet
-{
- int n_patterns;
- FcPattern **patterns;
- PangoFontset *fontset;
- GList *cache_link;
-
- PangoFcFontsetKey *key;
-};
-
struct _PangoFcFindFuncInfo
{
PangoFcDecoderFindFunc findfunc;
@@ -121,6 +117,7 @@ struct _PangoFcFindFuncInfo
static GType pango_fc_family_get_type (void);
static GType pango_fc_face_get_type (void);
+static GType pango_fc_fontset_get_type (void);
static void pango_fc_font_map_finalize (GObject *object);
static PangoFont * pango_fc_font_map_load_font (PangoFontMap *fontmap,
@@ -136,28 +133,44 @@ static void pango_fc_font_map_list_families (PangoFontMap
static double pango_fc_font_map_get_resolution (PangoFcFontMap *fcfontmap,
PangoContext *context);
+static PangoFont *pango_fc_font_map_new_font (PangoFcFontMap *fontmap,
+ PangoFcFontsetKey *fontset_key,
+ FcPattern *match);
-static void pango_fc_font_map_cache_fontset (PangoFcFontMap *fcfontmap,
- PangoFcPatternSet *patterns);
-
-static void pango_fc_pattern_set_free (PangoFcPatternSet *patterns);
-
-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 guint pango_fc_font_key_hash (const PangoFcFontKey *key);
-static gboolean pango_fc_font_key_equal (const PangoFcFontKey *key_a,
- const PangoFcFontKey *key_b);
-static void pango_fc_font_key_free (PangoFcFontKey *key);
-
-static guint pango_fc_fontset_key_hash (const PangoFcFontsetKey *key);
-static gboolean pango_fc_fontset_key_equal (const PangoFcFontsetKey *key_a,
- const PangoFcFontsetKey *key_b);
-static void pango_fc_fontset_key_free (PangoFcFontsetKey *key);
+static void pango_fc_fontset_key_init (PangoFcFontsetKey *key,
+ PangoFcFontMap *fcfontmap,
+ PangoContext *context,
+ const PangoFontDescription *desc,
+ PangoLanguage *language);
+static PangoFcFontsetKey *pango_fc_fontset_key_copy (const PangoFcFontsetKey *key);
+static void pango_fc_fontset_key_free (PangoFcFontsetKey *key);
+static guint pango_fc_fontset_key_hash (const PangoFcFontsetKey *key);
+static gboolean pango_fc_fontset_key_equal (const PangoFcFontsetKey *key_a,
+ const PangoFcFontsetKey *key_b);
+
+static void pango_fc_font_key_init (PangoFcFontKey *key,
+ PangoFcFontMap *fcfontmap,
+ PangoFcFontsetKey *fontset_key,
+ FcPattern *pattern);
+static PangoFcFontKey *pango_fc_font_key_copy (const PangoFcFontKey *key);
+static void pango_fc_font_key_free (PangoFcFontKey *key);
+static guint pango_fc_font_key_hash (const PangoFcFontKey *key);
+static gboolean pango_fc_font_key_equal (const PangoFcFontKey *key_a,
+ const PangoFcFontKey *key_b);
+
+static PangoFcPatterns *pango_fc_patterns_new (FcPattern *pat,
+ PangoFcFontMap *fontmap);
+static PangoFcPatterns *pango_fc_patterns_ref (PangoFcPatterns *pats);
+static void pango_fc_patterns_unref (PangoFcPatterns *pats);
+static FcPattern *pango_fc_patterns_get_pattern (PangoFcPatterns *pats);
+static FcPattern *pango_fc_patterns_get_font_pattern (PangoFcPatterns *pats, int i);
+
+static FcPattern *uniquify_pattern (PangoFcFontMap *fcfontmap,
+ FcPattern *pattern);
static gpointer
get_gravity_class (void)
@@ -171,43 +184,6 @@ get_gravity_class (void)
}
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;
@@ -243,6 +219,37 @@ hash_bytes_fnv (unsigned char *buffer,
return hval;
}
+static void
+get_context_matrix (PangoContext *context,
+ PangoMatrix *matrix)
+{
+ const PangoMatrix *set_matrix;
+ static const PangoMatrix identity = PANGO_MATRIX_INIT;
+
+ set_matrix = context ? pango_context_get_matrix (context) : NULL;
+ *matrix = set_matrix ? *set_matrix : identity;
+ matrix->x0 = matrix->y0 = 0.;
+}
+
+static int
+get_scaled_size (PangoFcFontMap *fcfontmap,
+ PangoContext *context,
+ const PangoFontDescription *desc)
+{
+ double size = pango_font_description_get_size (desc);
+
+ if (!pango_font_description_get_size_is_absolute (desc))
+ {
+ double dpi = pango_fc_font_map_get_resolution (fcfontmap, context);
+
+ size = size * dpi / 72.;
+ }
+
+ return .5 + pango_matrix_get_font_scale_factor (pango_context_get_matrix (context)) * size;
+}
+
+
+
struct _PangoFcFontsetKey {
PangoFcFontMap *fontmap;
PangoLanguage *language;
@@ -255,11 +262,35 @@ struct _PangoFcFontsetKey {
struct _PangoFcFontKey {
PangoFcFontMap *fontmap;
- const FcPattern *pattern;
+ FcPattern *pattern;
PangoMatrix matrix;
gpointer context_key;
};
+static void
+pango_fc_fontset_key_init (PangoFcFontsetKey *key,
+ PangoFcFontMap *fcfontmap,
+ PangoContext *context,
+ const PangoFontDescription *desc,
+ PangoLanguage *language)
+{
+ if (!language && context)
+ language = pango_context_get_language (context);
+
+ key->fontmap = fcfontmap;
+ get_context_matrix (context, &key->matrix);
+ key->pixelsize = get_scaled_size (fcfontmap, context, desc);
+ key->resolution = pango_fc_font_map_get_resolution (fcfontmap, context);
+ key->language = language;
+ key->desc = pango_font_description_copy_static (desc);
+ pango_font_description_unset_fields (key->desc, PANGO_FONT_MASK_SIZE);
+
+ if (context && PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get)
+ key->context_key = (gpointer)PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
+ else
+ key->context_key = NULL;
+}
+
static gboolean
pango_fc_fontset_key_equal (const PangoFcFontsetKey *key_a,
const PangoFcFontsetKey *key_b)
@@ -314,7 +345,7 @@ pango_fc_fontset_key_free (PangoFcFontsetKey *key)
}
static PangoFcFontsetKey *
-pango_fc_fontset_key_copy (PangoFcFontsetKey *old)
+pango_fc_fontset_key_copy (const PangoFcFontsetKey *old)
{
PangoFcFontsetKey *key = g_slice_new (PangoFcFontsetKey);
@@ -343,8 +374,8 @@ pango_fc_fontset_key_copy (PangoFcFontsetKey *old)
*
* Since: 1.24
**/
-const PangoLanguage *
-pango_fc_fontset_key_get_language (const PangoFcFontsetKey *key)
+PangoLanguage *
+pango_fc_fontset_key_get_language (const PangoFcFontsetKey *key)
{
return key->language;
}
@@ -470,6 +501,9 @@ pango_fc_font_key_hash (const PangoFcFontKey *key)
static void
pango_fc_font_key_free (PangoFcFontKey *key)
{
+ if (key->pattern)
+ FcPatternDestroy (key->pattern);
+
if (key->context_key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
key->context_key);
@@ -478,11 +512,12 @@ pango_fc_font_key_free (PangoFcFontKey *key)
}
static PangoFcFontKey *
-pango_fc_font_key_copy (PangoFcFontKey *old)
+pango_fc_font_key_copy (const PangoFcFontKey *old)
{
PangoFcFontKey *key = g_slice_new (PangoFcFontKey);
key->fontmap = old->fontmap;
+ FcPatternReference (old->pattern);
key->pattern = old->pattern;
key->matrix = old->matrix;
if (old->context_key)
@@ -495,32 +530,15 @@ pango_fc_font_key_copy (PangoFcFontKey *old)
}
static void
-get_context_matrix (PangoContext *context,
- PangoMatrix *matrix)
-{
- const PangoMatrix *set_matrix;
- static const PangoMatrix identity = PANGO_MATRIX_INIT;
-
- set_matrix = context ? pango_context_get_matrix (context) : NULL;
- *matrix = set_matrix ? *set_matrix : identity;
-}
-
-static void
-pango_fc_font_key_init (PangoFcFontKey *key,
- PangoFcFontMap *fcfontmap,
- PangoContext *context,
- const FcPattern *pattern)
+pango_fc_font_key_init (PangoFcFontKey *key,
+ PangoFcFontMap *fcfontmap,
+ PangoFcFontsetKey *fontset_key,
+ FcPattern *pattern)
{
key->fontmap = fcfontmap;
key->pattern = pattern;
-
- get_context_matrix (context, &key->matrix);
- key->matrix.x0 = key->matrix.y0 = 0.;
-
- if (PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get)
- key->context_key = (gpointer)PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
- else
- key->context_key = NULL;
+ key->matrix = *pango_fc_fontset_key_get_matrix (fontset_key);
+ key->context_key = pango_fc_fontset_key_get_context_key (fontset_key);
}
/* Public API */
@@ -575,6 +593,347 @@ pango_fc_font_key_get_context_key (const PangoFcFontKey *key)
/*
+ * PangoFcPatterns
+ */
+
+struct _PangoFcPatterns {
+ guint ref_count;
+
+ PangoFcFontMap *fontmap;
+
+ FcPattern *pattern;
+ FcPattern *match;
+ FcFontSet *fontset;
+};
+
+static PangoFcPatterns *
+pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap)
+{
+ PangoFcPatterns *pats;
+
+ pat = uniquify_pattern (fontmap, pat);
+ pats = g_hash_table_lookup (fontmap->priv->patterns_hash, pat);
+ if (pats)
+ return pango_fc_patterns_ref (pats);
+
+ pats = g_slice_new0 (PangoFcPatterns);
+
+ pats->fontmap = fontmap;
+
+ pats->ref_count = 1;
+ FcPatternReference (pat);
+ pats->pattern = pat;
+
+ g_hash_table_insert (fontmap->priv->patterns_hash,
+ pats->pattern, pats);
+
+ return pats;
+}
+
+static PangoFcPatterns *
+pango_fc_patterns_ref (PangoFcPatterns *pats)
+{
+ g_return_val_if_fail (pats->ref_count > 0, NULL);
+
+ pats->ref_count++;
+
+ return pats;
+}
+
+static void
+pango_fc_patterns_unref (PangoFcPatterns *pats)
+{
+ g_return_if_fail (pats->ref_count > 0);
+
+ pats->ref_count--;
+
+ if (pats->ref_count)
+ return;
+
+ /* Only remove from fontmap hash if we are in it. This is not necessarily
+ * the case after a cache_clear() call. */
+ if (pats->fontmap->priv->patterns_hash &&
+ pats == g_hash_table_lookup (pats->fontmap->priv->patterns_hash, pats->pattern))
+ g_hash_table_remove (pats->fontmap->priv->patterns_hash,
+ pats->pattern);
+
+ if (pats->pattern)
+ FcPatternDestroy (pats->pattern);
+
+ if (pats->match)
+ FcPatternDestroy (pats->match);
+
+ if (pats->fontset)
+ FcFontSetDestroy (pats->fontset);
+
+ g_slice_free (PangoFcPatterns, pats);
+}
+
+static FcPattern *
+pango_fc_patterns_get_pattern (PangoFcPatterns *pats)
+{
+ return pats->pattern;
+}
+
+static FcPattern *
+pango_fc_patterns_get_font_pattern (PangoFcPatterns *pats, int i)
+{
+ if (i == 0)
+ {
+ FcResult result;
+ if (!pats->match && !pats->fontset)
+ {
+ pats->match = FcFontMatch (NULL, pats->pattern, &result);
+ }
+
+ if (pats->match)
+ return pats->match;
+ }
+ else
+ {
+ if (!pats->fontset)
+ {
+ FcResult result;
+ pats->fontset = FcFontSort (NULL, pats->pattern, FcTrue, NULL, &result);
+ if (pats->match)
+ {
+ FcPatternDestroy (pats->match);
+ pats->match = NULL;
+ }
+ }
+ }
+
+ if (i < pats->fontset->nfont)
+ return pats->fontset->fonts[i];
+ else
+ return NULL;
+}
+
+
+/*
+ * PangoFcFontset
+ */
+
+static void pango_fc_fontset_finalize (GObject *object);
+static void pango_fc_fontset_init (PangoFcFontset *fontset);
+static PangoLanguage * pango_fc_fontset_get_language (PangoFontset *fontset);
+static PangoFont * pango_fc_fontset_get_font (PangoFontset *fontset,
+ guint wc);
+static void pango_fc_fontset_foreach (PangoFontset *fontset,
+ PangoFontsetForeachFunc func,
+ gpointer data);
+
+struct _PangoFcFontset
+{
+ PangoFontset parent_instance;
+
+ PangoFcFontsetKey *key;
+
+ PangoFcPatterns *patterns;
+ int patterns_i;
+
+ GPtrArray *fonts;
+ GPtrArray *coverages;
+
+ GList *cache_link;
+};
+
+typedef PangoFontsetClass PangoFcFontsetClass;
+
+static PangoFontsetClass *fc_fontset_parent_class; /* Parent class structure for PangoFcFontset */
+
+static PangoFcFontset *
+pango_fc_fontset_new (PangoFcFontsetKey *key,
+ PangoFcPatterns *patterns)
+{
+ PangoFcFontset *fontset;
+
+ fontset = g_object_new (PANGO_FC_TYPE_FONTSET, NULL);
+
+ fontset->key = pango_fc_fontset_key_copy (key);
+ fontset->patterns = pango_fc_patterns_ref (patterns);
+
+ return fontset;
+}
+
+static PangoFcFontsetKey *
+pango_fc_fontset_get_key (PangoFcFontset *fontset)
+{
+ return fontset->key;
+}
+
+static PangoFont *
+pango_fc_fontset_load_next_font (PangoFcFontset *fontset)
+{
+ FcPattern *pattern, *font_pattern;
+ PangoFont *font;
+
+ pattern = pango_fc_patterns_get_pattern (fontset->patterns),
+ font_pattern = pango_fc_patterns_get_font_pattern (fontset->patterns,
+ fontset->patterns_i++);
+ if (G_UNLIKELY (!font_pattern))
+ return NULL;
+
+ font_pattern = FcFontRenderPrepare (NULL, pattern, font_pattern);
+
+ if (G_UNLIKELY (!font_pattern))
+ return NULL;
+
+#ifdef FC_PATTERN
+ /* The FC_PATTERN element, which points back to our the original
+ * pattern defeats our hash tables.
+ */
+ FcPatternDel (font_pattern, FC_PATTERN);
+#endif /* FC_PATTERN */
+
+ font = pango_fc_font_map_new_font (fontset->key->fontmap,
+ fontset->key,
+ font_pattern);
+
+ FcPatternDestroy (font_pattern);
+
+ return font;
+}
+
+static PangoFont *
+pango_fc_fontset_get_font_at (PangoFcFontset *fontset,
+ unsigned int i)
+{
+ while (i >= fontset->fonts->len)
+ {
+ PangoFont *font = pango_fc_fontset_load_next_font (fontset);
+ g_ptr_array_add (fontset->fonts, font);
+ g_ptr_array_add (fontset->coverages, NULL);
+ if (!font)
+ return NULL;
+ }
+
+ return g_ptr_array_index (fontset->fonts, i);
+}
+
+static void
+pango_fc_fontset_class_init (PangoFcFontsetClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontsetClass *fontset_class = PANGO_FONTSET_CLASS (class);
+
+ fc_fontset_parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_fc_fontset_finalize;
+ fontset_class->get_font = pango_fc_fontset_get_font;
+ fontset_class->get_language = pango_fc_fontset_get_language;
+ fontset_class->foreach = pango_fc_fontset_foreach;
+}
+
+static void
+pango_fc_fontset_init (PangoFcFontset *fontset)
+{
+ fontset->fonts = g_ptr_array_new ();
+ fontset->coverages = g_ptr_array_new ();
+}
+
+static void
+pango_fc_fontset_finalize (GObject *object)
+{
+ PangoFcFontset *fontset = PANGO_FC_FONTSET (object);
+ unsigned int i;
+
+ for (i = 0; i < fontset->fonts->len; i++)
+ g_object_unref (g_ptr_array_index(fontset->fonts, i));
+ g_ptr_array_free (fontset->fonts, TRUE);
+
+ for (i = 0; i < fontset->coverages->len; i++)
+ {
+ PangoCoverage *coverage = g_ptr_array_index (fontset->coverages, i);
+ if (coverage)
+ pango_coverage_unref (coverage);
+ }
+ g_ptr_array_free (fontset->coverages, TRUE);
+
+ if (fontset->key)
+ pango_fc_fontset_key_free (fontset->key);
+
+ if (fontset->patterns)
+ pango_fc_patterns_unref (fontset->patterns);
+
+ G_OBJECT_CLASS (fc_fontset_parent_class)->finalize (object);
+}
+
+static PangoLanguage *
+pango_fc_fontset_get_language (PangoFontset *fontset)
+{
+ PangoFcFontset *fcfontset = PANGO_FC_FONTSET (fontset);
+
+ return pango_fc_fontset_key_get_language (pango_fc_fontset_get_key (fcfontset));
+}
+
+static PangoFont *
+pango_fc_fontset_get_font (PangoFontset *fontset,
+ guint wc)
+{
+ PangoFcFontset *fcfontset = PANGO_FC_FONTSET (fontset);
+ PangoCoverageLevel best_level = PANGO_COVERAGE_NONE;
+ PangoCoverageLevel level;
+ PangoFont *font;
+ PangoCoverage *coverage;
+ int result = -1;
+ unsigned int i;
+
+ for (i = 0;
+ (font = pango_fc_fontset_get_font_at (fcfontset, i));
+ i++)
+ {
+ coverage = g_ptr_array_index (fcfontset->coverages, i);
+
+ if (coverage == NULL)
+ {
+ font = g_ptr_array_index (fcfontset->fonts, i);
+
+ coverage = pango_font_get_coverage (font, fcfontset->key->language);
+ g_ptr_array_index (fcfontset->coverages, i) = coverage;
+ }
+
+ level = pango_coverage_get (coverage, wc);
+
+ if (result == -1 || level > best_level)
+ {
+ result = i;
+ best_level = level;
+ if (level == PANGO_COVERAGE_EXACT)
+ break;
+ }
+ }
+
+ if (G_UNLIKELY (result == -1))
+ return NULL;
+
+ font = g_ptr_array_index(fcfontset->fonts, result);
+ return g_object_ref (font);
+}
+
+static void
+pango_fc_fontset_foreach (PangoFontset *fontset,
+ PangoFontsetForeachFunc func,
+ gpointer data)
+{
+ PangoFcFontset *fcfontset = PANGO_FC_FONTSET (fontset);
+ PangoFont *font;
+ unsigned int i;
+
+ for (i = 0;
+ (font = pango_fc_fontset_get_font_at (fcfontset, i));
+ i++)
+ {
+ if ((*func) (fontset, font, data))
+ return;
+ }
+}
+
+static PANGO_DEFINE_TYPE (PangoFcFontset, pango_fc_fontset,
+ pango_fc_fontset_class_init, pango_fc_fontset_init,
+ PANGO_TYPE_FONTSET)
+
+/*
* PangoFcFontMap
*/
@@ -602,24 +961,64 @@ pango_fc_font_map_init (PangoFcFontMap *fcfontmap)
priv->n_families = -1;
- priv->font_hash = g_hash_table_new_full ((GHashFunc)pango_fc_font_key_hash,
- (GEqualFunc)pango_fc_font_key_equal,
- (GDestroyNotify)pango_fc_font_key_free,
- NULL);
+ priv->font_hash = g_hash_table_new ((GHashFunc)pango_fc_font_key_hash,
+ (GEqualFunc)pango_fc_font_key_equal);
+
priv->fontset_hash = g_hash_table_new_full ((GHashFunc)pango_fc_fontset_key_hash,
(GEqualFunc)pango_fc_fontset_key_equal,
- (GDestroyNotify)pango_fc_fontset_key_free,
- (GDestroyNotify)pango_fc_pattern_set_free);
+ NULL,
+ (GDestroyNotify)g_object_unref);
+ priv->fontset_cache = g_queue_new ();
+
+ priv->patterns_hash = g_hash_table_new (NULL, NULL);
+
+ priv->pattern_hash = g_hash_table_new_full ((GHashFunc) FcPatternHash,
+ (GEqualFunc) FcPatternEqual,
+ (GDestroyNotify) FcPatternDestroy,
+ NULL);
priv->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);
- priv->fontset_cache = g_queue_new ();
priv->dpi = -1;
}
static void
+pango_fc_font_map_fini (PangoFcFontMap *fcfontmap)
+{
+ PangoFcFontMapPrivate *priv = fcfontmap->priv;
+ int i;
+
+ g_queue_free (priv->fontset_cache);
+ priv->fontset_cache = NULL;
+
+ g_hash_table_destroy (priv->fontset_hash);
+ priv->fontset_hash = NULL;
+
+ g_hash_table_destroy (priv->patterns_hash);
+ priv->patterns_hash = NULL;
+
+ g_hash_table_destroy (priv->font_hash);
+ priv->font_hash = NULL;
+
+ g_hash_table_destroy (priv->coverage_hash);
+ priv->coverage_hash = NULL;
+
+ g_hash_table_destroy (priv->pattern_hash);
+ priv->pattern_hash = NULL;
+
+ for (i = 0; i < priv->n_families; i++)
+ {
+ priv->families[i]->fontmap = NULL;
+ g_object_unref (priv->families[i]);
+ }
+ g_free (priv->families);
+ priv->n_families = -1;
+ priv->families = NULL;
+}
+
+static void
pango_fc_font_map_class_init (PangoFcFontMapClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
@@ -674,40 +1073,13 @@ static void
pango_fc_font_map_finalize (GObject *object)
{
PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (object);
- PangoFcFontMapPrivate *priv = fcfontmap->priv;
- int i;
- /* Shutdown, so we clear the fonts and mark them as shut down */
pango_fc_font_map_shutdown (fcfontmap);
- g_queue_free (priv->fontset_cache);
- g_hash_table_destroy (priv->coverage_hash);
-
- if (priv->pattern_hash)
- g_hash_table_destroy (priv->pattern_hash);
-
- while (priv->findfuncs)
- {
- PangoFcFindFuncInfo *info;
- info = priv->findfuncs->data;
- if (info->dnotify)
- info->dnotify (info->user_data);
-
- g_slice_free (PangoFcFindFuncInfo, info);
- priv->findfuncs = g_slist_delete_link (priv->findfuncs, priv->findfuncs);
- }
-
- for (i = 0; i < priv->n_families; i++)
- {
- priv->families[i]->fontmap = NULL;
- g_object_unref (priv->families[i]);
- }
- g_free (priv->families);
-
G_OBJECT_CLASS (pango_fc_font_map_parent_class)->finalize (object);
}
-/* Add a mapping from fcfont->font_pattern to fcfont */
+/* Add a mapping from key to fcfont */
static void
pango_fc_font_map_add (PangoFcFontMap *fcfontmap,
PangoFcFontKey *key,
@@ -725,12 +1097,10 @@ pango_fc_font_map_add (PangoFcFontMap *fcfontmap,
key_copy = pango_fc_font_key_copy (key);
_pango_fc_font_set_font_key (fcfont, key_copy);
- fcfont->matrix = key_copy->matrix;
-
g_hash_table_insert (priv->font_hash, key_copy, fcfont);
}
-/* Remove mapping from fcfont->font_pattern to fcfont */
+/* Remove mapping from fcfont->key to fcfont */
void
_pango_fc_font_map_remove (PangoFcFontMap *fcfontmap,
PangoFcFont *fcfont)
@@ -738,11 +1108,21 @@ _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap,
PangoFcFontMapPrivate *priv = fcfontmap->priv;
PangoFcFontKey *key;
+ fcfont->fontmap = NULL;
+
key = _pango_fc_font_get_font_key (fcfont);
if (key)
- g_hash_table_remove (priv->font_hash, key);
- fcfont->fontmap = NULL;
- _pango_fc_font_set_font_key (fcfont, NULL);
+ {
+ /* Only remove from fontmap hash if we are in it. This is not necessarily
+ * the case after a cache_clear() call. */
+ if (priv->font_hash &&
+ fcfont == g_hash_table_lookup (priv->font_hash, key))
+ {
+ g_hash_table_remove (priv->font_hash, key);
+ }
+ _pango_fc_font_set_font_key (fcfont, NULL);
+ pango_fc_font_key_free (key);
+ }
}
static PangoFcFamily *
@@ -998,13 +1378,32 @@ pango_fc_make_pattern (const PangoFontDescription *description,
return pattern;
}
+static FcPattern *
+uniquify_pattern (PangoFcFontMap *fcfontmap,
+ FcPattern *pattern)
+{
+ PangoFcFontMapPrivate *priv = fcfontmap->priv;
+ FcPattern *old_pattern;
+
+ old_pattern = g_hash_table_lookup (priv->pattern_hash, pattern);
+ if (old_pattern)
+ {
+ return old_pattern;
+ }
+ else
+ {
+ FcPatternReference (pattern);
+ g_hash_table_insert (priv->pattern_hash, pattern, pattern);
+ return pattern;
+ }
+}
+
static PangoFont *
-pango_fc_font_map_new_font (PangoFontMap *fontmap,
- PangoContext *context,
- FcPattern *match)
+pango_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
+ PangoFcFontsetKey *fontset_key,
+ FcPattern *match)
{
PangoFcFontMapClass *class;
- PangoFcFontMap *fcfontmap = (PangoFcFontMap *)fontmap;
PangoFcFontMapPrivate *priv = fcfontmap->priv;
FcPattern *pattern;
PangoFcFont *fcfont;
@@ -1014,60 +1413,51 @@ pango_fc_font_map_new_font (PangoFontMap *fontmap,
if (priv->closed)
return NULL;
- pango_fc_font_key_init (&key, fcfontmap, context, match);
+ match = uniquify_pattern (fcfontmap, match);
+
+ pango_fc_font_key_init (&key, fcfontmap, fontset_key, match);
fcfont = g_hash_table_lookup (priv->font_hash, &key);
if (fcfont)
return g_object_ref (fcfont);
- class = PANGO_FC_FONT_MAP_GET_CLASS (fontmap);
+ class = PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap);
if (class->create_font)
{
- fcfont = PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->create_font (fcfontmap,
- &key);
+ fcfont = class->create_font (fcfontmap, &key);
}
else
{
- const PangoMatrix *pango_matrix;
-
- if (context)
- pango_matrix = pango_context_get_matrix (context);
- else
- pango_matrix = NULL;
-
- if (pango_matrix)
- {
- FcMatrix fc_matrix, *fc_matrix_val;
- int i;
+ const PangoMatrix *pango_matrix = pango_fc_fontset_key_get_matrix (fontset_key);
+ FcMatrix fc_matrix, *fc_matrix_val;
+ int i;
- /* Fontconfig has the Y axis pointing up, Pango, down.
- */
- fc_matrix.xx = pango_matrix->xx;
- fc_matrix.xy = - pango_matrix->xy;
- fc_matrix.yx = - pango_matrix->yx;
- fc_matrix.yy = pango_matrix->yy;
+ /* Fontconfig has the Y axis pointing up, Pango, down.
+ */
+ fc_matrix.xx = pango_matrix->xx;
+ fc_matrix.xy = - pango_matrix->xy;
+ fc_matrix.yx = - pango_matrix->yx;
+ fc_matrix.yy = pango_matrix->yy;
- pattern = FcPatternDuplicate (match);
+ pattern = FcPatternDuplicate (match);
- for (i = 0; FcPatternGetMatrix (pattern, FC_MATRIX, i, &fc_matrix_val) == FcResultMatch; i++)
- FcMatrixMultiply (&fc_matrix, &fc_matrix, fc_matrix_val);
+ for (i = 0; FcPatternGetMatrix (pattern, FC_MATRIX, i, &fc_matrix_val) == FcResultMatch; i++)
+ FcMatrixMultiply (&fc_matrix, &fc_matrix, fc_matrix_val);
- FcPatternDel (pattern, FC_MATRIX);
- FcPatternAddMatrix (pattern, FC_MATRIX, &fc_matrix);
- }
- else
- pattern = match;
+ FcPatternDel (pattern, FC_MATRIX);
+ FcPatternAddMatrix (pattern, FC_MATRIX, &fc_matrix);
- fcfont = PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->new_font (fcfontmap, pattern);
+ fcfont = class->new_font (fcfontmap, uniquify_pattern (fcfontmap, pattern));
- if (pango_matrix)
- FcPatternDestroy (pattern);
+ FcPatternDestroy (pattern);
}
if (!fcfont)
return NULL;
+ fcfont->matrix = key.matrix;
+
pango_fc_font_map_add (fcfontmap, &key, fcfont);
/*
@@ -1090,34 +1480,6 @@ pango_fc_font_map_new_font (PangoFontMap *fontmap,
return (PangoFont *)fcfont;
}
-static FcPattern *
-uniquify_pattern (PangoFcFontMap *fcfontmap,
- FcPattern *pattern)
-{
- PangoFcFontMapPrivate *priv = fcfontmap->priv;
- FcPattern *old_pattern;
-
- if (G_UNLIKELY (!priv->pattern_hash))
- priv->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 (priv->pattern_hash, pattern);
- if (old_pattern)
- {
- FcPatternDestroy (pattern);
- FcPatternReference (old_pattern);
- return old_pattern;
- }
- else
- {
- FcPatternReference (pattern);
- g_hash_table_insert (priv->pattern_hash, pattern, pattern);
- return pattern;
- }
-}
-
static void
pango_fc_default_substitute (PangoFcFontMap *fontmap,
PangoFcFontsetKey *fontsetkey,
@@ -1160,23 +1522,6 @@ pango_fc_font_map_get_resolution (PangoFcFontMap *fcfontmap,
return fcfontmap->priv->dpi;
}
-static int
-get_scaled_size (PangoFcFontMap *fcfontmap,
- PangoContext *context,
- const PangoFontDescription *desc)
-{
- double size = pango_font_description_get_size (desc);
-
- if (!pango_font_description_get_size_is_absolute (desc))
- {
- double dpi = pango_fc_font_map_get_resolution (fcfontmap, context);
-
- size = size * dpi / 72.;
- }
-
- return .5 + pango_matrix_get_font_scale_factor (pango_context_get_matrix (context)) * size;
-}
-
static FcPattern *
pango_fc_fontset_key_make_pattern (PangoFcFontsetKey *key)
{
@@ -1186,98 +1531,20 @@ pango_fc_fontset_key_make_pattern (PangoFcFontsetKey *key)
key->resolution);
}
-static PangoFcPatternSet *
-pango_fc_font_map_get_patterns (PangoFontMap *fontmap,
- PangoContext *context,
- const PangoFontDescription *desc,
- PangoLanguage *language)
+static PangoFcPatterns *
+pango_fc_font_map_get_patterns (PangoFontMap *fontmap,
+ PangoFcFontsetKey *key)
{
PangoFcFontMap *fcfontmap = (PangoFcFontMap *)fontmap;
- PangoFcFontMapPrivate *priv = fcfontmap->priv;
- FcPattern *pattern, *font_pattern;
- FcResult res;
- int f;
- PangoFcPatternSet *patterns;
- FcFontSet *font_patterns;
- PangoFcFontsetKey key;
-
- if (!language && context)
- language = pango_context_get_language (context);
-
- key.fontmap = fcfontmap;
- get_context_matrix (context, &key.matrix);
- key.pixelsize = get_scaled_size (fcfontmap, context, desc);
- key.resolution = pango_fc_font_map_get_resolution (fcfontmap, context);
- key.language = language;
- key.desc = pango_font_description_copy_static (desc);
- pango_font_description_unset_fields (key.desc, PANGO_FONT_MASK_SIZE);
-
- if (context && PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get)
- key.context_key = (gpointer)PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
- else
- key.context_key = NULL;
-
- patterns = g_hash_table_lookup (priv->fontset_hash, &key);
-
- if (patterns == NULL)
- {
- pattern = pango_fc_fontset_key_make_pattern (&key);
-
- pango_fc_default_substitute (fcfontmap, &key, pattern);
-
- font_patterns = FcFontSort (NULL, pattern, FcTrue, NULL, &res);
-
- if (!font_patterns)
- {
- g_critical ("No fonts found:\n"
- "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");
-
- font_patterns = FcFontSetCreate ();
- }
-
- patterns = g_slice_new (PangoFcPatternSet);
- 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]);
-
- if (font_pattern)
- {
-#ifdef FC_PATTERN
- /* The FC_PATTERN element, which points back to our the original
- * pattern defeats our hash tables.
- */
- FcPatternDel (font_pattern, FC_PATTERN);
-#endif /* FC_PATTERN */
-
- patterns->patterns[patterns->n_patterns++] = uniquify_pattern (fcfontmap, font_pattern);
- }
- }
-
- FcPatternDestroy (pattern);
-
- FcFontSetDestroy (font_patterns);
+ PangoFcPatterns *patterns;
+ FcPattern *pattern;
- patterns->key = pango_fc_fontset_key_copy (&key);
- g_hash_table_insert (priv->fontset_hash,
- patterns->key,
- patterns);
- }
+ pattern = pango_fc_fontset_key_make_pattern (key);
+ pango_fc_default_substitute (fcfontmap, key, pattern);
- if ((!patterns->cache_link ||
- patterns->cache_link != priv->fontset_cache->head))
- pango_fc_font_map_cache_fontset (fcfontmap, patterns);
+ patterns = pango_fc_patterns_new (pattern, fcfontmap);
- pango_font_description_free (key.desc);
+ FcPatternDestroy (pattern);
return patterns;
}
@@ -1322,35 +1589,23 @@ pango_fc_font_map_load_font (PangoFontMap *fontmap,
}
static void
-pango_fc_pattern_set_free (PangoFcPatternSet *patterns)
-{
- int i;
-
- if (patterns->fontset)
- g_object_unref (patterns->fontset);
-
- for (i = 0; i < patterns->n_patterns; i++)
- FcPatternDestroy (patterns->patterns[i]);
-
- g_free (patterns->patterns);
- g_slice_free (PangoFcPatternSet, patterns);
-}
-
-static void
-pango_fc_font_map_cache_fontset (PangoFcFontMap *fcfontmap,
- PangoFcPatternSet *patterns)
+pango_fc_fontset_cache (PangoFcFontset *fontset,
+ PangoFcFontMap *fcfontmap)
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
GQueue *cache = priv->fontset_cache;
- if (patterns->cache_link)
+ if (fontset->cache_link)
{
+ if (fontset->cache_link == cache->head)
+ return;
+
/* Already in cache, move to head
*/
- if (patterns->cache_link == cache->tail)
- cache->tail = patterns->cache_link->prev;
+ if (fontset->cache_link == cache->tail)
+ cache->tail = fontset->cache_link->prev;
- cache->head = g_list_remove_link (cache->head, patterns->cache_link);
+ cache->head = g_list_remove_link (cache->head, fontset->cache_link);
cache->length--;
}
else
@@ -1359,15 +1614,15 @@ pango_fc_font_map_cache_fontset (PangoFcFontMap *fcfontmap,
*/
if (cache->length == FONTSET_CACHE_SIZE)
{
- PangoFcPatternSet *tmp_patterns = g_queue_pop_tail (cache);
- tmp_patterns->cache_link = NULL;
- g_hash_table_remove (priv->fontset_hash, tmp_patterns->key);
+ PangoFcFontset *tmp_fontset = g_queue_pop_tail (cache);
+ tmp_fontset->cache_link = NULL;
+ g_hash_table_remove (priv->fontset_hash, tmp_fontset->key);
}
- patterns->cache_link = g_list_prepend (NULL, patterns);
+ fontset->cache_link = g_list_prepend (NULL, fontset);
}
- g_queue_push_head_link (cache, patterns->cache_link);
+ g_queue_push_head_link (cache, fontset->cache_link);
}
static PangoFontset *
@@ -1376,56 +1631,33 @@ pango_fc_font_map_load_fontset (PangoFontMap *fontmap,
const PangoFontDescription *desc,
PangoLanguage *language)
{
- PangoFcPatternSet *patterns = pango_fc_font_map_get_patterns (fontmap, context, desc, language);
- PangoFontset *result;
- int i;
+ PangoFcFontMap *fcfontmap = (PangoFcFontMap *)fontmap;
+ PangoFcFontMapPrivate *priv = fcfontmap->priv;
+ PangoFcFontset *fontset;
+ PangoFcFontsetKey key;
- if (!patterns)
- return NULL;
+ pango_fc_fontset_key_init (&key, fcfontmap, context, desc, language);
+
+ fontset = g_hash_table_lookup (priv->fontset_hash, &key);
- if (!patterns->fontset)
+ if (G_UNLIKELY (!fontset))
{
- PangoFontsetSimple *simple;
- simple = pango_fontset_simple_new (language);
- result = PANGO_FONTSET (simple);
+ PangoFcPatterns *patterns = pango_fc_font_map_get_patterns (fontmap, &key);
- for (i = 0; i < patterns->n_patterns; i++)
- {
- PangoFont *font;
+ if (!patterns)
+ return NULL;
- font = pango_fc_font_map_new_font (fontmap, context, patterns->patterns[i]);
- if (font)
- pango_fontset_simple_append (simple, font);
- }
+ fontset = pango_fc_fontset_new (&key, patterns);
+ g_hash_table_insert (priv->fontset_hash, pango_fc_fontset_get_key (fontset), fontset);
- patterns->fontset = PANGO_FONTSET (simple);
+ pango_fc_patterns_unref (patterns);
}
- result = g_object_ref (patterns->fontset);
+ pango_fc_fontset_cache (fontset, fcfontmap);
- return result;
-}
-
-static void
-uncache_patterns (PangoFcPatternSet *patterns,
- PangoFcFontMap *fcfontmap)
-{
- PangoFcFontMapPrivate *priv = fcfontmap->priv;
-
- g_hash_table_remove (priv->fontset_hash, patterns->key);
-}
-
-static void
-pango_fc_font_map_clear_fontset_cache (PangoFcFontMap *fcfontmap)
-{
- PangoFcFontMapPrivate *priv = fcfontmap->priv;
- GQueue *cache = priv->fontset_cache;
+ pango_font_description_free (key.desc);
- g_list_foreach (cache->head, (GFunc)uncache_patterns, fcfontmap);
- g_list_free (cache->head);
- cache->head = NULL;
- cache->tail = NULL;
- cache->length = 0;
+ return g_object_ref (fontset);
}
/**
@@ -1443,9 +1675,11 @@ pango_fc_font_map_clear_fontset_cache (PangoFcFontMap *fcfontmap)
void
pango_fc_font_map_cache_clear (PangoFcFontMap *fcfontmap)
{
- fcfontmap->priv->dpi = -1;
+ if (G_UNLIKELY (fcfontmap->priv->closed))
+ return;
- pango_fc_font_map_clear_fontset_cache (fcfontmap);
+ pango_fc_font_map_fini (fcfontmap);
+ pango_fc_font_map_init (fcfontmap);
}
static void
@@ -1486,7 +1720,7 @@ _pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap,
return NULL;
coverage = g_hash_table_lookup (priv->coverage_hash, &key);
- if (coverage)
+ if (G_LIKELY (coverage))
return pango_coverage_ref (coverage);
/*
@@ -1586,12 +1820,10 @@ pango_fc_font_map_create_context (PangoFcFontMap *fcfontmap)
}
static void
-cleanup_font (gpointer key G_GNUC_UNUSED,
- PangoFcFont *fcfont)
+shutdown_font (gpointer key G_GNUC_UNUSED,
+ PangoFcFont *fcfont)
{
_pango_fc_font_shutdown (fcfont);
-
- fcfont->fontmap = NULL;
}
/**
@@ -1602,7 +1834,7 @@ cleanup_font (gpointer key G_GNUC_UNUSED,
* all fonts open for the fontmap as dead. (See the shutdown()
* virtual function of #PangoFcFont.) This function might be used
* by a backend when the underlying windowing system for the font
- * map exits. This function is only intended to be called from
+ * map exits. This function is only intended to be called
* only for backend implementations deriving from #PangoFcFontmap.
*
* Since: 1.4
@@ -1612,18 +1844,23 @@ pango_fc_font_map_shutdown (PangoFcFontMap *fcfontmap)
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
- pango_fc_font_map_cache_clear (fcfontmap);
+ if (priv->closed)
+ return;
+
+ g_hash_table_foreach (priv->font_hash, (GHFunc) shutdown_font, NULL);
- if (priv->fontset_hash) {
- g_hash_table_destroy (priv->fontset_hash);
- priv->fontset_hash = NULL;
- }
+ pango_fc_font_map_fini (fcfontmap);
- if (priv->font_hash) {
- g_hash_table_foreach (priv->font_hash, (GHFunc)cleanup_font, NULL);
- g_hash_table_destroy (priv->font_hash);
- priv->font_hash = NULL;
- }
+ while (priv->findfuncs)
+ {
+ PangoFcFindFuncInfo *info;
+ info = priv->findfuncs->data;
+ if (info->dnotify)
+ info->dnotify (info->user_data);
+
+ g_slice_free (PangoFcFindFuncInfo, info);
+ priv->findfuncs = g_slist_delete_link (priv->findfuncs, priv->findfuncs);
+ }
priv->closed = TRUE;
}
@@ -1965,8 +2202,10 @@ pango_fc_face_finalize (GObject *object)
pango_fc_face_parent_class->finalize (object);
}
+typedef PangoFontFaceClass PangoFcFaceClass;
+
static void
-pango_fc_face_class_init (PangoFontFaceClass *class)
+pango_fc_face_class_init (PangoFcFaceClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
@@ -1979,34 +2218,9 @@ pango_fc_face_class_init (PangoFontFaceClass *class)
class->is_synthesized = pango_fc_face_is_synthesized;
}
-static GType
-pango_fc_face_get_type (void)
-{
- static GType object_type = 0;
-
- if (G_UNLIKELY (!object_type))
- {
- 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,
- NULL /* value_table */
- };
-
- object_type = g_type_register_static (PANGO_TYPE_FONT_FACE,
- I_("PangoFcFace"),
- &object_info, 0);
- }
-
- return object_type;
-}
+static PANGO_DEFINE_TYPE (PangoFcFace, pango_fc_face,
+ pango_fc_face_class_init, NULL,
+ PANGO_TYPE_FONT_FACE)
/*
* PangoFcFamily
@@ -2195,8 +2409,10 @@ pango_fc_family_finalize (GObject *object)
pango_fc_family_parent_class->finalize (object);
}
+typedef PangoFontFamilyClass PangoFcFamilyClass;
+
static void
-pango_fc_family_class_init (PangoFontFamilyClass *class)
+pango_fc_family_class_init (PangoFcFamilyClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
@@ -2214,31 +2430,6 @@ pango_fc_family_init (PangoFcFamily *fcfamily)
fcfamily->n_faces = -1;
}
-static GType
-pango_fc_family_get_type (void)
-{
- static GType object_type = 0;
-
- if (G_UNLIKELY (!object_type))
- {
- 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,
- NULL /* value_table */
- };
-
- object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY,
- I_("PangoFcFamily"),
- &object_info, 0);
- }
-
- return object_type;
-}
+static PANGO_DEFINE_TYPE (PangoFcFamily, pango_fc_family,
+ pango_fc_family_class_init, pango_fc_family_init,
+ PANGO_TYPE_FONT_FAMILY)
diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h
index 8de4aa33..d3f113a9 100644
--- a/pango/pangofc-fontmap.h
+++ b/pango/pangofc-fontmap.h
@@ -29,6 +29,9 @@
G_BEGIN_DECLS
+
+#ifdef PANGO_ENABLE_BACKEND
+
/**
* PangoFcFontsetKey:
*
@@ -39,7 +42,7 @@ G_BEGIN_DECLS
**/
typedef struct _PangoFcFontsetKey PangoFcFontsetKey;
-const PangoLanguage *pango_fc_fontset_key_get_language (const PangoFcFontsetKey *key);
+PangoLanguage *pango_fc_fontset_key_get_language (const PangoFcFontsetKey *key);
const PangoFontDescription *pango_fc_fontset_key_get_description (const PangoFcFontsetKey *key);
const PangoMatrix *pango_fc_fontset_key_get_matrix (const PangoFcFontsetKey *key);
double pango_fc_fontset_key_get_absolute_size (const PangoFcFontsetKey *key);
@@ -60,6 +63,9 @@ const FcPattern *pango_fc_font_key_get_pattern (const PangoFcFontKey *key)
const PangoMatrix *pango_fc_font_key_get_matrix (const PangoFcFontKey *key);
gpointer pango_fc_font_key_get_context_key (const PangoFcFontKey *key);
+#endif
+
+
/*
* PangoFcFontMap
*/