[cairo-commit] src/cairo-ft-font.c src/cairo-scaled-font.c src/cairo-scaled-font-private.h src/cairo-toy-font-face.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Feb 24 12:01:00 PST 2009


 src/cairo-ft-font.c             |    2 +-
 src/cairo-scaled-font-private.h |    2 ++
 src/cairo-scaled-font.c         |   17 +++++++++++++----
 src/cairo-toy-font-face.c       |    1 +
 4 files changed, 17 insertions(+), 5 deletions(-)

New commits:
commit 6eb0a9d97ff7eaaee69ca10e4081cb950a543ce3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 15 21:27:29 2009 +0000

    [scaled-font] Hold reference to original font face
    
    As noted by Carl during his LCA talk, caching of toy fonts was broken
    because we create the scaled font using the implementation font face and
    lose the reference to the containing font face that is cached by the toy
    font face create routines. So the toy fonts were not being preserved for
    the duration of the holdover scaled fonts and we recreated a new font
    face, new scaled font and new glyph caches every time we needed a font.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 4295d25..493a1e2 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -444,6 +444,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
     if (unlikely (status))
 	goto UNWIND_UNSCALED_MALLOC;
 
+    assert (unscaled->base.hash_entry.hash == key.base.hash_entry.hash);
     status = _cairo_hash_table_insert (font_map->hash_table,
 				       &unscaled->base.hash_entry);
     if (unlikely (status))
@@ -484,7 +485,6 @@ _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
 
 DONE:
     return _cairo_ft_unscaled_font_create_internal (font_face != NULL, filename, id, font_face);
-
 }
 
 static cairo_ft_unscaled_font_t *
diff --git a/src/cairo-scaled-font-private.h b/src/cairo-scaled-font-private.h
index 13d89eb..89820c8 100644
--- a/src/cairo-scaled-font-private.h
+++ b/src/cairo-scaled-font-private.h
@@ -84,6 +84,8 @@ struct _cairo_scaled_font {
     cairo_reference_count_t ref_count;
     cairo_user_data_array_t user_data;
 
+    cairo_font_face_t *original_font_face; /* may be NULL */
+
     /* hash key members */
     cairo_font_face_t *font_face; /* may be NULL */
     cairo_matrix_t font_matrix;	  /* font space => user space */
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 7096a01..36e3d9c 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -206,6 +206,7 @@ static const cairo_scaled_font_t _cairo_scaled_font_nil = {
     CAIRO_STATUS_NO_MEMORY,	/* status */
     CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */
     { 0, 0, 0, NULL },		/* user_data */
+    NULL,			/* original_font_face */
     NULL,			/* font_face */
     { 1., 0., 0., 1., 0, 0},	/* font_matrix */
     { 1., 0., 0., 1., 0, 0},	/* ctm */
@@ -706,14 +707,17 @@ _cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_
     const cairo_scaled_font_t *key_a = abstract_key_a;
     const cairo_scaled_font_t *key_b = abstract_key_b;
 
-    return (key_a->font_face == key_b->font_face &&
+    if (key_a->hash_entry.hash != key_b->hash_entry.hash)
+	return FALSE;
+
+    return key_a->font_face == key_b->font_face &&
 	    memcmp ((unsigned char *)(&key_a->font_matrix.xx),
 		    (unsigned char *)(&key_b->font_matrix.xx),
 		    sizeof(cairo_matrix_t)) == 0 &&
 	    memcmp ((unsigned char *)(&key_a->ctm.xx),
 		    (unsigned char *)(&key_b->ctm.xx),
 		    sizeof(cairo_matrix_t)) == 0 &&
-	    cairo_font_options_equal (&key_a->options, &key_b->options));
+	    cairo_font_options_equal (&key_a->options, &key_b->options);
 }
 
 /*
@@ -863,8 +867,8 @@ _cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font)
 
     _cairo_scaled_glyph_page_cache_remove_scaled_font (scaled_font);
 
-    if (scaled_font->font_face != NULL)
-	cairo_font_face_destroy (scaled_font->font_face);
+    cairo_font_face_destroy (scaled_font->font_face);
+    cairo_font_face_destroy (scaled_font->original_font_face);
 
     CAIRO_MUTEX_FINI (scaled_font->mutex);
 
@@ -916,6 +920,7 @@ cairo_scaled_font_create (cairo_font_face_t          *font_face,
 {
     cairo_status_t status;
     cairo_scaled_font_map_t *font_map;
+    cairo_font_face_t *original_font_face = font_face;
     cairo_scaled_font_t key, *old = NULL, *scaled_font = NULL;
     double det;
 
@@ -1051,6 +1056,10 @@ cairo_scaled_font_create (cairo_font_face_t          *font_face,
 	return scaled_font;
     }
 
+    scaled_font->original_font_face =
+	cairo_font_face_reference (original_font_face);
+
+    assert (scaled_font->hash_entry.hash == key.hash_entry.hash);
     status = _cairo_hash_table_insert (font_map->hash_table,
 				       &scaled_font->hash_entry);
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
diff --git a/src/cairo-toy-font-face.c b/src/cairo-toy-font-face.c
index 05ad495..b2d41af 100644
--- a/src/cairo-toy-font-face.c
+++ b/src/cairo-toy-font-face.c
@@ -325,6 +325,7 @@ cairo_toy_font_face_create (const char          *family,
     if (unlikely (status))
 	goto UNWIND_FONT_FACE_MALLOC;
 
+    assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
     status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
     if (unlikely (status))
 	goto UNWIND_FONT_FACE_INIT;


More information about the cairo-commit mailing list