summaryrefslogtreecommitdiff
path: root/pango/pangofc-font.c
diff options
context:
space:
mode:
Diffstat (limited to 'pango/pangofc-font.c')
-rw-r--r--pango/pangofc-font.c59
1 files changed, 49 insertions, 10 deletions
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index e3585acf..2c0968d4 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -37,14 +37,33 @@ enum {
PROP_PATTERN
};
+typedef struct _GUnicharToGlyphCacheEntry GUnicharToGlyphCacheEntry;
+
+/* An entry in the fixed-size cache for the gunichar -> glyph mapping.
+ * The cache is indexed by the lower N bits of the gunichar (see
+ * GLYPH_CACHE_NUM_ENTRIES). For scripts with few code points,
+ * this should provide pretty much instant lookups.
+ *
+ * The "ch" field is zero if that cache entry is invalid.
+ */
+struct _GUnicharToGlyphCacheEntry
+{
+ gunichar ch;
+ PangoGlyph glyph;
+};
+
typedef struct _PangoFcFontPrivate PangoFcFontPrivate;
struct _PangoFcFontPrivate
{
PangoFcDecoder *decoder;
gpointer context_key;
+ GUnicharToGlyphCacheEntry *char_to_glyph_cache;
};
+#define GLYPH_CACHE_NUM_ENTRIES 256 /* should be power of two */
+#define GLYPH_CACHE_MASK (GLYPH_CACHE_NUM_ENTRIES - 1)
+
static gboolean pango_fc_font_real_has_char (PangoFcFont *font,
gunichar wc);
static guint pango_fc_font_real_get_glyph (PangoFcFont *font,
@@ -69,9 +88,6 @@ static PangoFontDescription *pango_fc_font_describe (PangoFont *font)
#define PANGO_FC_FONT_LOCK_FACE(font) (PANGO_FC_FONT_GET_CLASS (font)->lock_face (font))
#define PANGO_FC_FONT_UNLOCK_FACE(font) (PANGO_FC_FONT_GET_CLASS (font)->unlock_face (font))
-
-
-
G_DEFINE_TYPE (PangoFcFont, pango_fc_font, PANGO_TYPE_FONT)
static void
@@ -134,6 +150,9 @@ pango_fc_font_finalize (GObject *object)
if (priv->decoder)
_pango_fc_font_set_decoder (fcfont, NULL);
+ if (priv->char_to_glyph_cache)
+ g_free (priv->char_to_glyph_cache);
+
G_OBJECT_CLASS (pango_fc_font_parent_class)->finalize (object);
}
@@ -505,15 +524,35 @@ pango_fc_font_real_get_glyph (PangoFcFont *font,
FT_Face face;
FT_UInt index;
- face = PANGO_FC_FONT_LOCK_FACE (font);
-
- index = FcFreeTypeCharIndex (face, wc);
- if (index > (FT_UInt)face->num_glyphs)
- index = 0;
+ guint idx;
+ GUnicharToGlyphCacheEntry *entry;
- PANGO_FC_FONT_UNLOCK_FACE (font);
+ PangoFcFontPrivate *priv = font->priv;
+
+ if (G_UNLIKELY (priv->char_to_glyph_cache == NULL))
+ {
+ priv->char_to_glyph_cache = g_new0 (GUnicharToGlyphCacheEntry, GLYPH_CACHE_NUM_ENTRIES);
+ /* Make sure all cache entries are invalid initially */
+ priv->char_to_glyph_cache[0].ch = 1; /* char 1 cannot happen in bucket 0 */
+ }
+
+ idx = wc & GLYPH_CACHE_MASK;
+ entry = priv->char_to_glyph_cache + idx;
+
+ if (entry->ch != wc)
+ {
+ face = PANGO_FC_FONT_LOCK_FACE (font);
+ index = FcFreeTypeCharIndex (face, wc);
+ if (index > (FT_UInt)face->num_glyphs)
+ index = 0;
+
+ entry->ch = wc;
+ entry->glyph = index;
+
+ PANGO_FC_FONT_UNLOCK_FACE (font);
+ }
- return index;
+ return entry->glyph;
}
/**