1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/win32-gdi-font-cache-no-HFONT.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,145 @@ 1.4 +# HG changeset patch 1.5 +# User Robert O'Callahan <robert@ocallahan.org> 1.6 +# Date 1357107533 -46800 1.7 +# Node ID ed54dfdd2facb11a4d4158138b460a31de45e9f7 1.8 +# Parent ab6457cc16ec14ea07386dcfc57cad6b8a9ac55d 1.9 +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 1.10 + 1.11 +diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c 1.12 +--- a/gfx/cairo/cairo/src/cairo-win32-font.c 1.13 ++++ b/gfx/cairo/cairo/src/cairo-win32-font.c 1.14 +@@ -1941,16 +1942,21 @@ const cairo_font_face_backend_t _cairo_w 1.15 + * The primary purpose of this mapping is to provide unique 1.16 + * #cairo_font_face_t values so that our cache and mapping from 1.17 + * #cairo_font_face_t => #cairo_scaled_font_t works. Once the 1.18 + * corresponding #cairo_font_face_t objects fall out of downstream 1.19 + * caches, we don't need them in this hash table anymore. 1.20 + * 1.21 + * Modifications to this hash table are protected by 1.22 + * _cairo_win32_font_face_mutex. 1.23 ++ * 1.24 ++ * Only #cairo_font_face_t values with null 'hfont' (no 1.25 ++ * HFONT preallocated by caller) are stored in this table. We rely 1.26 ++ * on callers to manage the lifetime of the HFONT, and they can't 1.27 ++ * do that if we share #cairo_font_face_t values with other callers. 1.28 + */ 1.29 + 1.30 + static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL; 1.31 + 1.32 + static int 1.33 + _cairo_win32_font_face_keys_equal (const void *key_a, 1.34 + const void *key_b); 1.35 + 1.36 +@@ -2036,22 +2042,24 @@ static int 1.37 + } 1.38 + 1.39 + static void 1.40 + _cairo_win32_font_face_destroy (void *abstract_face) 1.41 + { 1.42 + cairo_hash_table_t *hash_table; 1.43 + cairo_win32_font_face_t *font_face = abstract_face; 1.44 + 1.45 +- hash_table = _cairo_win32_font_face_hash_table_lock (); 1.46 +- if (unlikely (hash_table == NULL)) { 1.47 +- return; 1.48 ++ if (!font_face->hfont) { 1.49 ++ hash_table = _cairo_win32_font_face_hash_table_lock (); 1.50 ++ if (unlikely (hash_table == NULL)) { 1.51 ++ return; 1.52 ++ } 1.53 ++ _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); 1.54 ++ _cairo_win32_font_face_hash_table_unlock (); 1.55 + } 1.56 +- _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); 1.57 +- _cairo_win32_font_face_hash_table_unlock (); 1.58 + } 1.59 + 1.60 + /** 1.61 + * cairo_win32_font_face_create_for_logfontw_hfont: 1.62 + * @logfont: A #LOGFONTW structure specifying the font to use. 1.63 + * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement 1.64 + * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and 1.65 + * lfEscapement must be zero. 1.66 +@@ -2070,55 +2078,63 @@ static void 1.67 + **/ 1.68 + cairo_font_face_t * 1.69 + cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font) 1.70 + { 1.71 + cairo_win32_font_face_t *font_face, key; 1.72 + cairo_hash_table_t *hash_table; 1.73 + cairo_status_t status; 1.74 + 1.75 +- hash_table = _cairo_win32_font_face_hash_table_lock (); 1.76 +- if (unlikely (hash_table == NULL)) { 1.77 +- _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 1.78 +- return (cairo_font_face_t *)&_cairo_font_face_nil; 1.79 +- } 1.80 ++ if (!font) { 1.81 ++ hash_table = _cairo_win32_font_face_hash_table_lock (); 1.82 ++ if (unlikely (hash_table == NULL)) { 1.83 ++ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 1.84 ++ return (cairo_font_face_t *)&_cairo_font_face_nil; 1.85 ++ } 1.86 + 1.87 +- _cairo_win32_font_face_init_key (&key, logfont, font); 1.88 ++ _cairo_win32_font_face_init_key (&key, logfont, font); 1.89 + 1.90 +- /* Return existing unscaled font if it exists in the hash table. */ 1.91 +- font_face = _cairo_hash_table_lookup (hash_table, 1.92 +- &key.base.hash_entry); 1.93 +- if (font_face != NULL) { 1.94 +- cairo_font_face_reference (&font_face->base); 1.95 +- goto DONE; 1.96 ++ /* Return existing unscaled font if it exists in the hash table. */ 1.97 ++ font_face = _cairo_hash_table_lookup (hash_table, 1.98 ++ &key.base.hash_entry); 1.99 ++ if (font_face != NULL) { 1.100 ++ cairo_font_face_reference (&font_face->base); 1.101 ++ goto DONE; 1.102 ++ } 1.103 + } 1.104 + 1.105 + /* Otherwise create it and insert into hash table. */ 1.106 + font_face = malloc (sizeof (cairo_win32_font_face_t)); 1.107 + if (!font_face) { 1.108 + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 1.109 + goto FAIL; 1.110 + } 1.111 + 1.112 + _cairo_win32_font_face_init_key (font_face, logfont, font); 1.113 + _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); 1.114 ++ assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); 1.115 + 1.116 +- assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); 1.117 +- status = _cairo_hash_table_insert (hash_table, 1.118 +- &font_face->base.hash_entry); 1.119 +- if (unlikely (status)) 1.120 +- goto FAIL; 1.121 ++ if (!font) { 1.122 ++ status = _cairo_hash_table_insert (hash_table, 1.123 ++ &font_face->base.hash_entry); 1.124 ++ if (unlikely (status)) 1.125 ++ goto FAIL; 1.126 ++ } 1.127 + 1.128 + DONE: 1.129 +- _cairo_win32_font_face_hash_table_unlock (); 1.130 ++ if (!font) { 1.131 ++ _cairo_win32_font_face_hash_table_unlock (); 1.132 ++ } 1.133 + 1.134 + return &font_face->base; 1.135 + 1.136 + FAIL: 1.137 +- _cairo_win32_font_face_hash_table_unlock (); 1.138 ++ if (!font) { 1.139 ++ _cairo_win32_font_face_hash_table_unlock (); 1.140 ++ } 1.141 + 1.142 + return (cairo_font_face_t *)&_cairo_font_face_nil; 1.143 + } 1.144 + 1.145 + /** 1.146 + * cairo_win32_font_face_create_for_logfontw: 1.147 + * @logfont: A #LOGFONTW structure specifying the font to use. 1.148 + * The lfHeight, lfWidth, lfOrientation and lfEscapement