Index: ChangeLog =================================================================== RCS file: /cvs/gnome/pango/ChangeLog,v retrieving revision 1.1202 diff -u -p -r1.1202 ChangeLog --- ChangeLog 3 Oct 2005 03:21:46 -0000 1.1202 +++ ChangeLog 10 Oct 2005 03:59:35 -0000 @@ -1,3 +1,16 @@ +2005-10-09 Federico Mena Quintero + + * pango/pangocairo-fcfont.c (pango_cairo_fc_font_class_init): + Override PangoFcFontClass->get_glyph(). + (pango_cairo_fc_font_get_glyph): New method. We keep a small, + fixed-size cache for the gunichar -> glyph mapping. + (struct _PangoCairoFcFont): Add a char_to_glyph_cache array of a + fixed size. + (pango_cairo_fc_font_get_glyph): Implement the overriden method. + We first look the gunichar in our cache, and only look it up in + the parent class's method if it is not in the cache. + (pango_cairo_fc_font_finalize): Free the cache. + 2005-10-02 Behdad Esfahbod * pango/pango-engine.h: Add const to gchar * members of structs. Index: pango/pangocairo-fcfont.c =================================================================== RCS file: /cvs/gnome/pango/pango/pangocairo-fcfont.c,v retrieving revision 1.15 diff -u -p -r1.15 pangocairo-fcfont.c --- pango/pangocairo-fcfont.c 15 Aug 2005 19:41:00 -0000 1.15 +++ pango/pangocairo-fcfont.c 10 Oct 2005 03:59:36 -0000 @@ -44,6 +44,18 @@ typedef struct _PangoCairoFcFont Pa typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass; typedef struct _PangoCairoFcGlyphInfo PangoCairoFcGlyphInfo; +/* An entry in the fixed-size cache for the gunichar -> glyph mapping. + * The cache is indexed by the lower 8 bits of the gunichar. For scripts + * with few code points, this should provide pretty much instant lookups. + * + * The "ch" field is zero if that cache entry is invalid. + */ +typedef struct +{ + gunichar ch; + PangoGlyph glyph; +} GlyphCacheEntry; + struct _PangoCairoFcFont { PangoFcFont font; @@ -55,6 +67,8 @@ struct _PangoCairoFcFont cairo_font_options_t *options; GHashTable *glyph_info; + + GlyphCacheEntry *char_to_glyph_cache; }; struct _PangoCairoFcFontClass @@ -161,6 +175,8 @@ pango_cairo_fc_font_finalize (GObject *o g_hash_table_destroy (cffont->glyph_info); + g_free (cffont->char_to_glyph_cache); + G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object); } @@ -313,6 +329,47 @@ pango_cairo_fc_font_unlock_face (PangoFc } static PangoGlyph +pango_cairo_fc_font_get_glyph (PangoFcFont *font, + gunichar wc) +{ + PangoCairoFcFont *cffont = (PangoCairoFcFont *)font; + guint idx; + GlyphCacheEntry *entry; + + /* We create the cache dynamically because although we'll have a lot of + * PangoCairoFcFont structures (one per font in the fontset, as many as needed + * to cover the whole Unicode space), we'll only end up using a few of them + * for the user's actual text. + */ + if (cffont->char_to_glyph_cache == NULL) { + cffont->char_to_glyph_cache = g_new0 (GlyphCacheEntry, 256); +#if 0 + printf ("creating glyph cache for cffont %p\n", cffont); +#endif + } + + idx = wc & 0x00ff; + entry = cffont->char_to_glyph_cache + idx; + + if (entry->ch != wc || entry->ch == 0) + { +#if 0 + printf ("cache MISS: cffont %p, gunichar %x = '%c'\n", cffont, wc, (wc < 128) ? wc : 0); +#endif + entry->ch = wc; + entry->glyph = ((PangoFcFontClass *) pango_cairo_fc_font_parent_class)->get_glyph (font, wc); + } + else + { +#if 0 + printf ("cache HIT: cffont %p, gunichar %x = '%c'\n", cffont, wc, (wc < 128) ? wc : 0); +#endif + } + + return entry->glyph; +} + +static PangoGlyph pango_cairo_fc_font_real_get_unknown_glyph (PangoFcFont *font, gunichar wc) { @@ -349,6 +406,7 @@ pango_cairo_fc_font_class_init (PangoCai fc_font_class->lock_face = pango_cairo_fc_font_lock_face; fc_font_class->unlock_face = pango_cairo_fc_font_unlock_face; + fc_font_class->get_glyph = pango_cairo_fc_font_get_glyph; fc_font_class->get_unknown_glyph = pango_cairo_fc_font_real_get_unknown_glyph; fc_font_class->shutdown = pango_cairo_fc_font_shutdown; } @@ -433,6 +491,6 @@ _pango_cairo_fc_font_new (PangoCairoFcFo cairo_matrix_init_identity (&cffont->ctm); cffont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context)); - + return PANGO_FC_FONT (cffont); }