[cairo-commit] 4 commits - src/cairo-ft-font.c src/cairo-ft-private.h src/cairo-hash.c src/cairo-scaled-font.c src/cairo-scaled-font-subsets.c src/cairo-xcb-connection.c src/cairo-xcb-screen.c

Andrea Canciani ranma42 at kemper.freedesktop.org
Mon Aug 1 10:23:33 PDT 2011


 src/cairo-ft-font.c             |   28 ++++++++++------------
 src/cairo-ft-private.h          |   12 ---------
 src/cairo-hash.c                |   49 ++++++++++++++++++++++++++--------------
 src/cairo-scaled-font-subsets.c |   11 --------
 src/cairo-scaled-font.c         |   14 -----------
 src/cairo-xcb-connection.c      |   11 +-------
 src/cairo-xcb-screen.c          |    6 ----
 7 files changed, 50 insertions(+), 81 deletions(-)

New commits:
commit 1e02ffd9a99f0f4917a4bb7c0755cc81f88fc80f
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Mon Aug 1 13:56:10 2011 +0200

    scaled-font: Make unscaled font utility functions static
    
    They are only used within cairo-scaled-font.c

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index aee305b..7f5f6d0 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -226,6 +226,16 @@ typedef struct _cairo_ft_unscaled_font_map {
 static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
 
 
+static FT_Face
+_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled);
+
+static void
+_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
+
+static cairo_bool_t
+_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font);
+
+
 static void
 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
 				  cairo_ft_unscaled_font_t *unscaled)
@@ -621,7 +631,7 @@ _has_unlocked_face (const void *entry)
  * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
  * set the scale on the face, but just returns it at the last scale.
  */
-cairo_warn FT_Face
+static cairo_warn FT_Face
 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
 {
     cairo_ft_unscaled_font_map_t *font_map;
@@ -676,7 +686,7 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
 
 /* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
  */
-void
+static void
 _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
 {
     assert (unscaled->lock_count > 0);
@@ -3350,7 +3360,7 @@ cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
     _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
 }
 
-cairo_bool_t
+static cairo_bool_t
 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
 {
     cairo_ft_scaled_font_t *ft_scaled_font;
diff --git a/src/cairo-ft-private.h b/src/cairo-ft-private.h
index db1081d..3921518 100644
--- a/src/cairo-ft-private.h
+++ b/src/cairo-ft-private.h
@@ -52,15 +52,6 @@ _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font);
 /* These functions are needed by the PDF backend, which needs to keep track of the
  * the different fonts-on-disk used by a document, so it can embed them
  */
-cairo_private FT_Face
-_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled);
-
-cairo_private void
-_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled);
-
-cairo_private cairo_bool_t
-_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font);
-
 cairo_private unsigned int
 _cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t *scaled_font);
 
commit daca1d999f487fd089421591061f9bf36d47f11f
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Mon Aug 1 10:47:01 2011 +0200

    scaled-font: Remove _cairo_ft_scaled_font_get_unscaled_font()
    
    It is unused since 068df654daa74cdf516657af432002471a03c161.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index c490d69..aee305b 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -3350,18 +3350,6 @@ cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
     _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
 }
 
-/* We expose our unscaled font implementation internally for the the
- * PDF backend, which needs to keep track of the the different
- * fonts-on-disk used by a document, so it can embed them.
- */
-cairo_unscaled_font_t *
-_cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *abstract_font)
-{
-    cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
-
-    return &scaled_font->unscaled->base;
-}
-
 cairo_bool_t
 _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
 {
diff --git a/src/cairo-ft-private.h b/src/cairo-ft-private.h
index ff6ad4e..db1081d 100644
--- a/src/cairo-ft-private.h
+++ b/src/cairo-ft-private.h
@@ -52,9 +52,6 @@ _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font);
 /* These functions are needed by the PDF backend, which needs to keep track of the
  * the different fonts-on-disk used by a document, so it can embed them
  */
-cairo_private cairo_unscaled_font_t *
-_cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *scaled_font);
-
 cairo_private FT_Face
 _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled);
 
commit 400d055f3cd2eecd2cc4b91a40eac4146ec61932
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Mon Aug 1 19:01:16 2011 +0200

    hash: Compare hash values before calling keys_equal
    
    If the hash value is different, the keys cannot be equal. Testing this
    beforehand can avoid a few function calls and shares this optimization
    across all cairo-hash uses.

diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index 7cab89d..98f48a8 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -128,6 +128,25 @@ struct _cairo_hash_table {
 };
 
 /**
+ * _cairo_hash_table_uid_keys_equal:
+ * @key_a: the first key to be compared
+ * @key_b: the second key to be compared
+ *
+ * Provides a cairo_hash_keys_equal_func_t which always returns
+ * %TRUE. This is useful to create hash tables using keys whose hash
+ * completely describes the key, because in this special case
+ * comparing the hashes is sufficient to guarantee that the keys are
+ * equal.
+ *
+ * Return value: %TRUE.
+ **/
+static cairo_bool_t
+_cairo_hash_table_uid_keys_equal (const void *key_a, const void *key_b)
+{
+    return TRUE;
+}
+
+/**
  * _cairo_hash_table_create:
  * @keys_equal: a function to return %TRUE if two keys are equal
  *
@@ -139,6 +158,9 @@ struct _cairo_hash_table {
  * _cairo_hash_table_remove), and other times both a key and a value
  * will be necessary, (as in _cairo_hash_table_insert).
  *
+ * If @keys_equal is %NULL, two keys will be considered equal if and
+ * only if their hashes are equal.
+ *
  * See #cairo_hash_entry_t for more details.
  *
  * Return value: the new hash table or %NULL if out of memory.
@@ -154,7 +176,10 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
 	return NULL;
     }
 
-    hash_table->keys_equal = keys_equal;
+    if (keys_equal == NULL)
+	hash_table->keys_equal = _cairo_hash_table_uid_keys_equal;
+    else
+	hash_table->keys_equal = keys_equal;
 
     hash_table->arrangement = &hash_table_arrangements[0];
 
@@ -316,7 +341,7 @@ _cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
 
     entry = hash_table->entries[idx];
     if (ENTRY_IS_LIVE (entry)) {
-	if (hash_table->keys_equal (key, entry))
+	if (entry->hash == key->hash && hash_table->keys_equal (key, entry))
 	    return entry;
     } else if (ENTRY_IS_FREE (entry))
 	return NULL;
@@ -330,7 +355,7 @@ _cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
 
 	entry = hash_table->entries[idx];
 	if (ENTRY_IS_LIVE (entry)) {
-	    if (hash_table->keys_equal (key, entry))
+	    if (entry->hash == key->hash && hash_table->keys_equal (key, entry))
 		return entry;
 	} else if (ENTRY_IS_FREE (entry))
 	    return NULL;
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index d3d9d65..0e9880a 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -152,15 +152,6 @@ _cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t  *sub_font_glyph,
     sub_font_glyph->base.hash = scaled_font_glyph_index;
 }
 
-static cairo_bool_t
-_cairo_sub_font_glyphs_equal (const void *key_a, const void *key_b)
-{
-    const cairo_sub_font_glyph_t *sub_font_glyph_a = key_a;
-    const cairo_sub_font_glyph_t *sub_font_glyph_b = key_b;
-
-    return sub_font_glyph_a->base.hash == sub_font_glyph_b->base.hash;
-}
-
 static cairo_sub_font_glyph_t *
 _cairo_sub_font_glyph_create (unsigned long	scaled_font_glyph_index,
 			      unsigned int	subset_id,
@@ -314,7 +305,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t	*parent,
     sub_font->num_glyphs_in_latin_subset = 0;
     sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
 
-    sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal);
+    sub_font->sub_font_glyphs = _cairo_hash_table_create (NULL);
     if (unlikely (sub_font->sub_font_glyphs == NULL)) {
 	free (sub_font);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 6dc8ed3..cb59bce 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -638,9 +638,6 @@ _cairo_scaled_font_keys_equal (const void *abstract_key_a,
     const cairo_scaled_font_t *key_a = abstract_key_a;
     const cairo_scaled_font_t *key_b = abstract_key_b;
 
-    if (key_a->hash_entry.hash != key_b->hash_entry.hash)
-	return FALSE;
-
     return key_a->original_font_face == key_b->original_font_face &&
 	    memcmp ((unsigned char *)(&key_a->font_matrix.xx),
 		    (unsigned char *)(&key_b->font_matrix.xx),
@@ -668,15 +665,6 @@ _cairo_scaled_font_matches (const cairo_scaled_font_t *scaled_font,
 	    cairo_font_options_equal (&scaled_font->options, options);
 }
 
-static cairo_bool_t
-_cairo_scaled_glyphs_equal (const void *abstract_a, const void *abstract_b)
-{
-    const cairo_scaled_glyph_t *a = abstract_a;
-    const cairo_scaled_glyph_t *b = abstract_b;
-
-    return a->hash_entry.hash == b->hash_entry.hash;
-}
-
 /*
  * Basic #cairo_scaled_font_t object management
  */
@@ -725,7 +713,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t               *scaled_font,
 	    return status;
     }
 
