1# HG changeset patch 2# User Robert O'Callahan <robert@ocallahan.org> 3# Date 1357107533 -46800 4# Node ID ed54dfdd2facb11a4d4158138b460a31de45e9f7 5# Parent ab6457cc16ec14ea07386dcfc57cad6b8a9ac55d 6Bug 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 7 8diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c 9--- a/gfx/cairo/cairo/src/cairo-win32-font.c 10+++ b/gfx/cairo/cairo/src/cairo-win32-font.c 11@@ -1941,16 +1942,21 @@ const cairo_font_face_backend_t _cairo_w 12 * The primary purpose of this mapping is to provide unique 13 * #cairo_font_face_t values so that our cache and mapping from 14 * #cairo_font_face_t => #cairo_scaled_font_t works. Once the 15 * corresponding #cairo_font_face_t objects fall out of downstream 16 * caches, we don't need them in this hash table anymore. 17 * 18 * Modifications to this hash table are protected by 19 * _cairo_win32_font_face_mutex. 20+ * 21+ * Only #cairo_font_face_t values with null 'hfont' (no 22+ * HFONT preallocated by caller) are stored in this table. We rely 23+ * on callers to manage the lifetime of the HFONT, and they can't 24+ * do that if we share #cairo_font_face_t values with other callers. 25 */ 26 27 static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL; 28 29 static int 30 _cairo_win32_font_face_keys_equal (const void *key_a, 31 const void *key_b); 32 33@@ -2036,22 +2042,24 @@ static int 34 } 35 36 static void 37 _cairo_win32_font_face_destroy (void *abstract_face) 38 { 39 cairo_hash_table_t *hash_table; 40 cairo_win32_font_face_t *font_face = abstract_face; 41 42- hash_table = _cairo_win32_font_face_hash_table_lock (); 43- if (unlikely (hash_table == NULL)) { 44- return; 45+ if (!font_face->hfont) { 46+ hash_table = _cairo_win32_font_face_hash_table_lock (); 47+ if (unlikely (hash_table == NULL)) { 48+ return; 49+ } 50+ _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); 51+ _cairo_win32_font_face_hash_table_unlock (); 52 } 53- _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); 54- _cairo_win32_font_face_hash_table_unlock (); 55 } 56 57 /** 58 * cairo_win32_font_face_create_for_logfontw_hfont: 59 * @logfont: A #LOGFONTW structure specifying the font to use. 60 * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement 61 * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and 62 * lfEscapement must be zero. 63@@ -2070,55 +2078,63 @@ static void 64 **/ 65 cairo_font_face_t * 66 cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font) 67 { 68 cairo_win32_font_face_t *font_face, key; 69 cairo_hash_table_t *hash_table; 70 cairo_status_t status; 71 72- hash_table = _cairo_win32_font_face_hash_table_lock (); 73- if (unlikely (hash_table == NULL)) { 74- _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 75- return (cairo_font_face_t *)&_cairo_font_face_nil; 76- } 77+ if (!font) { 78+ hash_table = _cairo_win32_font_face_hash_table_lock (); 79+ if (unlikely (hash_table == NULL)) { 80+ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 81+ return (cairo_font_face_t *)&_cairo_font_face_nil; 82+ } 83 84- _cairo_win32_font_face_init_key (&key, logfont, font); 85+ _cairo_win32_font_face_init_key (&key, logfont, font); 86 87- /* Return existing unscaled font if it exists in the hash table. */ 88- font_face = _cairo_hash_table_lookup (hash_table, 89- &key.base.hash_entry); 90- if (font_face != NULL) { 91- cairo_font_face_reference (&font_face->base); 92- goto DONE; 93+ /* Return existing unscaled font if it exists in the hash table. */ 94+ font_face = _cairo_hash_table_lookup (hash_table, 95+ &key.base.hash_entry); 96+ if (font_face != NULL) { 97+ cairo_font_face_reference (&font_face->base); 98+ goto DONE; 99+ } 100 } 101 102 /* Otherwise create it and insert into hash table. */ 103 font_face = malloc (sizeof (cairo_win32_font_face_t)); 104 if (!font_face) { 105 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 106 goto FAIL; 107 } 108 109 _cairo_win32_font_face_init_key (font_face, logfont, font); 110 _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); 111+ assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); 112 113- assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); 114- status = _cairo_hash_table_insert (hash_table, 115- &font_face->base.hash_entry); 116- if (unlikely (status)) 117- goto FAIL; 118+ if (!font) { 119+ status = _cairo_hash_table_insert (hash_table, 120+ &font_face->base.hash_entry); 121+ if (unlikely (status)) 122+ goto FAIL; 123+ } 124 125 DONE: 126- _cairo_win32_font_face_hash_table_unlock (); 127+ if (!font) { 128+ _cairo_win32_font_face_hash_table_unlock (); 129+ } 130 131 return &font_face->base; 132 133 FAIL: 134- _cairo_win32_font_face_hash_table_unlock (); 135+ if (!font) { 136+ _cairo_win32_font_face_hash_table_unlock (); 137+ } 138 139 return (cairo_font_face_t *)&_cairo_font_face_nil; 140 } 141 142 /** 143 * cairo_win32_font_face_create_for_logfontw: 144 * @logfont: A #LOGFONTW structure specifying the font to use. 145 * The lfHeight, lfWidth, lfOrientation and lfEscapement 146