summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--docs/pango-sections.txt7
-rw-r--r--docs/tmpl/pangofc-fontmap.sgml35
-rw-r--r--docs/tmpl/text-attributes.sgml1
-rw-r--r--pango/pangocairo-fc.h6
-rw-r--r--pango/pangocairo-fcfont.c78
-rw-r--r--pango/pangocairo-fcfontmap.c20
-rw-r--r--pango/pangofc-font.c14
-rw-r--r--pango/pangofc-fontmap.c344
-rw-r--r--pango/pangofc-fontmap.h47
-rw-r--r--pango/pangofc-private.h6
11 files changed, 363 insertions, 228 deletions
diff --git a/ChangeLog b/ChangeLog
index 898a8d71..fcad4df4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,38 @@
2009-01-09 Behdad Esfahbod <behdad@gnome.org>
+ * docs/pango-sections.txt:
+ * docs/tmpl/pangofc-fontmap.sgml:
+ * docs/tmpl/text-attributes.sgml:
+ * pango/pangocairo-fc.h:
+ * pango/pangocairo-fcfont.c (get_font_size), (get_gravity_class),
+ (get_gravity), (_pango_cairo_fc_font_new):
+ * pango/pangocairo-fcfontmap.c
+ (pango_cairo_fc_font_map_font_key_substitute),
+ (pango_cairo_fc_font_map_create_font),
+ (pango_cairo_fc_font_map_class_init):
+ * pango/pangofc-font.c (_pango_fc_font_get_font_key),
+ (_pango_fc_font_set_font_key):
+ * pango/pangofc-fontmap.c (pango_fc_font_key_equal),
+ (pango_fc_font_key_hash), (pango_fc_font_key_free),
+ (pango_fc_font_key_copy), (get_context_matrix),
+ (pango_fc_font_key_init), (pango_fc_font_key_get_pattern),
+ (pango_fc_font_key_get_matrix),
+ (pango_fc_font_key_get_context_key), (pango_fc_font_map_init),
+ (pango_fc_font_map_class_init), (pango_fc_font_map_add),
+ (_pango_fc_font_map_remove), (pango_fc_make_pattern),
+ (pango_fc_font_map_new_font), (pango_fc_default_substitute),
+ (pango_fc_font_map_get_patterns), (pango_fc_font_map_load_fontset):
+ * pango/pangofc-fontmap.h:
+ * pango/pangofc-private.h:
+ Change PangoFc font loading API such that PangoContext is not passed
+ down. We use a new opaque struct called PangoFcFontKey. This struct
+ is in fact our font hash key. This avoids problems where previously
+ we were using context members that were not necessarily considered
+ by the pangofc layer when caching.
+ This is in preparation for lazy loading of fonts in the pangofc fontmap.
+
+2009-01-09 Behdad Esfahbod <behdad@gnome.org>
+
* pango/pangocairo-atsuifont.c (_pango_cairo_atsui_font_new):
* pango/pangocairo-fcfont.c (_pango_cairo_fc_font_new):
* pango/pangocairo-font.c (_pango_cairo_font_private_initialize):
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index b4809b50..9e42923e 100644
--- a/docs/pango-sections.txt
+++ b/docs/pango-sections.txt
@@ -933,11 +933,18 @@ PANGO_FC_FONT_MAP_CLASS
PANGO_IS_FC_FONT_MAP_CLASS
PANGO_FC_FONT_MAP_GET_CLASS
+<SUBSECTION>
+PangoFcFontKey
+pango_fc_font_key_get_context_key
+pango_fc_font_key_get_matrix
+pango_fc_font_key_get_pattern
+
<SUBSECTION Private>
PangoFcFontMapPrivate
pango_fc_font_map_get_type
</SECTION>
+
<SECTION>
<FILE>pangofc-font</FILE>
<TITLE>PangoFcFont</TITLE>
diff --git a/docs/tmpl/pangofc-fontmap.sgml b/docs/tmpl/pangofc-fontmap.sgml
index 5d85676c..6800d30a 100644
--- a/docs/tmpl/pangofc-fontmap.sgml
+++ b/docs/tmpl/pangofc-fontmap.sgml
@@ -53,7 +53,7 @@ Fontconfig-based backend involves deriving from both
@context_key_free:
@context_key_hash:
@context_key_equal:
-@context_substitute:
+@font_key_substitute:
@create_font:
<!-- ##### FUNCTION pango_fc_font_map_create_context ##### -->
@@ -133,3 +133,36 @@ Fontconfig-based backend involves deriving from both
+<!-- ##### STRUCT PangoFcFontKey ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION pango_fc_font_key_get_context_key ##### -->
+<para>
+
+</para>
+
+@key:
+@Returns:
+
+
+<!-- ##### FUNCTION pango_fc_font_key_get_matrix ##### -->
+<para>
+
+</para>
+
+@key:
+@Returns:
+
+
+<!-- ##### FUNCTION pango_fc_font_key_get_pattern ##### -->
+<para>
+
+</para>
+
+@key:
+@Returns:
+
+
diff --git a/docs/tmpl/text-attributes.sgml b/docs/tmpl/text-attributes.sgml
index 050fe594..57469b8a 100644
--- a/docs/tmpl/text-attributes.sgml
+++ b/docs/tmpl/text-attributes.sgml
@@ -99,6 +99,7 @@ such that the attribute covers from the beginning of the text.
Since: 1.24
+
<!-- ##### MACRO PANGO_ATTR_INDEX_TO_TEXT_END ##### -->
<para>
This value can be used to set the end_index member of a #PangoAttribute
diff --git a/pango/pangocairo-fc.h b/pango/pangocairo-fc.h
index 74f39bab..ea4fccbc 100644
--- a/pango/pangocairo-fc.h
+++ b/pango/pangocairo-fc.h
@@ -44,10 +44,8 @@ struct _PangoCairoFcFontMap
GType pango_cairo_fc_font_map_get_type (void) G_GNUC_CONST;
-PangoFcFont *_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
- PangoContext *context,
- const PangoFontDescription *desc,
- FcPattern *pattern);
+PangoFcFont *_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
+ PangoFcFontKey *key);
FT_Library _pango_cairo_fc_font_map_get_library (PangoCairoFcFontMap *fontmap);
G_END_DECLS
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c
index 129fa865..1c9a77aa 100644
--- a/pango/pangocairo-fcfont.c
+++ b/pango/pangocairo-fcfont.c
@@ -169,52 +169,59 @@ pango_cairo_fc_font_init (PangoCairoFcFont *cffont G_GNUC_UNUSED)
********************/
static double
-get_font_size (PangoCairoFcFontMap *cffontmap,
- PangoContext *context,
- const PangoFontDescription *desc,
- FcPattern *pattern)
+get_font_size (const FcPattern *pattern)
{
double size;
-
- /* The reason why we read FC_PIXEL_SIZE here rather than just
- * using the specified size is to support operations like clamping
- * a font to a minimal readable size in fonts.conf. This is pretty weird,
- * since it could mean that changing the Cairo CTM doesn't change the
- * font size, but it's just a more radical version of the non-linear
- * font scaling we already have due to hinting and due to bitmap
- * fonts being only available at a few sizes.
- *
- * If honoring FC_PIXEL_SIZE gets in the way of more useful features
- * it should be removed since it only matters in the unusual case
- * of people doing exotic stuff in fonts.conf.
- */
+ double dpi;
if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
- return size * PANGO_SCALE / pango_matrix_get_font_scale_factor (pango_context_get_matrix (context));
+ return size * PANGO_SCALE;
/* Just in case FC_PIXEL_SIZE got unset between pango_fc_make_pattern()
- * and here.
+ * and here. That would be very weird.
*/
- if (pango_font_description_get_size_is_absolute (desc))
- return pango_font_description_get_size (desc);
- else
- {
- double dpi = pango_cairo_context_get_resolution (context);
- if (dpi <= 0)
- dpi = cffontmap->dpi;
+ if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) != FcResultMatch)
+ dpi = 72;
+
+ if (FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch)
+ return size * dpi / 72.;
+
+ /* Whatever */
+ return 18.;
+}
+
+static gpointer
+get_gravity_class (void)
+{
+ static GEnumClass *class = NULL;
- return dpi * pango_font_description_get_size (desc) / 72.;
+ if (G_UNLIKELY (!class))
+ class = g_type_class_ref (PANGO_TYPE_GRAVITY);
+
+ return class;
+}
+
+static PangoGravity
+get_gravity (const FcPattern *pattern)
+{
+ char *s;
+
+ if (FcPatternGetString (pattern, PANGO_FC_GRAVITY, 0, (FcChar8 **)(void *)&s) == FcResultMatch)
+ {
+ GEnumValue *value = g_enum_get_value_by_nick (get_gravity_class (), s);
+ return value->value;
}
+
+ return PANGO_GRAVITY_SOUTH;
}
PangoFcFont *
-_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
- PangoContext *context,
- const PangoFontDescription *desc,
- FcPattern *pattern)
+_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
+ PangoFcFontKey *key)
{
PangoCairoFcFont *cffont;
+ const FcPattern *pattern = pango_fc_font_key_get_pattern (key);
cairo_matrix_t font_matrix;
FcMatrix *fc_matrix;
double size;
@@ -226,7 +233,8 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
"pattern", pattern,
NULL);
- size = get_font_size (cffontmap, context, desc, pattern);
+ size = get_font_size (pattern) /
+ pango_matrix_get_font_scale_factor (pango_fc_font_key_get_matrix (key));
if (FcPatternGetMatrix (pattern,
FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
@@ -244,9 +252,9 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
_pango_cairo_font_private_initialize (&cffont->cf_priv,
(PangoCairoFont *) cffont,
- pango_font_description_get_gravity (desc),
- _pango_cairo_context_get_merged_font_options (context),
- pango_context_get_matrix (context),
+ get_gravity (pattern),
+ pango_fc_font_key_get_context_key (key),
+ pango_fc_font_key_get_matrix (key),
&font_matrix);
((PangoFcFont *)(cffont))->is_hinted = _pango_cairo_font_private_is_metrics_hinted (&cffont->cf_priv);
diff --git a/pango/pangocairo-fcfontmap.c b/pango/pangocairo-fcfontmap.c
index 33e94549..c66602b6 100644
--- a/pango/pangocairo-fcfontmap.c
+++ b/pango/pangocairo-fcfontmap.c
@@ -80,14 +80,14 @@ pango_cairo_fc_font_map_finalize (GObject *object)
}
static void
-pango_cairo_fc_font_map_context_substitute (PangoFcFontMap *fcfontmap G_GNUC_UNUSED,
- PangoContext *context,
- FcPattern *pattern)
+pango_cairo_fc_font_map_font_key_substitute (PangoFcFontMap *fcfontmap G_GNUC_UNUSED,
+ PangoFcFontKey *fontkey,
+ FcPattern *pattern)
{
FcConfigSubstitute (NULL, pattern, FcMatchPattern);
- if (context)
- cairo_ft_font_options_substitute (_pango_cairo_context_get_merged_font_options (context),
+ if (fontkey)
+ cairo_ft_font_options_substitute (pango_fc_font_key_get_context_key (fontkey),
pattern);
FcDefaultSubstitute (pattern);
@@ -151,13 +151,11 @@ pango_cairo_fc_font_map_context_key_equal (PangoFcFontMap *fcfontmap G_GNUC_UNUS
}
static PangoFcFont *
-pango_cairo_fc_font_map_create_font (PangoFcFontMap *fcfontmap,
- PangoContext *context,
- const PangoFontDescription *desc,
- FcPattern *pattern)
+pango_cairo_fc_font_map_create_font (PangoFcFontMap *fcfontmap,
+ PangoFcFontKey *key)
{
return _pango_cairo_fc_font_new ((PangoCairoFcFontMap *) (fcfontmap),
- context, desc, pattern);
+ key);
}
static void
@@ -168,7 +166,7 @@ pango_cairo_fc_font_map_class_init (PangoCairoFcFontMapClass *class)
gobject_class->finalize = pango_cairo_fc_font_map_finalize;
- fcfontmap_class->context_substitute = pango_cairo_fc_font_map_context_substitute;
+ fcfontmap_class->font_key_substitute = pango_cairo_fc_font_map_font_key_substitute;
fcfontmap_class->get_resolution = pango_cairo_fc_font_map_get_resolution_fc;
fcfontmap_class->context_key_get = pango_cairo_fc_font_map_context_key_get;
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index d5f2d57f..64199239 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -57,7 +57,7 @@ typedef struct _PangoFcFontPrivate PangoFcFontPrivate;
struct _PangoFcFontPrivate
{
PangoFcDecoder *decoder;
- gpointer context_key;
+ PangoFcFontKey *key;
GUnicharToGlyphCacheEntry *char_to_glyph_cache;
};
@@ -855,21 +855,21 @@ _pango_fc_font_set_decoder (PangoFcFont *font,
g_object_ref (priv->decoder);
}
-gpointer
-_pango_fc_font_get_context_key (PangoFcFont *fcfont)
+PangoFcFontKey *
+_pango_fc_font_get_font_key (PangoFcFont *fcfont)
{
PangoFcFontPrivate *priv = fcfont->priv;
- return priv->context_key;
+ return priv->key;
}
void
-_pango_fc_font_set_context_key (PangoFcFont *fcfont,
- gpointer context_key)
+_pango_fc_font_set_font_key (PangoFcFont *fcfont,
+ PangoFcFontKey *key)
{
PangoFcFontPrivate *priv = fcfont->priv;
- priv->context_key = context_key;
+ priv->key = key;
}
static FT_Glyph_Metrics *
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 0d7fe7ee..42cfe01e 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -38,7 +38,6 @@ typedef struct _PangoFcFamily PangoFcFamily;
typedef struct _PangoFcPatternSet PangoFcPatternSet;
typedef struct _PangoFcFindFuncInfo PangoFcFindFuncInfo;
typedef struct _FontsetHashKey FontsetHashKey;
-typedef struct _FontHashKey FontHashKey;
#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))
@@ -136,6 +135,9 @@ static void pango_fc_font_map_list_families (PangoFontMap
PangoFontFamily ***families,
int *n_families);
+static double pango_fc_font_map_get_resolution (PangoFcFontMap *fcfontmap,
+ PangoContext *context);
+
static void pango_fc_font_map_cache_fontset (PangoFcFontMap *fcfontmap,
PangoFcPatternSet *patterns);
@@ -148,72 +150,16 @@ static guint pango_fc_coverage_key_hash (PangoFcCoverageKey *key);
static gboolean pango_fc_coverage_key_equal (PangoFcCoverageKey *key1,
PangoFcCoverageKey *key2);
-static guint font_hash_key_hash (const FontHashKey *key);
-static gboolean font_hash_key_equal (const FontHashKey *key_a,
- const FontHashKey *key_b);
-static void font_hash_key_free (FontHashKey *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 void pango_fc_font_key_free (PangoFcFontKey *key);
static guint fontset_hash_key_hash (const FontsetHashKey *key);
static gboolean fontset_hash_key_equal (const FontsetHashKey *key_a,
const FontsetHashKey *key_b);
static void fontset_hash_key_free (FontsetHashKey *key);
-G_DEFINE_ABSTRACT_TYPE (PangoFcFontMap, pango_fc_font_map, PANGO_TYPE_FONT_MAP)
-
-static void
-pango_fc_font_map_init (PangoFcFontMap *fcfontmap)
-{
- static gboolean registered_modules = FALSE;
- PangoFcFontMapPrivate *priv;
-
- priv = fcfontmap->priv = G_TYPE_INSTANCE_GET_PRIVATE (fcfontmap,
- PANGO_TYPE_FC_FONT_MAP,
- PangoFcFontMapPrivate);
-
- if (!registered_modules)
- {
- int i;
-
- registered_modules = TRUE;
-
- for (i = 0; _pango_included_fc_modules[i].list; i++)
- pango_module_register (&_pango_included_fc_modules[i]);
- }
-
- priv->n_families = -1;
-
- priv->font_hash = g_hash_table_new_full ((GHashFunc)font_hash_key_hash,
- (GEqualFunc)font_hash_key_equal,
- (GDestroyNotify)font_hash_key_free,
- NULL);
- priv->fontset_hash = g_hash_table_new_full ((GHashFunc)fontset_hash_key_hash,
- (GEqualFunc)fontset_hash_key_equal,
- (GDestroyNotify)fontset_hash_key_free,
- (GDestroyNotify)pango_fc_pattern_set_free);
-
- 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_class_init (PangoFcFontMapClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);
-
- object_class->finalize = pango_fc_font_map_finalize;
- fontmap_class->load_font = pango_fc_font_map_load_font;
- fontmap_class->load_fontset = pango_fc_font_map_load_fontset;
- fontmap_class->list_families = pango_fc_font_map_list_families;
- fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_FC;
-
- g_type_class_add_private (object_class, sizeof (PangoFcFontMapPrivate));
-}
-
static gpointer
get_gravity_class (void)
{
@@ -283,10 +229,10 @@ struct _FontsetHashKey {
gpointer context_key;
};
-struct _FontHashKey {
+struct _PangoFcFontKey {
PangoFcFontMap *fontmap;
+ const FcPattern *pattern;
PangoMatrix matrix;
- FcPattern *pattern;
gpointer context_key;
};
@@ -378,15 +324,16 @@ fontset_hash_key_copy (FontsetHashKey *old)
return key;
}
+/*
+ * PangoFcFontKey
+ */
+
static gboolean
-font_hash_key_equal (const FontHashKey *key_a,
- const FontHashKey *key_b)
-{
- if (key_a->matrix.xx == key_b->matrix.xx &&
- key_a->matrix.xy == key_b->matrix.xy &&
- key_a->matrix.yx == key_b->matrix.yx &&
- key_a->matrix.yy == key_b->matrix.yy &&
- key_a->pattern == key_b->pattern)
+pango_fc_font_key_equal (const PangoFcFontKey *key_a,
+ const PangoFcFontKey *key_b)
+{
+ 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)
return PANGO_FC_FONT_MAP_GET_CLASS (key_a->fontmap)->context_key_equal (key_a->fontmap,
@@ -400,7 +347,7 @@ font_hash_key_equal (const FontHashKey *key_a,
}
static guint
-font_hash_key_hash (const FontHashKey *key)
+pango_fc_font_key_hash (const PangoFcFontKey *key)
{
guint32 hash = FNV1_32_INIT;
@@ -417,23 +364,23 @@ font_hash_key_hash (const FontHashKey *key)
}
static void
-font_hash_key_free (FontHashKey *key)
+pango_fc_font_key_free (PangoFcFontKey *key)
{
if (key->context_key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
key->context_key);
- g_slice_free (FontHashKey, key);
+ g_slice_free (PangoFcFontKey, key);
}
-static FontHashKey *
-font_hash_key_copy (FontHashKey *old)
+static PangoFcFontKey *
+pango_fc_font_key_copy (PangoFcFontKey *old)
{
- FontHashKey *key = g_slice_new (FontHashKey);
+ PangoFcFontKey *key = g_slice_new (PangoFcFontKey);
key->fontmap = old->fontmap;
- key->matrix = old->matrix;
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,
old->context_key);
@@ -443,6 +390,147 @@ font_hash_key_copy (FontHashKey *old)
return key;
}
+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)
+{
+ 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;
+}
+
+/* Public API */
+
+/**
+ * pango_fc_font_key_get_pattern:
+ * @key: the font key
+ *
+ * Gets the fontconfig pattern member of @key.
+ *
+ * Returns: the pattern, which is owned by @key and should not be modified.
+ *
+ * Since: 1.24
+ **/
+const FcPattern *
+pango_fc_font_key_get_pattern (const PangoFcFontKey *key)
+{
+ return key->pattern;
+}
+
+/**
+ * pango_fc_font_key_get_matrix:
+ * @key: the font key
+ *
+ * Gets the matrix member of @key.
+ *
+ * Returns: the matrix, which is owned by @key and should not be modified.
+ *
+ * Since: 1.24
+ **/
+const PangoMatrix *
+pango_fc_font_key_get_matrix (const PangoFcFontKey *key)
+{
+ return &key->matrix;
+}
+
+/**
+ * pango_fc_font_key_get_context_key:
+ * @key: the font key
+ *
+ * Gets the context key member of @key.
+ *
+ * Returns: the context key, which is owned by @key and should not be modified.
+ *
+ * Since: 1.24
+ **/
+gpointer
+pango_fc_font_key_get_context_key (const PangoFcFontKey *key)
+{
+ return key->context_key;
+}
+
+
+/*
+ * PangoFcFontMap
+ */
+
+G_DEFINE_ABSTRACT_TYPE (PangoFcFontMap, pango_fc_font_map, PANGO_TYPE_FONT_MAP)
+
+static void
+pango_fc_font_map_init (PangoFcFontMap *fcfontmap)
+{
+ static gboolean registered_modules = FALSE;
+ PangoFcFontMapPrivate *priv;
+
+ priv = fcfontmap->priv = G_TYPE_INSTANCE_GET_PRIVATE (fcfontmap,
+ PANGO_TYPE_FC_FONT_MAP,
+ PangoFcFontMapPrivate);
+
+ if (!registered_modules)
+ {
+ int i;
+
+ registered_modules = TRUE;
+
+ for (i = 0; _pango_included_fc_modules[i].list; i++)
+ pango_module_register (&_pango_included_fc_modules[i]);
+ }
+
+ 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->fontset_hash = g_hash_table_new_full ((GHashFunc)fontset_hash_key_hash,
+ (GEqualFunc)fontset_hash_key_equal,
+ (GDestroyNotify)fontset_hash_key_free,
+ (GDestroyNotify)pango_fc_pattern_set_free);
+
+ 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_class_init (PangoFcFontMapClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);
+
+ object_class->finalize = pango_fc_font_map_finalize;
+ fontmap_class->load_font = pango_fc_font_map_load_font;
+ fontmap_class->load_fontset = pango_fc_font_map_load_fontset;
+ fontmap_class->list_families = pango_fc_font_map_list_families;
+ fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_FC;
+
+ g_type_class_add_private (object_class, sizeof (PangoFcFontMapPrivate));
+}
+
+
/**
* pango_fc_font_map_add_decoder_find_func:
* @fcfontmap: The #PangoFcFontMap to add this method to.
@@ -515,47 +603,14 @@ pango_fc_font_map_finalize (GObject *object)
G_OBJECT_CLASS (pango_fc_font_map_parent_class)->finalize (object);
}
-static void
-get_context_matrix (PangoContext *context,
- PangoMatrix *matrix)
-{
- const PangoMatrix *set_matrix;
- static const PangoMatrix identity = PANGO_MATRIX_INIT;
-
- if (context)
- set_matrix = pango_context_get_matrix (context);
- else
- set_matrix = NULL;
-
- if (set_matrix)
- *matrix = *set_matrix;
- else
- *matrix = identity;
-}
-
-static void
-font_hash_key_for_context (PangoFcFontMap *fcfontmap,
- PangoContext *context,
- FontHashKey *key)
-{
- key->fontmap = fcfontmap;
- get_context_matrix (context, &key->matrix);
-
- 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;
-}
-
/* Add a mapping from fcfont->font_pattern to fcfont */
static void
pango_fc_font_map_add (PangoFcFontMap *fcfontmap,
- PangoContext *context,
+ PangoFcFontKey *key,
PangoFcFont *fcfont)
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
- FontHashKey key;
- FontHashKey *key_copy;
+ PangoFcFontKey *key_copy;
g_assert (fcfont->fontmap == NULL);
fcfont->fontmap = (PangoFontMap *) fcfontmap;
@@ -564,46 +619,26 @@ pango_fc_font_map_add (PangoFcFontMap *fcfontmap,
* here though as PangoFcFontMap already cleans up fcfont->fontmap
* as part of it's caching scheme. */
- font_hash_key_for_context (fcfontmap, context, &key);
- key.pattern = fcfont->font_pattern;
-
- key_copy = font_hash_key_copy (&key);
- _pango_fc_font_set_context_key (fcfont, key_copy->context_key);
- fcfont->matrix = key.matrix;
+ 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);
}
-static PangoFcFont *
-pango_fc_font_map_lookup (PangoFcFontMap *fcfontmap,
- PangoContext *context,
- FcPattern *pattern)
-{
- PangoFcFontMapPrivate *priv = fcfontmap->priv;
- FontHashKey key;
-
- font_hash_key_for_context (fcfontmap, context, &key);
- key.pattern = pattern;
-
- return g_hash_table_lookup (priv->font_hash, &key);
-}
-
/* Remove mapping from fcfont->font_pattern to fcfont */
void
_pango_fc_font_map_remove (PangoFcFontMap *fcfontmap,
PangoFcFont *fcfont)
{
PangoFcFontMapPrivate *priv = fcfontmap->priv;
- FontHashKey key;
+ PangoFcFontKey *key;
- key.fontmap = fcfontmap;
- key.matrix = fcfont->matrix;
- key.pattern = fcfont->font_pattern;
- key.context_key = _pango_fc_font_get_context_key (fcfont);
+ key = _pango_fc_font_get_font_key (fcfont);
- g_hash_table_remove (priv->font_hash, &key);
+ g_hash_table_remove (priv->font_hash, key);
fcfont->fontmap = NULL;
- _pango_fc_font_set_context_key (fcfont, NULL);
+ _pango_fc_font_set_font_key (fcfont, NULL);
}
static PangoFcFamily *
@@ -832,6 +867,7 @@ pango_fc_make_pattern (const PangoFontDescription *description,
#ifdef FC_VERTICAL_LAYOUT
FC_VERTICAL_LAYOUT, FcTypeBool, vertical,
#endif
+ FC_DPI, FcTypeDouble, dpi,
FC_SIZE, FcTypeDouble, pixel_size * (72. / dpi),
FC_PIXEL_SIZE, FcTypeDouble, pixel_size,
NULL);
@@ -861,7 +897,6 @@ pango_fc_make_pattern (const PangoFontDescription *description,
static PangoFont *
pango_fc_font_map_new_font (PangoFontMap *fontmap,
PangoContext *context,
- const PangoFontDescription *description,
FcPattern *match)
{
PangoFcFontMapClass *class;
@@ -870,11 +905,14 @@ pango_fc_font_map_new_font (PangoFontMap *fontmap,
FcPattern *pattern;
PangoFcFont *fcfont;
GSList *l;
+ PangoFcFontKey key;
if (priv->closed)
return NULL;
- fcfont = pango_fc_font_map_lookup (fcfontmap, context, match);
+ pango_fc_font_key_init (&key, fcfontmap, context, match);
+
+ fcfont = g_hash_table_lookup (priv->font_hash, &key);
if (fcfont)
return g_object_ref (fcfont);
@@ -883,9 +921,7 @@ pango_fc_font_map_new_font (PangoFontMap *fontmap,
if (class->create_font)
{
fcfont = PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->create_font (fcfontmap,
- context,
- description,
- match);
+ &key);
}
else
{
@@ -922,7 +958,7 @@ pango_fc_font_map_new_font (PangoFontMap *fontmap,
if (!fcfont)
return NULL;
- pango_fc_font_map_add (fcfontmap, context, fcfont);
+ pango_fc_font_map_add (fcfontmap, &key, fcfont);
/*
* Give any custom decoders a crack at this font now that it's been
@@ -974,16 +1010,16 @@ uniquify_pattern (PangoFcFontMap *fcfontmap,
static void
pango_fc_default_substitute (PangoFcFontMap *fontmap,
- PangoContext *context,
+ PangoFcFontKey *fontkey,
FcPattern *pattern)
{
- if (PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->context_substitute)
- PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->context_substitute (fontmap, context, pattern);
+ if (PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->font_key_substitute)
+ PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->font_key_substitute (fontmap, fontkey, pattern);
else if (PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->default_substitute)
PANGO_FC_FONT_MAP_GET_CLASS (fontmap)->default_substitute (fontmap, pattern);
}
-static gdouble
+static double
pango_fc_font_map_get_resolution (PangoFcFontMap *fcfontmap,
PangoContext *context)
{
@@ -1064,11 +1100,14 @@ pango_fc_font_map_get_patterns (PangoFontMap *fontmap,
if (patterns == NULL)
{
+ PangoFcFontKey fontkey;
+
pattern = pango_fc_make_pattern (desc, language,
key.scaled_size / 1024.,
pango_fc_font_map_get_resolution (fcfontmap, context));
- pango_fc_default_substitute (fcfontmap, context, pattern);
+ pango_fc_font_key_init (&fontkey, fcfontmap, context, pattern);
+ pango_fc_default_substitute (fcfontmap, &fontkey, pattern);
font_patterns = FcFontSort (NULL, pattern, FcTrue, NULL, &res);
@@ -1238,8 +1277,7 @@ pango_fc_font_map_load_fontset (PangoFontMap *fontmap,
{
PangoFont *font;
- font = pango_fc_font_map_new_font (fontmap, context, desc,
- patterns->patterns[i]);
+ font = pango_fc_font_map_new_font (fontmap, context, patterns->patterns[i]);
if (font)
pango_fontset_simple_append (simple, font);
}
diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h
index fe1e1b5b..6ae73ce2 100644
--- a/pango/pangofc-fontmap.h
+++ b/pango/pangofc-fontmap.h
@@ -29,6 +29,24 @@
G_BEGIN_DECLS
+/**
+ * PangoFcFontKey:
+ *
+ * An opaque structure containing all the information needed for
+ * loading a font #PangoFcFont.
+ *
+ * Since: 1.24
+ **/
+typedef struct _PangoFcFontKey PangoFcFontKey;
+
+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);
+
+/*
+ * PangoFcFontMap
+ */
+
#define PANGO_TYPE_FC_FONT_MAP (pango_fc_font_map_get_type ())
#define PANGO_FC_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FC_FONT_MAP, PangoFcFontMap))
#define PANGO_IS_FC_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FC_FONT_MAP))
@@ -64,7 +82,7 @@ struct _PangoFcFontMap
* @default_substitute: Substitutes in default values for
* unspecified fields in a #FcPattern. This will be called
* prior to creating a font for the pattern. May be %NULL.
- * Deprecated in favor of @context_substitute().
+ * Deprecated in favor of @font_key_substitute().
* @new_font: Creates a new #PangoFcFont for the specified
* pattern of the appropriate type for this font map. The
* @pattern argument must be passed to the "pattern" property
@@ -87,15 +105,18 @@ struct _PangoFcFontMap
* @context_key_copy.
* @context_key_hash: Gets a hash value for a context key
* @context_key_equal: Compares two context keys for equality.
- * @create_font: Creates a new #PangoFcFont for the specified
- * pattern of the appropriate type for this font map using
- * information from the context that is passed in. The
- * @pattern argument must be passed to the "pattern" property
- * of #PangoFcFont when you call g_object_new(). Deprecated
- * in favor of @create_font(). If %NULL, new_font() is used.
- * @context_substitute: Substitutes in default values for
+ * @font_key_substitute: Substitutes in default values for
* unspecified fields in a #FcPattern. This will be called
* prior to creating a font for the pattern. May be %NULL.
+ * (Since: 1.24)
+ * @create_font: Creates a new #PangoFcFont for the specified
+ * pattern of the appropriate type for this font map using
+ * information from the font key that is passed in. The
+ * @pattern member of @font_key can be retrieved using
+ * pango_fc_font_key_get_pattern() and must be passed to
+ * the "pattern" property of #PangoFcFont when you call
+ * g_object_new(). If %NULL, new_font() is used.
+ * (Since: 1.24)
*
* Class structure for #PangoFcFontMap.
**/
@@ -105,7 +126,7 @@ struct _PangoFcFontMapClass
PangoFontMapClass parent_class;
/*< public >*/
- /* Deprecated in favor of context_substitute */
+ /* Deprecated in favor of font_key_substitute */
void (*default_substitute) (PangoFcFontMap *fontmap,
FcPattern *pattern);
/* Deprecated in favor of create_font */
@@ -127,13 +148,11 @@ struct _PangoFcFontMapClass
gconstpointer key_a,
gconstpointer key_b);
- void (*context_substitute) (PangoFcFontMap *fontmap,
- PangoContext *context,
+ void (*font_key_substitute)(PangoFcFontMap *fontmap,
+ PangoFcFontKey *fontkey,
FcPattern *pattern);
PangoFcFont *(*create_font) (PangoFcFontMap *fontmap,
- PangoContext *context,
- const PangoFontDescription *desc,
- FcPattern *pattern);
+ PangoFcFontKey *fontkey);
/*< private >*/
/* Padding for future expansion */
diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h
index a8f3c23c..bc67ffb7 100644
--- a/pango/pangofc-private.h
+++ b/pango/pangofc-private.h
@@ -54,9 +54,9 @@ PangoFcDecoder *_pango_fc_font_get_decoder (PangoFcFont *font);
void _pango_fc_font_set_decoder (PangoFcFont *font,
PangoFcDecoder *decoder);
-gpointer _pango_fc_font_get_context_key (PangoFcFont *font);
-void _pango_fc_font_set_context_key (PangoFcFont *font,
- gpointer context_key);
+PangoFcFontKey *_pango_fc_font_get_font_key (PangoFcFont *fcfont);
+void _pango_fc_font_set_font_key (PangoFcFont *fcfont,
+ PangoFcFontKey *key);
void pango_fc_font_get_raw_extents (PangoFcFont *font,
FT_Int32 load_flags,