-    scaled_font->glyphs = _cairo_hash_table_create (_cairo_scaled_glyphs_equal);
+    scaled_font->glyphs = _cairo_hash_table_create (NULL);
     if (unlikely (scaled_font->glyphs == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
diff --git a/src/cairo-xcb-connection.c b/src/cairo-xcb-connection.c
index 3cba883..b252648 100644
--- a/src/cairo-xcb-connection.c
+++ b/src/cairo-xcb-connection.c
@@ -500,13 +500,6 @@ _device_flush (void *device)
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_bool_t
-_xrender_formats_equal (const void *A, const void *B)
-{
-    const cairo_xcb_xrender_format_t *a = A, *b = B;
-    return a->key.hash == b->key.hash;
-}
-
 static void
 _pluck_xrender_format (void *entry,
 		       void *closure)
@@ -633,7 +626,7 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
     cairo_list_init (&connection->fonts);
     cairo_list_init (&connection->screens);
     cairo_list_init (&connection->link);
-    connection->xrender_formats = _cairo_hash_table_create (_xrender_formats_equal);
+    connection->xrender_formats = _cairo_hash_table_create (NULL);
     if (connection->xrender_formats == NULL) {
 	CAIRO_MUTEX_FINI (connection->device.mutex);
 	free (connection);
@@ -641,7 +634,7 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
 	goto unlock;
     }
 
-    connection->visual_to_xrender_format = _cairo_hash_table_create (_xrender_formats_equal);
+    connection->visual_to_xrender_format = _cairo_hash_table_create (NULL);
     if (connection->visual_to_xrender_format == NULL) {
 	_cairo_hash_table_destroy (connection->xrender_formats);
 	CAIRO_MUTEX_FINI (connection->device.mutex);
diff --git a/src/cairo-xcb-screen.c b/src/cairo-xcb-screen.c
index 7b5493f..18e75a5 100644
--- a/src/cairo-xcb-screen.c
+++ b/src/cairo-xcb-screen.c
@@ -97,9 +97,6 @@ _linear_pattern_cache_entry_equal (const void *A, const void *B)
 {
     const struct pattern_cache_entry *a = A, *b = B;
 
-    if (a->key.hash != b->key.hash)
-	return FALSE;
-
     return _cairo_linear_pattern_equal (&a->pattern.gradient.linear,
 					&b->pattern.gradient.linear);
 }
@@ -109,9 +106,6 @@ _radial_pattern_cache_entry_equal (const void *A, const void *B)
 {
     const struct pattern_cache_entry *a = A, *b = B;
 
-    if (a->key.hash != b->key.hash)
-	return FALSE;
-
     return _cairo_radial_pattern_equal (&a->pattern.gradient.radial,
 					&b->pattern.gradient.radial);
 }
commit 02665975d3ef0204bc512de1be55f898637f2d21
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Mon Aug 1 18:18:31 2011 +0200

    hash: Improve double hashing
    
    Instead of artificially introducing collisions in the step value by
    replacing 0 with 1 (which causes the value 1 to have twice the
    frequency of any other value), the step value can simply be computed
    as an uniformly distributed value in the range [1, rehash], extremes
    included.
    
    This is safe because any step value smaller than the hash modulus is
    co-prime with it, hence induces an orbit which includes every integer
    in [0, table_size - 1].

diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index 81a48a2..7cab89d 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -72,7 +72,7 @@
  * prime chosen to be a little more than double the high water mark for a
  * given arrangement, so the tables should remain < 50% full. The table
  * size makes for the "first" hash modulus; a second prime (2 less than the
- * first prime) serves as the "second" hash modulus, which is co-prime and
+ * first prime) serves as the "second" hash modulus, which is smaller and
  * thus guarantees a complete permutation of table indices.
  *
  * This structure, and accompanying table, is borrowed/modified from the
@@ -218,9 +218,7 @@ _cairo_hash_table_lookup_unique_key (cairo_hash_table_t *hash_table,
 	return entry;
 
     i = 1;
-    step = key->hash % hash_table->arrangement->rehash;
-    if (step == 0)
-	step = 1;
+    step = 1 + key->hash % hash_table->arrangement->rehash;
     do {
 	idx += step;
 	if (idx >= table_size)
@@ -324,9 +322,7 @@ _cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
 	return NULL;
 
     i = 1;
-    step = key->hash % hash_table->arrangement->rehash;
-    if (step == 0)
-	step = 1;
+    step = 1 + key->hash % hash_table->arrangement->rehash;
     do {
 	idx += step;
 	if (idx >= table_size)
@@ -381,9 +377,7 @@ _cairo_hash_table_random_entry (cairo_hash_table_t	   *hash_table,
 	return entry;
 
     i = 1;
-    step = hash % hash_table->arrangement->rehash;
-    if (step == 0)
-	step = 1;
+    step = 1 + hash % hash_table->arrangement->rehash;
     do {
 	idx += step;
 	if (idx >= table_size)
@@ -455,9 +449,7 @@ _cairo_hash_table_lookup_exact_key (cairo_hash_table_t *hash_table,
 	return entry;
 
     i = 1;
-    step = key->hash % hash_table->arrangement->rehash;
-    if (step == 0)
-	step = 1;
+    step = 1 + key->hash % hash_table->arrangement->rehash;
     do {
 	idx += step;
 	if (idx >= table_size)


More information about the cairo-commit mailing list