diff options
author | Owen Taylor <otaylor@redhat.com> | 2005-06-14 19:02:47 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2005-06-14 19:02:47 +0000 |
commit | 8e7f0a9c9626c55568c4430c38be64ca0b59b118 (patch) | |
tree | f30b75aad011bbd99c71e9fe6104685f5732ac81 /pango/pangocairo-fcfont.c | |
parent | 8670c597a1a6b8f3332a35ed646fc06d13aaa7af (diff) | |
download | pango-8e7f0a9c9626c55568c4430c38be64ca0b59b118.tar.gz |
Add a (hopefully temporary) cache in front of getting metrics from Cairo.
2005-06-10 Owen Taylor <otaylor@redhat.com>
* pango/pangocairo-fcfont.c: Add a (hopefully temporary) cache
in front of getting metrics from Cairo.
* pango/pangocairo-fcfont.c: Remove some cast checks in critical
code paths.
Diffstat (limited to 'pango/pangocairo-fcfont.c')
-rw-r--r-- | pango/pangocairo-fcfont.c | 133 |
1 files changed, 87 insertions, 46 deletions
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c index 326cd3e5..e16b7bb4 100644 --- a/pango/pangocairo-fcfont.c +++ b/pango/pangocairo-fcfont.c @@ -41,6 +41,7 @@ typedef struct _PangoCairoFcFont PangoCairoFcFont; typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass; +typedef struct _PangoCairoFcGlyphInfo PangoCairoFcGlyphInfo; struct _PangoCairoFcFont { @@ -50,6 +51,8 @@ struct _PangoCairoFcFont cairo_scaled_font_t *scaled_font; cairo_matrix_t font_matrix; cairo_matrix_t ctm; + + GHashTable *glyph_info; }; struct _PangoCairoFcFontClass @@ -57,6 +60,12 @@ struct _PangoCairoFcFontClass PangoFcFontClass parent_class; }; +struct _PangoCairoFcGlyphInfo +{ + PangoRectangle logical_rect; + PangoRectangle ink_rect; +}; + GType pango_cairo_fc_font_get_type (void); static cairo_font_face_t *pango_cairo_fc_font_get_font_face (PangoCairoFont *font); @@ -88,7 +97,7 @@ pango_cairo_fc_font_get_font_face (PangoCairoFont *font) static cairo_scaled_font_t * pango_cairo_fc_font_get_scaled_font (PangoCairoFont *font) { - PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font); + PangoCairoFcFont *cffont = (PangoCairoFcFont *)font; if (!cffont->scaled_font) { @@ -132,6 +141,7 @@ cairo_font_iface_init (PangoCairoFontIface *iface) G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFont, pango_cairo_fc_font, PANGO_TYPE_FC_FONT, { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) }); + static void pango_cairo_fc_font_finalize (GObject *object) { @@ -142,79 +152,106 @@ pango_cairo_fc_font_finalize (GObject *object) if (cffont->scaled_font) cairo_scaled_font_destroy (cffont->scaled_font); + g_hash_table_destroy (cffont->glyph_info); + G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object); } static void -pango_cairo_fc_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect) +compute_glyph_extents (PangoFont *font, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) { - cairo_scaled_font_t *scaled_font; - - scaled_font = pango_cairo_fc_font_get_scaled_font (PANGO_CAIRO_FONT (font)); - - if (logical_rect) - { - /* It may well be worth caching the font_extents here, since getting them - * is pretty expensive. - */ - cairo_font_extents_t font_extents; - - cairo_scaled_font_extents (scaled_font, &font_extents); - - logical_rect->x = 0; - logical_rect->y = - font_extents.ascent * PANGO_SCALE; - logical_rect->width = 0; - logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; - } + PangoCairoFont *cfont = (PangoCairoFont *)font; + cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); + + /* It may well be worth caching the font_extents here, since getting them + * is pretty expensive. + */ + cairo_font_extents_t font_extents; + cairo_text_extents_t extents; + cairo_glyph_t cairo_glyph; + + cairo_scaled_font_extents (scaled_font, &font_extents); + + logical_rect->x = 0; + logical_rect->y = - font_extents.ascent * PANGO_SCALE; + logical_rect->width = 0; + logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; if (glyph) { - cairo_text_extents_t extents; - cairo_glyph_t cairo_glyph; - cairo_glyph.index = glyph; cairo_glyph.x = 0; cairo_glyph.y = 0; cairo_scaled_font_glyph_extents (scaled_font, &cairo_glyph, 1, &extents); - - if (ink_rect) - { - ink_rect->x = extents.x_bearing * PANGO_SCALE; - ink_rect->y = extents.y_bearing * PANGO_SCALE; - ink_rect->width = extents.width * PANGO_SCALE; - ink_rect->height = extents.height * PANGO_SCALE; - } - if (logical_rect) - logical_rect->width = extents.x_advance * PANGO_SCALE; + ink_rect->x = extents.x_bearing * PANGO_SCALE; + ink_rect->y = extents.y_bearing * PANGO_SCALE; + ink_rect->width = extents.width * PANGO_SCALE; + ink_rect->height = extents.height * PANGO_SCALE; + + logical_rect->width = extents.x_advance * PANGO_SCALE; } - else +} + +static PangoCairoFcGlyphInfo * +pango_cairo_fc_font_get_glyph_info (PangoFont *font, + PangoGlyph glyph) +{ + PangoCairoFcFont *cffont = (PangoCairoFcFont *)font; + PangoCairoFcGlyphInfo *info; + + info = g_hash_table_lookup (cffont->glyph_info, GUINT_TO_POINTER (glyph)); + if (!info) { - if (ink_rect) - { - ink_rect->x = 0; - ink_rect->y = 0; - ink_rect->width = 0; - ink_rect->height = 0; - } + info = g_new0 (PangoCairoFcGlyphInfo, 1); + + compute_glyph_extents (font, glyph, + &info->ink_rect, + &info->logical_rect); + + g_hash_table_insert (cffont->glyph_info, GUINT_TO_POINTER (glyph), info); } + + return info; +} + +static void +pango_cairo_fc_font_get_glyph_extents (PangoFont *font, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + PangoCairoFcGlyphInfo *info; + + info = pango_cairo_fc_font_get_glyph_info (font, glyph); + + if (ink_rect) + *ink_rect = info->ink_rect; + if (logical_rect) + *logical_rect = info->logical_rect; } static FT_Face pango_cairo_fc_font_lock_face (PangoFcFont *font) { - return cairo_ft_scaled_font_lock_face (pango_cairo_fc_font_get_scaled_font (PANGO_CAIRO_FONT (font))); + PangoCairoFont *cfont = (PangoCairoFont *)font; + cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); + + return cairo_ft_scaled_font_lock_face (scaled_font); } static void pango_cairo_fc_font_unlock_face (PangoFcFont *font) { - cairo_ft_scaled_font_unlock_face (pango_cairo_fc_font_get_scaled_font (PANGO_CAIRO_FONT (font))); + PangoCairoFont *cfont = (PangoCairoFont *)font; + cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); + + return cairo_ft_scaled_font_unlock_face (scaled_font); } static PangoGlyph @@ -260,6 +297,10 @@ pango_cairo_fc_font_class_init (PangoCairoFcFontClass *class) static void pango_cairo_fc_font_init (PangoCairoFcFont *cffont) { + cffont->glyph_info = g_hash_table_new_full (g_direct_hash, + NULL, + NULL, + (GDestroyNotify)g_free); } /******************** |