DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (31ec81b5d7bb)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
# HG changeset patch
# User Robert O'Callahan <robert@ocallahan.org>
# Date 1357107533 -46800
# Node ID ed54dfdd2facb11a4d4158138b460a31de45e9f7
# Parent ab6457cc16ec14ea07386dcfc57cad6b8a9ac55d
Bug 717178. Part 3 alternative: don't put Win32 cairo_font_face_ts into the font-face cache if they were created with an explicit HFONT. r=jrmuizel

diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c
--- a/gfx/cairo/cairo/src/cairo-win32-font.c
+++ b/gfx/cairo/cairo/src/cairo-win32-font.c
@@ -1941,16 +1942,21 @@ const cairo_font_face_backend_t _cairo_w
  * The primary purpose of this mapping is to provide unique
  * #cairo_font_face_t values so that our cache and mapping from
  * #cairo_font_face_t => #cairo_scaled_font_t works. Once the
  * corresponding #cairo_font_face_t objects fall out of downstream
  * caches, we don't need them in this hash table anymore.
  *
  * Modifications to this hash table are protected by
  * _cairo_win32_font_face_mutex.
+ *
+ * Only #cairo_font_face_t values with null 'hfont' (no
+ * HFONT preallocated by caller) are stored in this table. We rely
+ * on callers to manage the lifetime of the HFONT, and they can't
+ * do that if we share #cairo_font_face_t values with other callers.
  */
 
 static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
 
 static int
 _cairo_win32_font_face_keys_equal (const void *key_a,
 				   const void *key_b);
 
@@ -2036,22 +2042,24 @@ static int
 }
 
 static void
 _cairo_win32_font_face_destroy (void *abstract_face)
 {
     cairo_hash_table_t *hash_table;
     cairo_win32_font_face_t *font_face = abstract_face;
 
-    hash_table = _cairo_win32_font_face_hash_table_lock ();
-    if (unlikely (hash_table == NULL)) {
-        return;
+    if (!font_face->hfont) {
+        hash_table = _cairo_win32_font_face_hash_table_lock ();
+        if (unlikely (hash_table == NULL)) {
+            return;
+        }
+        _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+        _cairo_win32_font_face_hash_table_unlock ();
     }
-    _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
-    _cairo_win32_font_face_hash_table_unlock ();
 }
 
 /**
  * cairo_win32_font_face_create_for_logfontw_hfont:
  * @logfont: A #LOGFONTW structure specifying the font to use.
  *   If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
  *   fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
  *   lfEscapement must be zero.
@@ -2070,55 +2078,63 @@ static void
  **/
 cairo_font_face_t *
 cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
 {
     cairo_win32_font_face_t *font_face, key;
     cairo_hash_table_t *hash_table;
     cairo_status_t status;
 
-    hash_table = _cairo_win32_font_face_hash_table_lock ();
-    if (unlikely (hash_table == NULL)) {
-        _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_font_face_t *)&_cairo_font_face_nil;
-    }
+    if (!font) {
+        hash_table = _cairo_win32_font_face_hash_table_lock ();
+        if (unlikely (hash_table == NULL)) {
+            _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	    return (cairo_font_face_t *)&_cairo_font_face_nil;
+        }
 
-    _cairo_win32_font_face_init_key (&key, logfont, font);
+        _cairo_win32_font_face_init_key (&key, logfont, font);
 
-    /* Return existing unscaled font if it exists in the hash table. */
-    font_face = _cairo_hash_table_lookup (hash_table,
-					 &key.base.hash_entry);
-    if (font_face != NULL) {
-	cairo_font_face_reference (&font_face->base);
-	goto DONE;
+        /* Return existing unscaled font if it exists in the hash table. */
+        font_face = _cairo_hash_table_lookup (hash_table,
+                                              &key.base.hash_entry);
+        if (font_face != NULL) {
+	    cairo_font_face_reference (&font_face->base);
+	    goto DONE;
+        }
     }
 
     /* Otherwise create it and insert into hash table. */
     font_face = malloc (sizeof (cairo_win32_font_face_t));
     if (!font_face) {
         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL;
     }
 
     _cairo_win32_font_face_init_key (font_face, logfont, font);
     _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
+    assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
 
-    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 FAIL;
+    if (!font) {
+        status = _cairo_hash_table_insert (hash_table,
+                                           &font_face->base.hash_entry);
+        if (unlikely (status))
+	    goto FAIL;
+    }
 
 DONE:
-    _cairo_win32_font_face_hash_table_unlock ();
+    if (!font) {
+        _cairo_win32_font_face_hash_table_unlock ();
+    }
 
     return &font_face->base;
 
 FAIL:
-    _cairo_win32_font_face_hash_table_unlock ();
+    if (!font) {
+        _cairo_win32_font_face_hash_table_unlock ();
+    }
 
     return (cairo_font_face_t *)&_cairo_font_face_nil;
 }
 
 /**
  * cairo_win32_font_face_create_for_logfontw:
  * @logfont: A #LOGFONTW structure specifying the font to use.
  *   The lfHeight, lfWidth, lfOrientation and lfEscapement