diff options
Diffstat (limited to 'gfx/cairo/win32-gdi-font-cache-no-HFONT.patch')
-rw-r--r-- | gfx/cairo/win32-gdi-font-cache-no-HFONT.patch | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/gfx/cairo/win32-gdi-font-cache-no-HFONT.patch b/gfx/cairo/win32-gdi-font-cache-no-HFONT.patch new file mode 100644 index 0000000000..fe93095aed --- /dev/null +++ b/gfx/cairo/win32-gdi-font-cache-no-HFONT.patch @@ -0,0 +1,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 |