Index: pango/pangocairo-atsuifont.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-atsuifont.c,v
retrieving revision 1.7
diff -u -p -r1.7 pangocairo-atsuifont.c
--- pango/pangocairo-atsuifont.c	27 Jan 2006 19:14:29 -0000	1.7
+++ pango/pangocairo-atsuifont.c	2 Feb 2006 12:02:01 -0000
@@ -22,24 +22,19 @@
 
 #include <config.h>
 
-#include "pangoatsui-private.h"
-#include "pangocairo.h"
+#include "pango-fontmap.h"
 #include "pangocairo-private.h"
 #include "pangocairo-atsui.h"
 #include "pangocairo-atsuifont.h"
+#include "pangoatsui-private.h"
 
 struct _PangoCairoATSUIFont
 {
   PangoATSUIFont font;
-
-  ATSUFontID font_id;
-  cairo_font_face_t *font_face;
-  cairo_scaled_font_t *scaled_font;
-  cairo_matrix_t font_matrix;
-  cairo_matrix_t ctm;
-  cairo_font_options_t *options;
+  PangoCairoFontPrivate cf_priv;
 
   double size;
+  ATSUFontID font_id;
 };
 
 struct _PangoCairoATSUIFontClass
@@ -49,15 +44,13 @@ struct _PangoCairoATSUIFontClass
 
 
 
-static cairo_font_face_t *pango_cairo_atsui_font_get_font_face (PangoCairoFont *font);
-
 /**
  * pango_cairo_atsui_font_get_atsu_font_id:
  * @cafont: A #PangoCairoATSUIFont
  *
  * Returns the ATSUFontID of a font.
  *
- * Return value: the ATSUFontID associated to @cafont.
+ * Return value: the ATSUFontID associated with @cafont.
  *
  * Since: 1.12
  */
@@ -68,114 +61,14 @@ pango_cairo_atsui_font_get_atsu_font_id 
 }
 
 static void
-pango_cairo_atsui_font_install (PangoCairoFont *font,
-				cairo_t        *cr)
-{
-  PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font);
-
-  cairo_set_font_face (cr,
-		       pango_cairo_atsui_font_get_font_face (font));
-
-  cairo_set_font_matrix (cr, &cafont->font_matrix);
-  cairo_set_font_options (cr, cafont->options);
-}
-
-static cairo_font_face_t *
-pango_cairo_atsui_font_get_font_face (PangoCairoFont *font)
-{
-  PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font);
-
-  if (!cafont->font_face)
-    {
-      cafont->font_face = cairo_atsui_font_face_create_for_atsu_font_id (cafont->font_id);
-
-      /* Failure of the above should only occur for out of memory,
-       * we can't proceed at that point
-       */
-      if (!cafont->font_face)
-	g_error ("Unable to create ATSUI cairo font face.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
-    }
-
-  return cafont->font_face;
-}
-
-static cairo_scaled_font_t *
-pango_cairo_atsui_font_get_scaled_font (PangoCairoFont *font)
-{
-  PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font);
-
-  if (!cafont->scaled_font)
-    {
-      cairo_font_face_t *font_face;
-
-      font_face = pango_cairo_atsui_font_get_font_face (font);
-      cafont->scaled_font = cairo_scaled_font_create (font_face,
-						      &cafont->font_matrix,
-						      &cafont->ctm,
-						      cafont->options);
-
-      /* Failure of the above should only occur for out of memory,
-       * we can't proceed at that point
-       */
-      if (!cafont->scaled_font)
-	g_error ("Unable to create ATSUI cairo scaled font.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
-    }
-  
-  return cafont->scaled_font;
-}
-
-static void
 cairo_font_iface_init (PangoCairoFontIface *iface)
 {
-  iface->install = pango_cairo_atsui_font_install;
-  iface->get_font_face = pango_cairo_atsui_font_get_font_face;
-  iface->get_scaled_font = pango_cairo_atsui_font_get_scaled_font;
+  iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoATSUIFont, cf_priv);
 }
 
 G_DEFINE_TYPE_WITH_CODE (PangoCairoATSUIFont, pango_cairo_atsui_font, PANGO_TYPE_ATSUI_FONT,
     { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) });
 
-static void
-pango_cairo_atsui_font_get_glyph_extents (PangoFont        *font,
-					  PangoGlyph        glyph,
-					  PangoRectangle   *ink_rect,
-					  PangoRectangle   *logical_rect)
-{
-  cairo_scaled_font_t *scaled_font;
-  cairo_text_extents_t extents;
-  cairo_glyph_t cairo_glyph;
-
-  scaled_font = pango_cairo_atsui_font_get_scaled_font (PANGO_CAIRO_FONT (font));
-
-  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)
-    {
-      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 = extents.x_advance * PANGO_SCALE;
-      logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE;
-    }
-}
-
-
 static PangoFontMetrics *
 pango_cairo_atsui_font_get_metrics (PangoFont        *font,
 				    PangoLanguage    *language)
