summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/win32-gdi-font-cache-no-HFONT.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/win32-gdi-font-cache-no-HFONT.patch')
-rw-r--r--gfx/cairo/win32-gdi-font-cache-no-HFONT.patch145
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