summaryrefslogtreecommitdiff
path: root/pango/pangofc-fontmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pango/pangofc-fontmap.c')
-rw-r--r--pango/pangofc-fontmap.c229
1 files changed, 61 insertions, 168 deletions
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index cfe99014..5791753a 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -44,10 +44,7 @@
* - All FcPattern's referenced by any object in the fontmap are uniquified
* and cached in the fontmap. This both speeds lookups based on patterns
* faster, and saves memory. This is handled by fontmap->priv->pattern_hash.
- * The patterns are refcounted via PangoFcUPattern and removed from
- * pattern_hash when the reference count reaches zero. This avoids an ever
- * growing pattern_hash when a very large number of patterns are used within
- * the same font map (think an infinitely varied zoom factor on the text).
+ * The patterns are cached indefinitely.
*
* - The results of a FcFontSort() are used to populate fontsets. However,
* FcFontSort() relies on the search pattern only, which includes the font
@@ -92,7 +89,6 @@ typedef struct _PangoFcFontFaceData PangoFcFontFaceData;
typedef struct _PangoFcFace PangoFcFace;
typedef struct _PangoFcFamily PangoFcFamily;
typedef struct _PangoFcFindFuncInfo PangoFcFindFuncInfo;
-typedef struct _PangoFcUPattern PangoFcUPattern;
typedef struct _PangoFcPatterns PangoFcPatterns;
typedef struct _PangoFcFontset PangoFcFontset;
@@ -115,7 +111,7 @@ struct _PangoFcFontMapPrivate
GHashTable *font_hash; /* Maps PangoFcFontKey -> PangoFcFont */
- GHashTable *patterns_hash; /* Maps PangoFcUPattern -> PangoFcPatterns */
+ 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).
@@ -219,24 +215,13 @@ static gboolean pango_fc_fontset_key_equal (const PangoFcFontsetKey *k
static void pango_fc_font_key_init (PangoFcFontKey *key,
PangoFcFontMap *fcfontmap,
PangoFcFontsetKey *fontset_key,
- PangoFcUPattern *pattern);
+ 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 guint pango_fc_upattern_hash (const PangoFcUPattern *upattern);
-static gboolean pango_fc_upattern_equal (const PangoFcUPattern *upattern_a,
- const PangoFcUPattern *upattern_b);
-static void pango_fc_upattern_free (PangoFcUPattern *upattern);
-static PangoFcUPattern *pango_fc_upattern_create (FcPattern *pattern);
-static PangoFcUPattern *pango_fc_upattern_init_key (PangoFcUPattern *upattern,
- FcPattern *pattern);
-static PangoFcUPattern *pango_fc_upattern_ref (PangoFcUPattern *upattern);
-static void pango_fc_upattern_unref (PangoFcUPattern *upattern,
- PangoFcFontMap *fcfontmap);
-
static PangoFcPatterns *pango_fc_patterns_new (FcPattern *pat,
PangoFcFontMap *fontmap);
static PangoFcPatterns *pango_fc_patterns_ref (PangoFcPatterns *pats);
@@ -246,8 +231,8 @@ static FcPattern *pango_fc_patterns_get_font_pattern (PangoFcPatterns *pat
int i,
gboolean *prepare);
-static PangoFcUPattern *uniquify_pattern (PangoFcFontMap *fcfontmap,
- FcPattern *pattern);
+static FcPattern *uniquify_pattern (PangoFcFontMap *fcfontmap,
+ FcPattern *pattern);
static gpointer
get_gravity_class (void)
@@ -341,87 +326,6 @@ get_scaled_size (PangoFcFontMap *fcfontmap,
}
-/*
- * PangoFcUPattern
- */
-
-struct _PangoFcUPattern {
- FcPattern *pattern; /* only element that matters for equality in pattern_hash */
- guint ref_count; /* references from outside the pattern_hash */
-};
-
-static guint
-pango_fc_upattern_hash (const PangoFcUPattern *upattern)
-{
- return FcPatternHash(upattern->pattern);
-}
-
-static gboolean
-pango_fc_upattern_equal (const PangoFcUPattern *upattern_a, const PangoFcUPattern *upattern_b)
-{
- return FcPatternEqual(upattern_a->pattern, upattern_b->pattern);
-}
-
-static void
-pango_fc_upattern_free (PangoFcUPattern *upattern)
-{
- if (upattern->ref_count == 0)
- {
- FcPatternDestroy(upattern->pattern);
- g_slice_free(PangoFcUPattern, upattern);
- }
-}
-
-static PangoFcUPattern *
-pango_fc_upattern_create(FcPattern *pattern)
-{
- PangoFcUPattern *upat;
-
- upat = g_slice_new(PangoFcUPattern);
-
- FcPatternReference(pattern);
-
- upat->pattern = pattern;
- upat->ref_count = 1;
-
- return upat;
-}
-
-static PangoFcUPattern *
-pango_fc_upattern_init_key (PangoFcUPattern *upattern, FcPattern *pattern)
-{
- upattern->pattern = pattern;
- upattern->ref_count = 0;
-
- return upattern;
-}
-
-static PangoFcUPattern *
-pango_fc_upattern_ref (PangoFcUPattern *upattern)
-{
- g_return_val_if_fail (upattern->ref_count > 0, NULL);
-
- upattern->ref_count++;
-
- return upattern;
-}
-
-static void
-pango_fc_upattern_unref (PangoFcUPattern *upattern, PangoFcFontMap *fcfontmap)
-{
- g_return_if_fail (upattern->ref_count > 0);
-
- if ( --upattern->ref_count > 0 )
- return;
-
- /* Only remove from pattern_hash if we are really in it (and not just the same
- * pattern). This is not necessarily the case after a cache_clear() call. */
- if (fcfontmap && fcfontmap->priv->pattern_hash &&
- upattern == g_hash_table_lookup(fcfontmap->priv->pattern_hash, upattern))
- g_hash_table_remove (fcfontmap->priv->pattern_hash, upattern);
- else
- pango_fc_upattern_free (upattern);
-}
struct _PangoFcFontsetKey {
PangoFcFontMap *fontmap;
@@ -435,7 +339,7 @@ struct _PangoFcFontsetKey {
struct _PangoFcFontKey {
PangoFcFontMap *fontmap;
- PangoFcUPattern *upattern;
+ FcPattern *pattern;
PangoMatrix matrix;
gpointer context_key;
};
@@ -642,7 +546,7 @@ static gboolean
pango_fc_font_key_equal (const PangoFcFontKey *key_a,
const PangoFcFontKey *key_b)
{
- if (key_a->upattern == key_b->upattern &&
+ if (key_a->pattern == key_b->pattern &&
0 == memcmp (&key_a->matrix, &key_b->matrix, 4 * sizeof (double)))
{
if (key_a->context_key && key_b->context_key)
@@ -668,14 +572,14 @@ pango_fc_font_key_hash (const PangoFcFontKey *key)
hash ^= PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap,
key->context_key);
- return (hash ^ GPOINTER_TO_UINT (key->upattern));
+ return (hash ^ GPOINTER_TO_UINT (key->pattern));
}
static void
pango_fc_font_key_free (PangoFcFontKey *key)
{
- if (key->upattern)
- pango_fc_upattern_unref(key->upattern, key->fontmap);
+ if (key->pattern)
+ FcPatternDestroy (key->pattern);
if (key->context_key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
@@ -690,7 +594,8 @@ pango_fc_font_key_copy (const PangoFcFontKey *old)
PangoFcFontKey *key = g_slice_new (PangoFcFontKey);
key->fontmap = old->fontmap;
- key->upattern = pango_fc_upattern_ref (old->upattern);
+ FcPatternReference (old->pattern);
+ key->pattern = old->pattern;
key->matrix = old->matrix;
if (old->context_key)
key->context_key = PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_copy (key->fontmap,
@@ -705,10 +610,10 @@ static void
pango_fc_font_key_init (PangoFcFontKey *key,
PangoFcFontMap *fcfontmap,
PangoFcFontsetKey *fontset_key,
- PangoFcUPattern *upattern)
+ FcPattern *pattern)
{
key->fontmap = fcfontmap;
- key->upattern = upattern;
+ key->pattern = pattern;
key->matrix = *pango_fc_fontset_key_get_matrix (fontset_key);
key->context_key = pango_fc_fontset_key_get_context_key (fontset_key);
}
@@ -728,7 +633,7 @@ pango_fc_font_key_init (PangoFcFontKey *key,
const FcPattern *
pango_fc_font_key_get_pattern (const PangoFcFontKey *key)
{
- return key->upattern->pattern;
+ return key->pattern;
}
/**
@@ -773,7 +678,7 @@ struct _PangoFcPatterns {
PangoFcFontMap *fontmap;
- PangoFcUPattern *upattern;
+ FcPattern *pattern;
FcPattern *match;
FcFontSet *fontset;
};
@@ -782,25 +687,22 @@ static PangoFcPatterns *
pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap)
{
PangoFcPatterns *pats;
- PangoFcUPattern *upat;
- upat = uniquify_pattern (fontmap, pat);
- pats = g_hash_table_lookup (fontmap->priv->patterns_hash, upat);
+ pat = uniquify_pattern (fontmap, pat);
+ pats = g_hash_table_lookup (fontmap->priv->patterns_hash, pat);
if (pats)
- {
- pango_fc_upattern_unref(upat, fontmap);
- return pango_fc_patterns_ref (pats);
- }
+ return pango_fc_patterns_ref (pats);
pats = g_slice_new0 (PangoFcPatterns);
pats->fontmap = fontmap;
pats->ref_count = 1;
- pats->upattern = upat;
+ FcPatternReference (pat);
+ pats->pattern = pat;
g_hash_table_insert (fontmap->priv->patterns_hash,
- pats->upattern, pats);
+ pats->pattern, pats);
return pats;
}
@@ -828,12 +730,12 @@ pango_fc_patterns_unref (PangoFcPatterns *pats)
/* 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->upattern))
+ pats == g_hash_table_lookup (pats->fontmap->priv->patterns_hash, pats->pattern))
g_hash_table_remove (pats->fontmap->priv->patterns_hash,
- pats->upattern);
+ pats->pattern);
- if (pats->upattern)
- pango_fc_upattern_unref (pats->upattern, pats->fontmap);
+ if (pats->pattern)
+ FcPatternDestroy (pats->pattern);
if (pats->match)
FcPatternDestroy (pats->match);
@@ -847,7 +749,7 @@ pango_fc_patterns_unref (PangoFcPatterns *pats)
static FcPattern *
pango_fc_patterns_get_pattern (PangoFcPatterns *pats)
{
- return pats->upattern->pattern;
+ return pats->pattern;
}
static FcPattern *
@@ -858,21 +760,27 @@ pango_fc_patterns_get_font_pattern (PangoFcPatterns *pats, int i, gboolean *prep
FcResult result;
if (!pats->match && !pats->fontset)
{
- pats->match = FcFontMatch (NULL, pats->upattern->pattern, &result);
+ pats->match = FcFontMatch (NULL, pats->pattern, &result);
+#ifdef FC_PATTERN
+ /* The FC_PATTERN element, which points back to our the original
+ * pattern defeats our hash tables.
+ */
+ FcPatternDel (pats->match, FC_PATTERN);
+#endif /* FC_PATTERN */
}
if (pats->match)
- {
+ {
*prepare = FALSE;
return pats->match;
- }
+ }
}
else
{
if (!pats->fontset)
{
FcResult result;
- pats->fontset = FcFontSort (NULL, pats->upattern->pattern, FcTrue, NULL, &result);
+ pats->fontset = FcFontSort (NULL, pats->pattern, FcTrue, NULL, &result);
if (pats->match)
{
FcPatternDestroy (pats->match);
@@ -959,20 +867,21 @@ pango_fc_fontset_load_next_font (PangoFcFontset *fontset)
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);
+ /* 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);
+ if (prepare)
+ FcPatternDestroy (font_pattern);
return font;
}
@@ -1154,9 +1063,9 @@ pango_fc_font_map_init (PangoFcFontMap *fcfontmap)
priv->patterns_hash = g_hash_table_new (NULL, NULL);
- priv->pattern_hash = g_hash_table_new_full ((GHashFunc) pango_fc_upattern_hash,
- (GEqualFunc) pango_fc_upattern_equal,
- (GDestroyNotify) pango_fc_upattern_free,
+ priv->pattern_hash = g_hash_table_new_full ((GHashFunc) FcPatternHash,
+ (GEqualFunc) FcPatternEqual,
+ (GDestroyNotify) FcPatternDestroy,
NULL);
priv->font_face_data_hash = g_hash_table_new_full ((GHashFunc)pango_fc_font_face_data_hash,
@@ -1591,27 +1500,23 @@ pango_fc_make_pattern (const PangoFontDescription *description,
return pattern;
}
-/* The returned PangoFcUPattern should be unreferenced via
- * pango_fc_upattern_unref() when done with it. */
-static PangoFcUPattern *
+static FcPattern *
uniquify_pattern (PangoFcFontMap *fcfontmap,
FcPattern *pattern)
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
- PangoFcUPattern upat_key;
- PangoFcUPattern *upattern;
+ FcPattern *old_pattern;
- upattern = g_hash_table_lookup (priv->pattern_hash,
- pango_fc_upattern_init_key(&upat_key, pattern));
- if ( upattern )
+ old_pattern = g_hash_table_lookup (priv->pattern_hash, pattern);
+ if (old_pattern)
{
- return pango_fc_upattern_ref (upattern);
+ return old_pattern;
}
else
{
- upattern = pango_fc_upattern_create(pattern);
- g_hash_table_insert (priv->pattern_hash, upattern, upattern);
- return upattern;
+ FcPatternReference (pattern);
+ g_hash_table_insert (priv->pattern_hash, pattern, pattern);
+ return pattern;
}
}
@@ -1622,7 +1527,6 @@ pango_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
{
PangoFcFontMapClass *class;
PangoFcFontMapPrivate *priv = fcfontmap->priv;
- PangoFcUPattern *umatch;
FcPattern *pattern;
PangoFcFont *fcfont;
PangoFcFontKey key;
@@ -1630,16 +1534,13 @@ pango_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
if (priv->closed)
return NULL;
- umatch = uniquify_pattern (fcfontmap, match);
+ match = uniquify_pattern (fcfontmap, match);
- pango_fc_font_key_init (&key, fcfontmap, fontset_key, umatch);
+ pango_fc_font_key_init (&key, fcfontmap, fontset_key, match);
fcfont = g_hash_table_lookup (priv->font_hash, &key);
if (fcfont)
- {
- pango_fc_upattern_unref(umatch, fcfontmap);
- return g_object_ref (fcfont);
- }
+ return g_object_ref (fcfont);
class = PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap);
@@ -1651,7 +1552,6 @@ pango_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
{
const PangoMatrix *pango_matrix = pango_fc_fontset_key_get_matrix (fontset_key);
FcMatrix fc_matrix, *fc_matrix_val;
- PangoFcUPattern *upattern;
int i;
/* Fontconfig has the Y axis pointing up, Pango, down.
@@ -1661,7 +1561,7 @@ pango_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
fc_matrix.yx = - pango_matrix->yx;
fc_matrix.yy = pango_matrix->yy;
- pattern = FcPatternDuplicate (umatch->pattern);
+ pattern = FcPatternDuplicate (match);
for (i = 0; FcPatternGetMatrix (pattern, FC_MATRIX, i, &fc_matrix_val) == FcResultMatch; i++)
FcMatrixMultiply (&fc_matrix, &fc_matrix, fc_matrix_val);
@@ -1669,18 +1569,13 @@ pango_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
FcPatternDel (pattern, FC_MATRIX);
FcPatternAddMatrix (pattern, FC_MATRIX, &fc_matrix);
- upattern = uniquify_pattern (fcfontmap, pattern);
- fcfont = class->new_font (fcfontmap, upattern->pattern);
- pango_fc_upattern_unref(upattern, fcfontmap);
+ fcfont = class->new_font (fcfontmap, uniquify_pattern (fcfontmap, pattern));
FcPatternDestroy (pattern);
}
if (!fcfont)
- {
- pango_fc_upattern_unref(umatch, fcfontmap);
- return NULL;
- }
+ return NULL;
fcfont->matrix = key.matrix;
/* In case the backend didn't set the fontmap */
@@ -1692,8 +1587,6 @@ pango_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
/* cache it on fontmap */
pango_fc_font_map_add (fcfontmap, &key, fcfont);
- pango_fc_upattern_unref(umatch, fcfontmap);
-
return (PangoFont *)fcfont;
}