@@ -211,14 +104,27 @@ pango_cairo_atsui_font_finalize (GObject
 {
   PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (object);
 
-  cairo_font_face_destroy (cafont->font_face);
-  cairo_scaled_font_destroy (cafont->scaled_font);
-  cairo_font_options_destroy (cafont->options);
+  _pango_cairo_font_private_finalize (&cafont->cf_priv);
 
   G_OBJECT_CLASS (pango_cairo_atsui_font_parent_class)->finalize (object);
 }
 
 static void
+pango_cairo_atsui_font_get_glyph_extents (PangoFont        *font,
+					  PangoGlyph        glyph,
+					  PangoRectangle   *ink_rect,
+					  PangoRectangle   *logical_rect)
+{
+  PangoCairoATSUIFont *cafont = (PangoCairoATSUIFont *)font;
+
+  _pango_cairo_font_with_private_get_glyph_extents ((PangoCairoFont *)font,
+						    &cafont->cf_priv,
+						    glyph,
+						    ink_rect,
+						    logical_rect);
+}
+
+static void
 pango_cairo_atsui_font_class_init (PangoCairoATSUIFontClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
@@ -241,12 +147,16 @@ _pango_cairo_atsui_font_new (PangoCairoA
 			     const char                 *postscript_name,
 			     const PangoFontDescription *desc)
 {
-  PangoCairoATSUIFont *cafont;
+  PangoCairoATSUIFont *cafont = NULL;
   PangoATSUIFont *afont;
   CFStringRef cfstr;
   ATSFontRef font_ref;
   const PangoMatrix *pango_ctm;
   ATSUFontID font_id;
+  cairo_scaled_font_t *scaled_font;
+  cairo_font_face_t *font_face;
+  cairo_matrix_t font_matrix, ctm;
+  cairo_font_options_t *font_options;
 
   cfstr = CFStringCreateWithCString (NULL, postscript_name, 
 				     kCFStringEncodingUTF8);
@@ -257,7 +167,11 @@ _pango_cairo_atsui_font_new (PangoCairoA
   CFRelease (cfstr);
 
   if (!font_id)
-    return NULL;
+    goto failed;
+
+  font_face = cairo_atsui_font_face_create_for_atsu_font_id (font_id);
+  if (!font_face)
+    goto failed;
 
   cafont = g_object_new (PANGO_TYPE_CAIRO_ATSUI_FONT, NULL);
   afont = PANGO_ATSUI_FONT (cafont);
@@ -274,6 +188,7 @@ _pango_cairo_atsui_font_new (PangoCairoA
     }  
 
   cairo_matrix_init_scale (&cafont->font_matrix, cafont->size, cafont->size);
+
   pango_ctm = pango_context_get_matrix (context);
   if (pango_ctm)
     cairo_matrix_init (&cafont->ctm,
@@ -286,6 +201,22 @@ _pango_cairo_atsui_font_new (PangoCairoA
     cairo_matrix_init_identity (&cafont->ctm);
 
   cafont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
+  scaled_font = _pango_cairo_font_private_scaled_font_new (&cafont->cf_priv,
+							   font_face,
+							   &font_matrix,
+							   &ctm,
+							   font_options);
+
+  cairo_font_face_destroy (font_face);
+  cairo_font_options_destroy (font_options);
+
+  if (!scaled_font)
+    goto failed;
 
   return afont;
+
+failed:
+  if (cafont)
+    g_object_unref (cafont);
+  return NULL;
 }
Index: pango/pangocairo-fcfont.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-fcfont.c,v
retrieving revision 1.27
diff -u -p -r1.27 pangocairo-fcfont.c
--- pango/pangocairo-fcfont.c	2 Feb 2006 10:52:49 -0000	1.27
+++ pango/pangocairo-fcfont.c	2 Feb 2006 12:02:02 -0000
@@ -21,9 +21,6 @@
 
 #include <config.h>
 
-#include <math.h>
-#include <stdlib.h>
-
 #include <cairo-ft.h>
 
 #include "pango-fontmap.h"
@@ -38,34 +35,6 @@
 #define PANGO_CAIRO_IS_FONT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_FC_FONT))
 #define PANGO_CAIRO_FC_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass))
 
-typedef struct _PangoCairoFcFont      PangoCairoFcFont;
-typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass;
-
-typedef struct _GlyphExtentsCacheEntry    GlyphExtentsCacheEntry;
-typedef struct _GUnicharToGlyphCacheEntry GUnicharToGlyphCacheEntry;
-
-
-/* define one of these to profile one of the caches */
-#undef PROFILE_GLYPH_EXTENTS_CACHE
-#undef PROFILE_CHAR_TO_GLYPH_CACHE
-
-#undef PROFILE_GLYPH_CACHE
-#ifdef PROFILE_GLYPH_EXTENTS_CACHE
-# define PROFILE_GLYPH_CACHE GlyphExtentsCacheEntry
-#endif
-#ifdef PROFILE_CHAR_TO_GLYPH_CACHE
-# define PROFILE_GLYPH_CACHE GUnicharToGlyphCacheEntry
-#endif
-#ifdef PROFILE_GLYPH_CACHE
-static long num_cairo_fc_fonts;
-static long max_cairo_fc_fonts;
-static long num_glyph_caches;
-static long max_glyph_caches;
-static long num_glyph_cache_hits;
-static long num_glyph_cache_misses;
-#endif
-
-
 
 #define GLYPH_CACHE_NUM_ENTRIES 256 /* should be power of two */
 #define GLYPH_CACHE_MASK (GLYPH_CACHE_NUM_ENTRIES - 1)
@@ -83,30 +52,15 @@ struct _GUnicharToGlyphCacheEntry
   PangoGlyph glyph;
 };
 
-/* An entry in the fixed-size cache for the glyph -> ink_rect mapping.
- * The cache is indexed by the lower N bits of the glyph (see
- * GLYPH_CACHE_NUM_ENTRIES).  For scripts with few glyphs,
- * this should provide pretty much instant lookups.
- */
-struct _GlyphExtentsCacheEntry
-{
-  PangoGlyph     glyph;
-  int            width;
-  PangoRectangle ink_rect;
-};
+typedef struct _PangoCairoFcFont      PangoCairoFcFont;
+typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass;
+typedef struct _GUnicharToGlyphCacheEntry GUnicharToGlyphCacheEntry;
 
 struct _PangoCairoFcFont
 {
   PangoFcFont font;
-
-  cairo_font_face_t *font_face;
-  cairo_scaled_font_t *scaled_font;
-  cairo_matrix_t font_matrix;
-  cairo_matrix_t ctm;
-  cairo_font_options_t *options;
-
-  PangoRectangle font_extents;
-  GlyphExtentsCacheEntry    *glyph_extents_cache;
+  PangoCairoFontPrivate cf_priv;
+  
   GUnicharToGlyphCacheEntry *char_to_glyph_cache;
 };
 
@@ -117,80 +71,14 @@ struct _PangoCairoFcFontClass
 
 GType pango_cairo_fc_font_get_type (void);
 
-static cairo_font_face_t *pango_cairo_fc_font_get_font_face (PangoCairoFont *font);
-
-/*******************************
- *       Utility functions     *
- *******************************/
-
-static cairo_font_face_t *
-pango_cairo_fc_font_get_font_face (PangoCairoFont *font)
-{
-  PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font);
-  PangoFcFont *fcfont = PANGO_FC_FONT (cffont);
-
-  if (!cffont->font_face)
-    {
-      cffont->font_face = cairo_ft_font_face_create_for_pattern (fcfont->font_pattern);
-      
-      /* Failure of the above should only occur for out of memory,
-       * we can't proceed at that point
-       */
-      if (!cffont->font_face)
-	g_error ("Unable to create FT2 cairo font face.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
-    }
-  
-  return cffont->font_face;
-}
-
-static cairo_scaled_font_t *
-pango_cairo_fc_font_get_scaled_font (PangoCairoFont *font)
-{
-  PangoCairoFcFont *cffont = (PangoCairoFcFont *)font;
-
-  if (!cffont->scaled_font)
-    {
-      cairo_font_face_t *font_face;
-
-      font_face = pango_cairo_fc_font_get_font_face (font);
-
-      cffont->scaled_font = cairo_scaled_font_create (font_face,
-						      &cffont->font_matrix,
-						      &cffont->ctm,
-						      cffont->options);
-
-      /* Failure of the above should only occur for out of memory,
-       * we can't proceed at that point
-       */
-      if (!cffont->scaled_font)
-	g_error ("Unable to create FT2 cairo scaled font.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
-    }
-  
-  return cffont->scaled_font;
-}
-
 /********************************
  *    Method implementations    *
  ********************************/
 
 static void
-pango_cairo_fc_font_install (PangoCairoFont *font,
-			     cairo_t        *cr)
-{
-  PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font);
-
-  cairo_set_font_face (cr,
-		       pango_cairo_fc_font_get_font_face (font));
-  cairo_set_font_matrix (cr, &cffont->font_matrix);
-  cairo_set_font_options (cr, cffont->options);
-}
-
-static void
 cairo_font_iface_init (PangoCairoFontIface *iface)
 {
-  iface->install = pango_cairo_fc_font_install;
-  iface->get_font_face = pango_cairo_fc_font_get_font_face;
-  iface->get_scaled_font = pango_cairo_fc_font_get_scaled_font;
+  iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoFcFont, cf_priv);
 }
 
 G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFont, pango_cairo_fc_font, PANGO_TYPE_FC_FONT,
@@ -201,38 +89,12 @@ pango_cairo_fc_font_finalize (GObject *o
 {
   PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (object);
 
-  if (cffont->font_face)
-    cairo_font_face_destroy (cffont->font_face);
-  if (cffont->scaled_font)
-    cairo_scaled_font_destroy (cffont->scaled_font);
-  if (cffont->options)
-    cairo_font_options_destroy (cffont->options);
-
-
-  if (cffont->glyph_extents_cache)
-    {
-      g_free (cffont->glyph_extents_cache);
-#ifdef PROFILE_GLYPH_EXTENTS_CACHE
-      num_glyph_caches--;
-      g_assert (num_glyph_caches >= 0);
-#endif
-    }
+  _pango_cairo_font_private_finalize (&cffont->cf_priv);
 
   if (cffont->char_to_glyph_cache)
-    {
-      g_free (cffont->char_to_glyph_cache);
-#ifdef PROFILE_CHAR_TO_GLYPH_CACHE
-      num_glyph_caches--;
-      g_assert (num_glyph_caches >= 0);
-#endif
-    }
+    g_free (cffont->char_to_glyph_cache);
 
   G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object);
-
-#ifdef PROFILE_GLYPH_CACHE
-  num_cairo_fc_fonts--;
-  g_assert (num_cairo_fc_fonts >= 0);
-#endif
 }
 
 /* This function is cut-and-pasted from pangocairo-fcfont.c - it might be
@@ -242,8 +104,8 @@ static PangoFontMetrics *
 pango_cairo_fc_font_get_metrics (PangoFont     *font,
 				 PangoLanguage *language)
 {
-  PangoFcFont *fcfont = PANGO_FC_FONT (font);
   PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font);
+  PangoFcFont *fcfont = (PangoFcFont *)font;
   PangoFcMetricsInfo *info = NULL; /* Quiet gcc */
   GSList *tmp_list;      
 
@@ -263,6 +125,8 @@ pango_cairo_fc_font_get_metrics (PangoFo
   if (!tmp_list)
     {
       PangoContext *context;
+      cairo_font_options_t *font_options;
+      
 
       if (!fcfont->fontmap)
 	return pango_font_metrics_new ();
@@ -275,7 +139,10 @@ pango_cairo_fc_font_get_metrics (PangoFo
 
       context = pango_fc_font_map_create_context (PANGO_FC_FONT_MAP (fcfont->fontmap));
       pango_context_set_language (context, language);
-      pango_cairo_context_set_font_options (context, cffont->options);
+      font_options = cairo_font_options_create ();
+      cairo_scaled_font_get_font_options (cffont->cf_priv.scaled_font, font_options);
+      pango_cairo_context_set_font_options (context, font_options);
+      cairo_font_options_destroy (font_options);
 
       info->metrics = pango_fc_font_create_metrics_for_context (fcfont, context);
 
@@ -288,19 +155,17 @@ pango_cairo_fc_font_get_metrics (PangoFo
 static FT_Face
 pango_cairo_fc_font_lock_face (PangoFcFont *font)
 {
-  PangoCairoFont *cfont = (PangoCairoFont *)font;
-  cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont);
+  PangoCairoFcFont *cffont = (PangoCairoFcFont *)font;
   
-  return cairo_ft_scaled_font_lock_face (scaled_font);
+  return cairo_ft_scaled_font_lock_face (cffont->cf_priv.scaled_font);
 }
 
 static void
 pango_cairo_fc_font_unlock_face (PangoFcFont *font)
 {
-  PangoCairoFont *cfont = (PangoCairoFont *)font;
-  cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont);
+  PangoCairoFcFont *cffont = (PangoCairoFcFont *)font;
   
-  cairo_ft_scaled_font_unlock_face (scaled_font);
+  return cairo_ft_scaled_font_unlock_face (cffont->cf_priv.scaled_font);
 }
 
 static PangoGlyph
@@ -311,16 +176,11 @@ pango_cairo_fc_font_get_glyph (PangoFcFo
   guint idx;
   GUnicharToGlyphCacheEntry *entry;
 
-  if (cffont->char_to_glyph_cache == NULL)
+  if (G_UNLIKELY (!cffont->char_to_glyph_cache))
     {
       cffont->char_to_glyph_cache = g_new0 (GUnicharToGlyphCacheEntry, GLYPH_CACHE_NUM_ENTRIES);
       /* Make sure all cache entries are invalid initially */
       cffont->char_to_glyph_cache[0].ch = 1; /* char 1 cannot happen in bucket 0 */
-#ifdef PROFILE_CHAR_TO_GLYPH_CACHE
-      num_glyph_caches++;
-      if (num_glyph_caches > max_glyph_caches)
-	max_glyph_caches = num_glyph_caches;
-#endif
     }
 
   idx = wc & GLYPH_CACHE_MASK;
@@ -328,169 +188,35 @@ pango_cairo_fc_font_get_glyph (PangoFcFo
 
   if (entry->ch != wc)
     {
-#ifdef PROFILE_CHAR_TO_GLYPH_CACHE
-      num_glyph_cache_misses++;
-      /*g_message ("cache MISS: cffont %p, gunichar %x = '%c'", cffont, wc, (wc < 128) ? wc : 0);*/
-#endif
       entry->ch = wc;
       entry->glyph = ((PangoFcFontClass *) pango_cairo_fc_font_parent_class)->get_glyph (font, wc);
     }
-#ifdef PROFILE_CHAR_TO_GLYPH_CACHE
-  else
-    {
-      num_glyph_cache_hits++;
-      /*g_message ("cache HIT: cffont %p, gunichar %x = '%c'", cffont, wc, (wc < 128) ? wc : 0);*/
-    }
-#endif
 
   return entry->glyph;
 }
 
 static void
-pango_cairo_fc_font_glyph_extents_cache_init (PangoCairoFcFont *cffont)
-{
-  PangoCairoFont *cfont = (PangoCairoFont *)cffont;
-  cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont);
-  cairo_font_extents_t font_extents;
-  cairo_scaled_font_extents (scaled_font, &font_extents);
-
-  cffont->font_extents.x = 0;
-  cffont->font_extents.y = - font_extents.ascent * PANGO_SCALE;
-  cffont->font_extents.height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE;
-  cffont->font_extents.width = 0;
-
-  cffont->glyph_extents_cache = g_new0 (GlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES);
-  /* Make sure all cache entries are invalid initially */
-  cffont->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */
-  
-#ifdef PROFILE_GLYPH_EXTENTS_CACHE
-  num_glyph_caches++;
-  if (num_glyph_caches > max_glyph_caches)
-    max_glyph_caches = num_glyph_caches;
-#endif
-}
-
-/* Fills in the glyph extents cache entry
- */
-static void
-compute_glyph_extents (PangoCairoFcFont       *cffont,
-		       PangoGlyph              glyph,
-		       GlyphExtentsCacheEntry *entry)
-{
-  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 (cffont->scaled_font,
-				   &cairo_glyph, 1, &extents);
-  
-  entry->glyph = glyph;
-  entry->width = extents.x_advance * PANGO_SCALE;
-  entry->ink_rect.x = extents.x_bearing * PANGO_SCALE;
-  entry->ink_rect.y = extents.y_bearing * PANGO_SCALE;
-  entry->ink_rect.width = extents.width * PANGO_SCALE;
-  entry->ink_rect.height = extents.height * PANGO_SCALE;
-}
-     
-static GlyphExtentsCacheEntry *
-pango_cairo_fc_font_get_glyph_extents_cache_entry (PangoCairoFcFont       *cffont,
-						   PangoGlyph              glyph)
-{
-  GlyphExtentsCacheEntry *entry;
-  guint idx;
-
-  idx = glyph & GLYPH_CACHE_MASK;
-  entry = cffont->glyph_extents_cache + idx;
-
-  if (entry->glyph != glyph)
-    {
-#ifdef PROFILE_GLYPH_EXTENTS_CACHE
-      num_glyph_cache_misses++;
-      /*g_message ("cache MISS: cffont %p, glyph %x", cffont, glyph);*/
-#endif
-      compute_glyph_extents (cffont, glyph, entry);
-    }
-#ifdef PROFILE_GLYPH_EXTENTS_CACHE
-  else
-    {
-      num_glyph_cache_hits++;
-      /*g_message ("cache HIT: cffont %p, glyph %x = '%c'", cffont, glyph);*/
-    }
-#endif
-
-  return entry;
-}
-
-static void
 pango_cairo_fc_font_get_glyph_extents (PangoFont      *font,
 				       PangoGlyph      glyph,
 				       PangoRectangle *ink_rect,
 				       PangoRectangle *logical_rect)
 {
   PangoCairoFcFont *cffont = (PangoCairoFcFont *)font;
-  GlyphExtentsCacheEntry *entry;
-
-  /* We need to initialize the cache here, since we use cffont->font_extents
-   */
-  if (cffont->glyph_extents_cache == NULL)
-    pango_cairo_fc_font_glyph_extents_cache_init (cffont);
-
-  if (glyph == PANGO_GLYPH_NULL)
-    {
-      if (ink_rect)
-	*ink_rect = cffont->font_extents;
-      if (logical_rect)
-	*logical_rect = cffont->font_extents;
-      return;
-    }
-  else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) 
-    {
-      _pango_cairo_get_glyph_extents_missing((PangoCairoFont *)font, glyph, ink_rect, logical_rect);
-      return;
-    }
-
-  entry = pango_cairo_fc_font_get_glyph_extents_cache_entry (cffont, glyph);
 
-  if (ink_rect)
-    *ink_rect = entry->ink_rect;
-  if (logical_rect)
-    {
-      *logical_rect = cffont->font_extents;
-      logical_rect->width = entry->width;
-    }
+  _pango_cairo_font_with_private_get_glyph_extents ((PangoCairoFont *)font,
+						    &cffont->cf_priv,
+						    glyph,
+						    ink_rect,
+						    logical_rect);
 }
 
 static void
 pango_cairo_fc_font_shutdown (PangoFcFont *fcfont)
 {
-  PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (fcfont);
-  if (cffont->scaled_font)
-    {
-      cairo_scaled_font_destroy (cffont->scaled_font);
-      cffont->scaled_font = NULL;
-    }
-  if (cffont->font_face)
-    {
-      cairo_font_face_destroy (cffont->font_face);
-      cffont->font_face = NULL;
-    }
-}
+  PangoCairoFcFont *cffont = (PangoCairoFcFont *)fcfont;
 
-#ifdef PROFILE_GLYPH_CACHE
-static void
-profile_glyph_cache_exit_cb (void)
-{
-  g_message ("Profiled %s cache", G_STRINGIFY (PROFILE_GLYPH_CACHE));
-  g_message ("Maximum number of PangoCairoFcFont objects: %ld", max_cairo_fc_fonts);
-  g_message ("Maximum number of glyph caches created: %ld (%ld KB)", max_glyph_caches, (max_glyph_caches * sizeof (PROFILE_GLYPH_CACHE) * GLYPH_CACHE_NUM_ENTRIES) / 1024);
-  g_message ("Glyph cache hits: %ld", num_glyph_cache_hits);
-  g_message ("Glyph cache misses: %ld", num_glyph_cache_misses);
-  g_message ("Glyph cache miss rate: %f%%", 100.0 * (double) num_glyph_cache_misses / (num_glyph_cache_misses + num_glyph_cache_hits));
+  _pango_cairo_font_private_finalize (&cffont->cf_priv);
 }
-#endif
 
 static void
 pango_cairo_fc_font_class_init (PangoCairoFcFontClass *class)
@@ -508,20 +234,11 @@ pango_cairo_fc_font_class_init (PangoCai
   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->shutdown = pango_cairo_fc_font_shutdown;
-
-#ifdef PROFILE_GLYPH_CACHE
-  atexit (profile_glyph_cache_exit_cb);
-#endif
 }
 
 static void
 pango_cairo_fc_font_init (PangoCairoFcFont *cffont)
 {
-#ifdef PROFILE_GLYPH_CACHE
-  num_cairo_fc_fonts++;
-  if (num_cairo_fc_fonts > max_cairo_fc_fonts)
-    max_cairo_fc_fonts = num_cairo_fc_fonts;
-#endif
 }
 
 /********************
@@ -575,14 +292,23 @@ _pango_cairo_fc_font_new (PangoCairoFcFo
 			  const PangoFontDescription *desc,
 			  FcPattern	             *pattern)
 {
-  PangoCairoFcFont *cffont;
+  PangoCairoFcFont *cffont = NULL;
   const PangoMatrix *pango_ctm;
   FcMatrix *fc_matrix;
   double size;
+  FT_Face face;
+  cairo_scaled_font_t *scaled_font;
+  cairo_font_face_t *font_face;
+  cairo_matrix_t font_matrix, ctm;
+  cairo_font_options_t *font_options;
   
   g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (cffontmap), NULL);
   g_return_val_if_fail (pattern != NULL, NULL);
 
+  font_face = cairo_ft_font_face_create_for_pattern (pattern);
+  if (!font_face)
+    goto failed;
+
   cffont = g_object_new (PANGO_TYPE_CAIRO_FC_FONT,
 			 "pattern", pattern,
 			 NULL);
@@ -590,7 +316,7 @@ _pango_cairo_fc_font_new (PangoCairoFcFo
   if  (FcPatternGetMatrix (pattern,
 			   FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
     {
-      cairo_matrix_init (&cffont->font_matrix,
+      cairo_matrix_init (&font_matrix,
 			 fc_matrix->xx,
 			 - fc_matrix->yx,
 			 - fc_matrix->xy,
@@ -598,27 +324,50 @@ _pango_cairo_fc_font_new (PangoCairoFcFo
 			 0., 0.);
     }
   else
-    cairo_matrix_init_identity (&cffont->font_matrix);
+    cairo_matrix_init_identity (&font_matrix);
 
   pango_ctm = pango_context_get_matrix (context);
 
   size = get_font_size (cffontmap, context, desc, pattern, pango_ctm);
 
-  cairo_matrix_scale (&cffont->font_matrix,
-		      size / PANGO_SCALE, size / PANGO_SCALE);
+  cairo_matrix_scale (&font_matrix, size / PANGO_SCALE, size / PANGO_SCALE);
 
   if (pango_ctm)
-    cairo_matrix_init (&cffont->ctm,
+    cairo_matrix_init (&ctm,
 		       pango_ctm->xx,
 		       pango_ctm->yx,
 		       pango_ctm->xy,
 		       pango_ctm->yy,
 		       0., 0.);
   else
-    cairo_matrix_init_identity (&cffont->ctm);
+    cairo_matrix_init_identity (&ctm);
 
+  font_options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
 
-  cffont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
-  
-  return PANGO_FC_FONT (cffont);
+  scaled_font = _pango_cairo_font_private_scaled_font_new (&cffont->cf_priv,
+							   font_face,
+							   &font_matrix,
+							   &ctm,
+							   font_options);
+
+  cairo_font_face_destroy (font_face);
+  cairo_font_options_destroy (font_options);
+
+  if (!scaled_font)
+    goto failed;
+
+  /* hack: we lock/unlock the face to make sure it gets loaded.
+   * fixes problem with fonts that are not readable.
+   */
+  face = cairo_ft_scaled_font_lock_face (scaled_font);
+  if (!face)
+    goto failed;
+  cairo_ft_scaled_font_unlock_face (scaled_font);
+
+  return (PangoFcFont *)cffont;
+
+failed:
+  if (cffont)
+    g_object_unref (cffont);
+  return NULL;
 }
Index: pango/pangocairo-font.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-font.c,v
retrieving revision 1.15
diff -u -p -r1.15 pangocairo-font.c
--- pango/pangocairo-font.c	2 Feb 2006 10:52:49 -0000	1.15
+++ pango/pangocairo-font.c	2 Feb 2006 12:02:02 -0000
@@ -30,6 +30,30 @@
 
 PangoCairoWarningHistory _pango_cairo_warning_history = { FALSE };
 
+#define PANGO_CAIRO_FONT_PRIVATE(font)		\
+  (&G_STRUCT_MEMBER (PangoCairoFontPrivate,	\
+		     font,			\
+		     PANGO_CAIRO_FONT_GET_IFACE(PANGO_CAIRO_FONT(font))->cf_priv_offset))
+
+
+#define GLYPH_CACHE_NUM_ENTRIES 256 /* should be power of two */
+#define GLYPH_CACHE_MASK (GLYPH_CACHE_NUM_ENTRIES - 1)
+
+/* An entry in the fixed-size cache for the glyph -> ink_rect mapping.
+ * The cache is indexed by the lower N bits of the glyph (see
+ * GLYPH_CACHE_NUM_ENTRIES).  For scripts with few glyphs,
+ * this should provide pretty much instant lookups.
+ */
+struct _PangoCairoGlyphExtentsCacheEntry
+{
+  PangoGlyph     glyph;
+  int            width;
+  PangoRectangle ink_rect;
+};
+
+
+
+
 GType
 pango_cairo_font_get_type (void)
 {
@@ -61,19 +85,177 @@ pango_cairo_font_get_type (void)
   return cairo_font_type;
 }
 
-/**
- * _pango_cairo_font_install:
- * @font: a #PangoCairoFont
- * @cr: a #cairo_t
- *
- * Makes @font the current font for rendering in the specified
- * Cairo context.
- **/
+cairo_scaled_font_t *
+_pango_cairo_font_private_scaled_font_new (PangoCairoFontPrivate      *cf_priv,
+					   cairo_font_face_t          *font_face,
+					   const cairo_matrix_t       *font_matrix,
+					   const cairo_matrix_t       *ctm,
+					   const cairo_font_options_t *font_options)
+{
+  cf_priv->scaled_font = cairo_scaled_font_create (font_face,
+						font_matrix,
+						ctm,
+						font_options);
+
+  return cf_priv->scaled_font;
+}
+
 void
-_pango_cairo_font_install (PangoCairoFont *font,
+_pango_cairo_font_private_finalize (PangoCairoFontPrivate *cf_priv)
+{
+  if (cf_priv->scaled_font)
+    {
+      cairo_scaled_font_destroy (cf_priv->scaled_font);
+      cf_priv->scaled_font = NULL;
+    }
+
+  if (cf_priv->glyph_extents_cache)
+    {
+      g_free (cf_priv->glyph_extents_cache);
+      cf_priv->glyph_extents_cache = NULL;
+    }
+
+  if (cf_priv->hbi)
+    {
+      g_object_unref (cf_priv->hbi->font);
+      g_slice_free (PangoCairoHexBoxInfo, cf_priv->hbi);
+    }
+}
+
+static void
+get_glyph_extents_missing (PangoCairoFont        *cfont,
+			   PangoGlyph             glyph,
+			   PangoRectangle        *ink_rect,
+			   PangoRectangle        *logical_rect)
+{
+  PangoCairoHexBoxInfo *hbi;  
+  gint rows, cols;
+
+  hbi = _pango_cairo_font_get_hex_box_info (cfont);
+  
+  rows = hbi->rows;
+  cols = ((glyph & ~PANGO_GLYPH_UNKNOWN_FLAG) > 0xffff ? 6 : 4) / rows;
+  
+  if (ink_rect)
+    {
+      ink_rect->x = PANGO_SCALE * hbi->pad_x;
+      ink_rect->y = PANGO_SCALE * (hbi->box_descent - hbi->box_height);
+      ink_rect->width = PANGO_SCALE * (3 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
+      ink_rect->height = PANGO_SCALE * hbi->box_height;
+    }
+  
+  if (logical_rect)
+    {
+      logical_rect->x = 0;
+      logical_rect->y = PANGO_SCALE * (hbi->box_descent - (hbi->box_height + hbi->pad_y));
+      logical_rect->width = PANGO_SCALE * (5 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
+      logical_rect->height = PANGO_SCALE * (hbi->box_height + 2 * hbi->pad_y);
+    }  
+}
+
+static void
+glyph_extents_cache_init (PangoCairoFontPrivate *cf_priv)
+{
+  cairo_scaled_font_t *scaled_font = cf_priv->scaled_font;
+
+  cairo_font_extents_t font_extents;
+  cairo_scaled_font_extents (scaled_font, &font_extents);
+
+  cf_priv->font_extents.x = 0;
+  cf_priv->font_extents.y = - font_extents.ascent * PANGO_SCALE;
+  cf_priv->font_extents.height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE;
+  cf_priv->font_extents.width = 0;
+
+  cf_priv->glyph_extents_cache = g_new0 (PangoCairoGlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES);
+  /* Make sure all cache entries are invalid initially */
+  cf_priv->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */
+}
+
+static void
+compute_glyph_extents (PangoCairoFontPrivate  *cf_priv,
+		       PangoGlyph              glyph,
+		       PangoCairoGlyphExtentsCacheEntry *entry)
+{
+  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 (cf_priv->scaled_font,
+				   &cairo_glyph, 1, &extents);
+  
+  entry->glyph = glyph;
+  entry->width = extents.x_advance * PANGO_SCALE;
+  entry->ink_rect.x = extents.x_bearing * PANGO_SCALE;
+  entry->ink_rect.y = extents.y_bearing * PANGO_SCALE;
+  entry->ink_rect.width = extents.width * PANGO_SCALE;
+  entry->ink_rect.height = extents.height * PANGO_SCALE;
+}
+     
+static PangoCairoGlyphExtentsCacheEntry *
+get_glyph_extents_cache_entry (PangoCairoFontPrivate *cf_priv,
+			       PangoGlyph             glyph)
+{
+  PangoCairoGlyphExtentsCacheEntry *entry;
+  guint idx;
+
+  idx = glyph & GLYPH_CACHE_MASK;
+  entry = cf_priv->glyph_extents_cache + idx;
+
+  if (entry->glyph != glyph)
+    compute_glyph_extents (cf_priv, glyph, entry);
+
+  return entry;
+}
+
+void
+_pango_cairo_font_with_private_get_glyph_extents (PangoCairoFont        *cfont,
+						  PangoCairoFontPrivate *cf_priv,
+						  PangoGlyph             glyph,
+						  PangoRectangle        *ink_rect,
+						  PangoRectangle        *logical_rect)
+{
+  PangoCairoGlyphExtentsCacheEntry *entry;
+
+  /* We need to initialize the cache here, since we use cf_priv->font_extents
+   */
+  if (G_UNLIKELY (!cf_priv->glyph_extents_cache))
+    glyph_extents_cache_init (cf_priv);
+
+  if (G_UNLIKELY (glyph & PANGO_GLYPH_UNKNOWN_FLAG)) 
+    {
+      get_glyph_extents_missing(cfont, glyph, ink_rect, logical_rect);
+      return;
+    }
+  else if (!glyph)
+    {
+      if (ink_rect)
+	*ink_rect = cf_priv->font_extents;
+      if (logical_rect)
+	*logical_rect = cf_priv->font_extents;
+      return;
+    }
+
+  entry = get_glyph_extents_cache_entry (cf_priv, glyph);
+
+  if (ink_rect)
+    *ink_rect = entry->ink_rect;
+  if (logical_rect)
+    {
+      *logical_rect = cf_priv->font_extents;
+      logical_rect->width = entry->width;
+    }
+}
+
+void
+_pango_cairo_font_install (PangoCairoFont *cfont,
 			   cairo_t        *cr)
 {
-  if (G_UNLIKELY (!PANGO_IS_CAIRO_FONT (font)))
+  PangoCairoFontPrivate *cf_priv;
+
+  if (G_UNLIKELY (!PANGO_IS_CAIRO_FONT (cfont)))
     {
       if (!_pango_cairo_warning_history.font_install)
         {
@@ -84,38 +266,23 @@ _pango_cairo_font_install (PangoCairoFon
       return;
     }
   
-  (* PANGO_CAIRO_FONT_GET_IFACE (font)->install) (font, cr);
-}
+  cf_priv = PANGO_CAIRO_FONT_PRIVATE (cfont);
 
-cairo_font_face_t *
-_pango_cairo_font_get_font_face (PangoCairoFont *font)
-{
-  g_return_val_if_fail (PANGO_IS_CAIRO_FONT (font), NULL);
-  
-  return (* PANGO_CAIRO_FONT_GET_IFACE (font)->get_font_face) (font);
+  cairo_set_scaled_font (cr, cf_priv->scaled_font);
 }
 
 cairo_scaled_font_t *
-_pango_cairo_font_get_scaled_font (PangoCairoFont *font)
+_pango_cairo_font_get_scaled_font (PangoCairoFont *cfont)
 {
-  g_return_val_if_fail (PANGO_IS_CAIRO_FONT (font), NULL);
-  
-  return (* PANGO_CAIRO_FONT_GET_IFACE (font)->get_scaled_font) (font);
-}
+  PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (cfont);
 
-static void
-_pango_cairo_hex_box_info_destroy (PangoCairoHexBoxInfo *hbi)
-{
-  if (hbi)
-    {
-      g_object_unref (hbi->font);
-      g_slice_free (PangoCairoHexBoxInfo, hbi);
-    }
-}  
+  return cf_priv->scaled_font;
+}
    
 PangoCairoHexBoxInfo *
-_pango_cairo_get_hex_box_info (PangoCairoFont *cfont)
+_pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont)
 {
+  PangoCairoFontPrivate *cf_priv;
   static const char hexdigits[] = "0123456789ABCDEF";
   char c[2] = {0, 0};
   PangoFont *mini_font;
@@ -137,9 +304,10 @@ _pango_cairo_get_hex_box_info (PangoCair
   if (!cfont)
     return NULL;
 
-  hbi = (PangoCairoHexBoxInfo *) g_object_get_data (G_OBJECT (cfont), "hex_box_info");
-  if (hbi)
-    return hbi;
+  cf_priv = PANGO_CAIRO_FONT_PRIVATE (cfont);
+
+  if (cf_priv->hbi)
+    return cf_priv->hbi;
 
   scaled_font = _pango_cairo_font_get_scaled_font (cfont);  
 
@@ -242,39 +410,7 @@ _pango_cairo_get_hex_box_info (PangoCair
   hbi->box_descent = HINT_Y (font_extents.descent -
 			     (font_extents.ascent + font_extents.descent - hbi->box_height) / 2);
 
-  g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", hbi, (GDestroyNotify)_pango_cairo_hex_box_info_destroy); 
+  cf_priv->hbi = hbi;
 
   return hbi;
 }
-
-void
-_pango_cairo_get_glyph_extents_missing (PangoCairoFont *cfont,
-				        PangoGlyph      glyph,
-				        PangoRectangle *ink_rect,
-				        PangoRectangle *logical_rect)
-{
-  PangoCairoHexBoxInfo *hbi;  
-  gint rows, cols;
-
-  hbi = _pango_cairo_get_hex_box_info (cfont);
-
-  rows = hbi->rows;
-  cols = ((glyph & ~PANGO_GLYPH_UNKNOWN_FLAG) > 0xffff ? 6 : 4) / rows;
-  
-  if (ink_rect)
-    {
-      ink_rect->x = PANGO_SCALE * hbi->pad_x;
-      ink_rect->y = PANGO_SCALE * (hbi->box_descent - hbi->box_height);
-      ink_rect->width = PANGO_SCALE * (3 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
-      ink_rect->height = PANGO_SCALE * hbi->box_height;
-    }
-  
-  if (logical_rect)
-    {
-      logical_rect->x = 0;
-      logical_rect->y = PANGO_SCALE * (hbi->box_descent - (hbi->box_height + hbi->pad_y));
-      logical_rect->width = PANGO_SCALE * (5 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
-      logical_rect->height = PANGO_SCALE * (hbi->box_height + 2 * hbi->pad_y);
-    }  
-}
-
Index: pango/pangocairo-private.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-private.h,v
retrieving revision 1.10
diff -u -p -r1.10 pangocairo-private.h
--- pango/pangocairo-private.h	2 Feb 2006 10:52:49 -0000	1.10
+++ pango/pangocairo-private.h	2 Feb 2006 12:02:02 -0000
@@ -43,6 +43,24 @@ struct _PangoCairoFontMapIface
 
 PangoRenderer *_pango_cairo_font_map_get_renderer (PangoCairoFontMap *cfontmap);
 
+
+
+typedef struct _PangoCairoHexBoxInfo PangoCairoHexBoxInfo;
+
+struct _PangoCairoHexBoxInfo
+{
+  PangoFont *font;
+  int rows;
+  double digit_width;
+  double digit_height;
+  double pad_x;
+  double pad_y;
+  double line_width;
+  double box_descent;
+  double box_height;
+};
+
+
 #define PANGO_CAIRO_FONT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT, PangoCairoFontIface))
 
 #define PANGO_TYPE_CAIRO_FONT       (pango_cairo_font_get_type ())
@@ -55,22 +73,19 @@ typedef struct _PangoCairoFontIface Pang
 struct _PangoCairoFontIface
 {
   GTypeInterface g_iface;
-
-  void (*install) (PangoCairoFont *font,
-		   cairo_t        *cr);
-
-  cairo_font_face_t *(*get_font_face) (PangoCairoFont *font);
-
-  cairo_scaled_font_t *(*get_scaled_font) (PangoCairoFont *font);
+  int cf_priv_offset;
 };
 
 GType pango_cairo_font_get_type (void);
 
-void _pango_cairo_font_install (PangoCairoFont *font,
+void _pango_cairo_font_install (PangoCairoFont *cfont,
 				cairo_t        *cr);
-cairo_font_face_t *_pango_cairo_font_get_font_face (PangoCairoFont *font);
+
 cairo_scaled_font_t *_pango_cairo_font_get_scaled_font (PangoCairoFont *font);
 
+PangoCairoHexBoxInfo *_pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont);
+
+
 #define PANGO_TYPE_CAIRO_RENDERER            (pango_cairo_renderer_get_type())
 #define PANGO_CAIRO_RENDERER(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRenderer))
 #define PANGO_IS_CAIRO_RENDERER(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_RENDERER))
@@ -82,27 +97,34 @@ GType pango_cairo_renderer_get_type    (
 const cairo_font_options_t *_pango_cairo_context_get_merged_font_options (PangoContext *context);
 
 
-typedef struct _PangoCairoHexBoxInfo PangoCairoHexBoxInfo;
 
-struct _PangoCairoHexBoxInfo
+
+typedef struct _PangoCairoGlyphExtentsCacheEntry PangoCairoGlyphExtentsCacheEntry;
+typedef struct _PangoCairoFontPrivate PangoCairoFontPrivate;
+
+struct _PangoCairoFontPrivate
 {
-	PangoFont *font;
-	int rows;
-	double digit_width;
-	double digit_height;
-	double pad_x;
-	double pad_y;
-	double line_width;
-	double box_descent;
-	double box_height;
+  cairo_scaled_font_t *scaled_font;
+  PangoCairoHexBoxInfo *hbi;
+  PangoRectangle font_extents;
+  PangoCairoGlyphExtentsCacheEntry *glyph_extents_cache;
 };
 
-PangoCairoHexBoxInfo *_pango_cairo_get_hex_box_info (PangoCairoFont *font);
 
-void _pango_cairo_get_glyph_extents_missing (PangoCairoFont *cfont,
-					     PangoGlyph      glyph,
-					     PangoRectangle *ink_rect,
-					     PangoRectangle *logical_rect);
+cairo_scaled_font_t *
+_pango_cairo_font_private_scaled_font_new (PangoCairoFontPrivate      *cf_priv,
+					   cairo_font_face_t          *font_face,
+					   const cairo_matrix_t       *font_matrix,
+					   const cairo_matrix_t       *ctm,
+					   const cairo_font_options_t *options);
+
+void _pango_cairo_font_private_finalize (PangoCairoFontPrivate *cf_priv);
+
+void _pango_cairo_font_with_private_get_glyph_extents (PangoCairoFont        *cfont,
+						       PangoCairoFontPrivate *cf_priv,
+						       PangoGlyph             glyph,
+						       PangoRectangle        *ink_rect,
+						       PangoRectangle        *logical_rect);
 
 typedef struct _PangoCairoWarningHistory PangoCairoWarningHistory;
 
Index: pango/pangocairo-win32font.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-win32font.c,v
retrieving revision 1.19
diff -u -p -r1.19 pangocairo-win32font.c
--- pango/pangocairo-win32font.c	29 Jan 2006 23:06:59 -0000	1.19
+++ pango/pangocairo-win32font.c	2 Feb 2006 12:02:02 -0000
@@ -21,16 +21,14 @@
 
 #include <config.h>
 
-#include <math.h>
-#include <stdlib.h>
 #include <string.h>
 
+#include <cairo-win32.h>
+
 #include "pango-fontmap.h"
-#include "pango-utils.h"
 #include "pangocairo-private.h"
 #include "pangocairo-win32.h"
-
-#include <cairo-win32.h>
+#include "pango-utils.h"
 
 #define PANGO_TYPE_CAIRO_WIN32_FONT           (pango_cairo_win32_font_get_type ())
 #define PANGO_CAIRO_WIN32_FONT(object)        (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_WIN32_FONT, PangoCairoWin32Font))
@@ -40,23 +38,14 @@
 
 typedef struct _PangoCairoWin32Font      PangoCairoWin32Font;
 typedef struct _PangoCairoWin32FontClass PangoCairoWin32FontClass;
-typedef struct _PangoCairoWin32GlyphInfo PangoCairoWin32GlyphInfo;
 
 struct _PangoCairoWin32Font
 {
   PangoWin32Font font;
+  PangoCairoFontPrivate cf_priv;
 
   int size;
-
-  cairo_font_face_t *font_face;
-  cairo_scaled_font_t *scaled_font;
-  
-  cairo_matrix_t font_matrix;
-  cairo_matrix_t ctm;
-  cairo_font_options_t *options;
-  
   GSList *metrics_by_lang;
-  GHashTable *glyph_info;
 };
 
 struct _PangoCairoWin32FontClass
@@ -64,98 +53,16 @@ struct _PangoCairoWin32FontClass
   PangoWin32FontClass  parent_class;
 };
 
-struct _PangoCairoWin32GlyphInfo
-{
-  PangoRectangle logical_rect;
-  PangoRectangle ink_rect;
-};
-
 GType pango_cairo_win32_font_get_type (void);
 
-/*******************************
- *       Utility functions     *
- *******************************/
-
-static cairo_font_face_t *
-pango_cairo_win32_font_get_font_face (PangoCairoFont *font)
-{
-  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
-  PangoWin32Font *win32font = PANGO_WIN32_FONT (cwfont);
-
-  if (cwfont->font_face == NULL)
-    {
-      LOGFONTW logfontw;
-
-      /* Count here on the fact that all the struct fields are the
-       * same for LOGFONTW and LOGFONTA except lfFaceName which is the
-       * last field
-       */
-      memcpy (&logfontw, &win32font->logfont, sizeof (LOGFONTA));
-      
-      if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
-				win32font->logfont.lfFaceName, -1,
-				logfontw.lfFaceName, G_N_ELEMENTS (logfontw.lfFaceName)))
-	logfontw.lfFaceName[0] = 0; /* Hopefully this will select some font */
-      
-      cwfont->font_face = cairo_win32_font_face_create_for_logfontw (&logfontw);
-
-      /* Failure of the above should only occur for out of memory,
-       * we can't proceed at that point
-       */
-      if (!cwfont->font_face)
-	g_error ("Unable to create Win32 cairo font face.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
-    }
-  
-  return cwfont->font_face;
-}
-
-static cairo_scaled_font_t *
-pango_cairo_win32_font_get_scaled_font (PangoCairoFont *font)
-{
-  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
-
-  if (!cwfont->scaled_font)
-    {
-      cairo_font_face_t *font_face;
-
-      font_face = pango_cairo_win32_font_get_font_face (font);
-      cwfont->scaled_font = cairo_scaled_font_create (font_face,
-						      &cwfont->font_matrix,
-						      &cwfont->ctm,
-						      cwfont->options);
-
-      /* Failure of the above should only occur for out of memory,
-       * we can't proceed at that point
-       */
-      if (!cwfont->scaled_font)
-	g_error ("Unable to create Win32 cairo scaled font.\nThis means out of memory or a cairo/fontconfig/FreeType bug");
-    }
-  
-  return cwfont->scaled_font;
-}
-
 /********************************
  *    Method implementations    *
  ********************************/
 
 static void
-pango_cairo_win32_font_install (PangoCairoFont *font,
-				cairo_t        *cr)
-{
-  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
-
-  cairo_set_font_face (cr,
-		       pango_cairo_win32_font_get_font_face (font));
-  cairo_set_font_matrix (cr, &cwfont->font_matrix);
-  cairo_set_font_options (cr, cwfont->options);
-}
-
-static void
 cairo_font_iface_init (PangoCairoFontIface *iface)
 {
-  iface->install = pango_cairo_win32_font_install;
-  iface->get_font_face = pango_cairo_win32_font_get_font_face;
-  iface->get_scaled_font = pango_cairo_win32_font_get_scaled_font;
+  iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoWin32Font, cf_priv);
 }
 
 G_DEFINE_TYPE_WITH_CODE (PangoCairoWin32Font, pango_cairo_win32_font, PANGO_TYPE_WIN32_FONT,
@@ -173,97 +80,27 @@ pango_cairo_win32_font_finalize (GObject
 {
   PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (object);
 
-  g_hash_table_destroy (cwfont->glyph_info);
+  _pango_cairo_font_private_finalize (&cwfont->cf_priv);
 
   g_slist_foreach (cwfont->metrics_by_lang, (GFunc)free_metrics_info, NULL);
   g_slist_free (cwfont->metrics_by_lang);  
 
-  if (cwfont->scaled_font)
-    cairo_scaled_font_destroy (cwfont->scaled_font);
-
-  if (cwfont->options)
-    cairo_font_options_destroy (cwfont->options);
-
   G_OBJECT_CLASS (pango_cairo_win32_font_parent_class)->finalize (object);
 }
 
 static void
-compute_glyph_extents (PangoFont        *font,
-		       PangoGlyph        glyph,
-		       PangoRectangle   *ink_rect,
-		       PangoRectangle   *logical_rect)
-{
-  PangoCairoFont *cfont = (PangoCairoFont *)font;
-  cairo_scaled_font_t *scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_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_glyph.index = glyph;
-      cairo_glyph.x = 0;
-      cairo_glyph.y = 0;
-      
-      cairo_scaled_font_glyph_extents (scaled_font,
-				       &cairo_glyph, 1, &extents);
-      
-      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;
-    }
-}
-
-static PangoCairoWin32GlyphInfo *
-pango_cairo_win32_font_get_glyph_info (PangoFont   *font,
-				       PangoGlyph   glyph)
-{
-  PangoCairoWin32Font *cwfont = (PangoCairoWin32Font *)font;
-  PangoCairoWin32GlyphInfo *info;
-
-  info = g_hash_table_lookup (cwfont->glyph_info, GUINT_TO_POINTER (glyph));
-  if (!info)
-    {
-      info = g_new0 (PangoCairoWin32GlyphInfo, 1);
-      
-      compute_glyph_extents (font, glyph,
-			     &info->ink_rect,
-			     &info->logical_rect);
-      
-      g_hash_table_insert (cwfont->glyph_info, GUINT_TO_POINTER (glyph), info);
-    }
-
-  return info;
-}
-     
-static void
 pango_cairo_win32_font_get_glyph_extents (PangoFont        *font,
 					  PangoGlyph        glyph,
 					  PangoRectangle   *ink_rect,
 					  PangoRectangle   *logical_rect)
 {
-  PangoCairoWin32GlyphInfo *info;
+  PangoCairoWin32Font *cwfont = (PangoCairoWin32Font *)font;
 
-  info = pango_cairo_win32_font_get_glyph_info (font, glyph);
-  
-  if (ink_rect)
-    *ink_rect = info->ink_rect;
-  if (logical_rect)
-    *logical_rect = info->logical_rect;
+  _pango_cairo_font_with_private_get_glyph_extents ((PangoCairoFont *)font,
+						    &cwfont->cf_priv,
+						    glyph,
+						    ink_rect,
+						    logical_rect);
 }
 
 static PangoFontMetrics *
@@ -277,16 +114,12 @@ create_metrics_for_context (PangoFont   
   PangoRectangle extents;
   PangoLanguage *language = pango_context_get_language (context);
   const char *sample_str = pango_language_get_sample_string (language);
-  cairo_scaled_font_t *scaled_font;
   cairo_font_extents_t font_extents;
   double height;
   
   metrics = pango_font_metrics_new ();
   
-  scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (cwfont));
-
-  cairo_scaled_font_extents (scaled_font, &font_extents);
-  cairo_win32_scaled_font_done_font (scaled_font);
+  cairo_scaled_font_extents (cwfont->cf_priv->scaled_font, &font_extents);
   
   metrics->ascent = font_extents.ascent * PANGO_SCALE;
   metrics->descent = font_extents.descent * PANGO_SCALE;
@@ -371,26 +204,26 @@ static gboolean
 pango_cairo_win32_font_select_font (PangoFont *font,
 				    HDC        hdc)
 {
-  cairo_scaled_font_t *scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (font));
+  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
   
-  return cairo_win32_scaled_font_select_font (scaled_font, hdc) == CAIRO_STATUS_SUCCESS;
+  return cairo_win32_scaled_font_select_font (cwfont->cf_priv->scaled_font, hdc) == CAIRO_STATUS_SUCCESS;
 }
 
 static void
 pango_cairo_win32_font_done_font (PangoFont *font)
 {
-  cairo_scaled_font_t *scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (font));
+  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
   
-  cairo_win32_scaled_font_done_font (scaled_font);
+  cairo_win32_scaled_font_done_font (cwfont->cf_priv->scaled_font);
 }
 
 static double
 pango_cairo_win32_font_get_metrics_factor (PangoFont *font)
 {
   PangoWin32Font *win32font = PANGO_WIN32_FONT (font);
-  cairo_scaled_font_t *scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (font));
+  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
 
-  return cairo_win32_scaled_font_get_metrics_factor (scaled_font) * win32font->size;
+  return cairo_win32_scaled_font_get_metrics_factor (cwfont->cf_priv->scaled_font) * win32font->size;
 }
 
 static void
@@ -413,10 +246,6 @@ pango_cairo_win32_font_class_init (Pango
 static void
 pango_cairo_win32_font_init (PangoCairoWin32Font *cwfont)
 {
-  cwfont->glyph_info = g_hash_table_new_full (g_direct_hash,
-					      NULL,
-					      NULL,
-					      (GDestroyNotify)g_free);
 }
 
 /********************
@@ -429,33 +258,41 @@ _pango_cairo_win32_font_new (PangoCairoW
 			     PangoWin32Face             *face,
 			     const PangoFontDescription *desc)
 {
-  PangoCairoWin32Font *cwfont;
+  PangoCairoWin32Font *cwfont = NULL;
   PangoWin32Font *win32font;
   const PangoMatrix *pango_ctm;
   double size;
-  double dpi;
 #define USE_FACE_CACHED_FONTS
 #ifdef USE_FACE_CACHED_FONTS
   PangoWin32FontMap *win32fontmap;
   GSList *tmp_list;
 #endif
+  LOGFONTW logfontw;
+  cairo_scaled_font_t *scaled_font;
+  cairo_font_face_t *font_face;
+  cairo_matrix_t font_matrix, ctm;
+  cairo_font_options_t *font_options;
 
   g_return_val_if_fail (PANGO_IS_CAIRO_WIN32_FONT_MAP (cwfontmap), NULL);
 
   size = (double) pango_font_description_get_size (desc) / PANGO_SCALE;
 
-  if (context)
+  if (!pango_font_description_get_size_is_absolute (desc))
     {
-      dpi = pango_cairo_context_get_resolution (context);
-      
-      if (dpi <= 0)
+      double dpi;
+
+      if (context)
+	{
+	  dpi = pango_cairo_context_get_resolution (context);
+	  
+	  if (dpi <= 0)
+	    dpi = cwfontmap->dpi;
+	}
+      else
 	dpi = cwfontmap->dpi;
-    }
-  else
-    dpi = cwfontmap->dpi;
   
-  if (!pango_font_description_get_size_is_absolute (desc))
-    size *= dpi / 72.;
+      size *= dpi / 72.;
+    }
 
 #ifdef USE_FACE_CACHED_FONTS
   win32fontmap = PANGO_WIN32_FONT_MAP (cwfontmap);
@@ -492,26 +329,57 @@ _pango_cairo_win32_font_new (PangoCairoW
    */
   win32font->size = size * PANGO_SCALE;
 
-  cairo_matrix_init_scale (&cwfont->font_matrix,
-			   size, size);
+  pango_win32_make_matching_logfont (win32font->fontmap,
+				     &face->logfont,
+				     win32font->size,
+				     &win32font->logfont);
+
+  /* Count here on the fact that all the struct fields are the
+   * same for LOGFONTW and LOGFONTA except lfFaceName which is the
+   * last field
+   */
+  memcpy (&logfontw, &win32font->logfont, sizeof (LOGFONTA));
+  
+  if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+			    win32font->logfont.lfFaceName, -1,
+			    logfontw.lfFaceName, G_N_ELEMENTS (logfontw.lfFaceName)))
+    logfontw.lfFaceName[0] = 0; /* Hopefully this will select some font */
+  
+  font_face = cairo_win32_font_face_create_for_logfontw (&logfontw);
+  if (!font_face)
+    goto failed;
+
+  cairo_matrix_init_scale (&font_matrix, size, size);
 
   pango_ctm = pango_context_get_matrix (context);
   if (pango_ctm)
-    cairo_matrix_init (&cwfont->ctm,
+    cairo_matrix_init (&ctm,
 		       pango_ctm->xx,
 		       pango_ctm->yx,
 		       pango_ctm->xy,
 		       pango_ctm->yy,
 		       0., 0.);
   else
-    cairo_matrix_init_identity (&cwfont->ctm);
+    cairo_matrix_init_identity (&ctm);
 
-  pango_win32_make_matching_logfont (win32font->fontmap,
-				     &face->logfont,
-				     win32font->size,
-				     &win32font->logfont);
-
-  cwfont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
+  font_options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
   
+  scaled_font = _pango_cairo_font_private_scaled_font_new (&cwfont->cf_priv,
+							   font_face,
+							   &font_matrix,
+							   &ctm,
+							   font_options);
+
+  cairo_font_face_destroy (font_face);
+  cairo_font_options_destroy (font_options);
+
+  if (!scaled_font)
+    goto failed;
+
   return PANGO_FONT (cwfont);
+
+failed:
+  if (cwfont)
+    g_object_unref (cwfont);
+  return NULL;
 }

