summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/win32-gdi-font-cache.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/win32-gdi-font-cache.patch')
-rw-r--r--gfx/cairo/win32-gdi-font-cache.patch375
1 files changed, 375 insertions, 0 deletions
diff --git a/gfx/cairo/win32-gdi-font-cache.patch b/gfx/cairo/win32-gdi-font-cache.patch
new file mode 100644
index 000000000..e082a2e4d
--- /dev/null
+++ b/gfx/cairo/win32-gdi-font-cache.patch
@@ -0,0 +1,375 @@
+# HG changeset patch
+# User Andrea Canciani <ranma42@gmail.com>, Adrian Johnson <ajohnson@redneon.com>
+# Date 1354838294 -46800
+# Node ID 390df735b9d5c5ba07a4d3fe9ca2ebc9e7626a78
+# Parent e30a5b6a5a003b85fc1ca8b76719a56ef59d976e
+Bug 717178. Part 2: Import changesets eb29a25d, 6e3e3291 and 101fab7c from upstream.
+======
+
+From 101fab7cd8a90f7cf3d8113c792b3f8c2a9afb7d Mon Sep 17 00:00:00 2001
+From: Andrea Canciani <ranma42@gmail.com>
+Date: Wed, 15 Jun 2011 09:37:36 +0000
+Subject: win32-font: Improve static data reset function
+
+The hashtable is guaranteed to only contain font faces which are
+currently referenced, hence there is no need to remove any font face
+when it is reset (just like for toy-font).
+
+This makes the function simpler and fixes the assertion
+
+Assertion failed: predicate != NULL, file cairo-hash.c, line 373
+
+hit by multiple tests (the first one being "clear").
+
+See https://bugs.freedesktop.org/show_bug.cgi?id=38049
+
+======
+
+From eb29a25dd6dddc511388bf883c9b95843ecdb823 Mon Sep 17 00:00:00 2001
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Tue, 16 Nov 2010 13:18:39 +0000
+Subject: win32: Use a font_face hash table to provide unique font faces
+
+Similar to the freetype and toy font backends, use a hash table
+to map logfont,hfont to font faces.
+
+This fixes the multiple embedding of the same font in PDF.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=24849
+
+======
+
+From 6e3e329170ab4b96bc0d587c8071e869e228e758 Mon Sep 17 00:00:00 2001
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Thu, 18 Nov 2010 12:37:45 +0000
+Subject: win32: fix font_face hashing
+
+some bugs were discovered while testing with firefox
+
+======
+
+diff --git a/gfx/cairo/cairo/src/cairo-debug.c b/gfx/cairo/cairo/src/cairo-debug.c
+--- a/gfx/cairo/cairo/src/cairo-debug.c
++++ b/gfx/cairo/cairo/src/cairo-debug.c
+@@ -64,16 +64,20 @@ cairo_debug_reset_static_data (void)
+ _cairo_scaled_font_map_destroy ();
+
+ _cairo_toy_font_face_reset_static_data ();
+
+ #if CAIRO_HAS_FT_FONT
+ _cairo_ft_font_reset_static_data ();
+ #endif
+
++#if CAIRO_HAS_WIN32_FONT
++ _cairo_win32_font_reset_static_data ();
++#endif
++
+ _cairo_intern_string_reset_static_data ();
+
+ _cairo_scaled_font_reset_static_data ();
+
+ _cairo_pattern_reset_static_data ();
+
+ _cairo_clip_reset_static_data ();
+
+diff --git a/gfx/cairo/cairo/src/cairo-mutex-list-private.h b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
+--- a/gfx/cairo/cairo/src/cairo-mutex-list-private.h
++++ b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
+@@ -46,16 +46,20 @@ CAIRO_MUTEX_DECLARE (_cairo_intern_strin
+ CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex)
+ CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex)
+ CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
+
+ #if CAIRO_HAS_FT_FONT
+ CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
+ #endif
+
++#if CAIRO_HAS_WIN32_FONT
++CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex)
++#endif
++
+ #if CAIRO_HAS_XLIB_SURFACE
+ CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
+ #endif
+
+ #if CAIRO_HAS_XCB_SURFACE
+ CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex)
+ #endif
+
+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
+@@ -42,16 +42,18 @@
+ # define _WIN32_WINNT 0x0500
+ #endif
+
+ #include "cairoint.h"
+
+ #include "cairo-win32-private.h"
+ #include "cairo-error-private.h"
+
++#include <wchar.h>
++
+ #ifndef SPI_GETFONTSMOOTHINGTYPE
+ #define SPI_GETFONTSMOOTHINGTYPE 0x200a
+ #endif
+ #ifndef FE_FONTSMOOTHINGCLEARTYPE
+ #define FE_FONTSMOOTHINGCLEARTYPE 2
+ #endif
+ #ifndef CLEARTYPE_QUALITY
+ #define CLEARTYPE_QUALITY 5
+@@ -1887,19 +1889,17 @@ struct _cairo_win32_font_face {
+ cairo_font_face_t base;
+ LOGFONTW logfont;
+ HFONT hfont;
+ };
+
+ /* implement the platform-specific interface */
+
+ static void
+-_cairo_win32_font_face_destroy (void *abstract_face)
+-{
+-}
++_cairo_win32_font_face_destroy (void *abstract_face);
+
+ static cairo_bool_t
+ _is_scale (const cairo_matrix_t *matrix, double scale)
+ {
+ return matrix->xx == scale && matrix->yy == scale &&
+ matrix->xy == 0. && matrix->yx == 0. &&
+ matrix->x0 == 0. && matrix->y0 == 0.;
+ }
+@@ -1932,16 +1932,128 @@ static cairo_status_t
+
+ const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
+ CAIRO_FONT_TYPE_WIN32,
+ _cairo_win32_font_face_create_for_toy,
+ _cairo_win32_font_face_destroy,
+ _cairo_win32_font_face_scaled_font_create
+ };
+
++/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
++ * 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.
++ */
++
++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);
++
++static void
++_cairo_win32_font_face_hash_table_destroy (void)
++{
++ cairo_hash_table_t *hash_table;
++
++ /* We manually acquire the lock rather than calling
++ * _cairo_win32_font_face_hash_table_lock simply to avoid creating
++ * the table only to destroy it again. */
++ CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
++ hash_table = cairo_win32_font_face_hash_table;
++ cairo_win32_font_face_hash_table = NULL;
++ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
++
++ if (hash_table != NULL)
++ _cairo_hash_table_destroy (hash_table);
++}
++
++static cairo_hash_table_t *
++_cairo_win32_font_face_hash_table_lock (void)
++{
++ CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
++
++ if (unlikely (cairo_win32_font_face_hash_table == NULL))
++ {
++ cairo_win32_font_face_hash_table =
++ _cairo_hash_table_create (_cairo_win32_font_face_keys_equal);
++
++ if (unlikely (cairo_win32_font_face_hash_table == NULL)) {
++ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
++ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
++ return NULL;
++ }
++ }
++
++ return cairo_win32_font_face_hash_table;
++}
++
++static void
++_cairo_win32_font_face_hash_table_unlock (void)
++{
++ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
++}
++
++static void
++_cairo_win32_font_face_init_key (cairo_win32_font_face_t *key,
++ LOGFONTW *logfont,
++ HFONT font)
++{
++ unsigned long hash = _CAIRO_HASH_INIT_VALUE;
++
++ key->logfont = *logfont;
++ key->hfont = font;
++
++ hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName));
++ hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight));
++ hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic));
++
++ key->base.hash_entry.hash = hash;
++}
++
++static int
++_cairo_win32_font_face_keys_equal (const void *key_a,
++ const void *key_b)
++{
++ const cairo_win32_font_face_t *face_a = key_a;
++ const cairo_win32_font_face_t *face_b = key_b;
++
++ if (face_a->logfont.lfWeight == face_b->logfont.lfWeight &&
++ face_a->logfont.lfItalic == face_b->logfont.lfItalic &&
++ face_a->logfont.lfUnderline == face_b->logfont.lfUnderline &&
++ face_a->logfont.lfStrikeOut == face_b->logfont.lfStrikeOut &&
++ face_a->logfont.lfCharSet == face_b->logfont.lfCharSet &&
++ face_a->logfont.lfOutPrecision == face_b->logfont.lfOutPrecision &&
++ face_a->logfont.lfClipPrecision == face_b->logfont.lfClipPrecision &&
++ face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily &&
++ (wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0))
++ return TRUE;
++ else
++ return FALSE;
++}
++
++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;
++ }
++ _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.
+ * @font: An #HFONT that can be used when the font matrix is a scale by
+ * -lfHeight and the CTM is identity.
+@@ -1954,30 +2066,61 @@ const cairo_font_face_backend_t _cairo_w
+ * and can be used with functions such as cairo_win32_scaled_font_select_font().
+ *
+ * Return value: a newly created #cairo_font_face_t. Free with
+ * cairo_font_face_destroy() when you are done using it.
+ **/
+ cairo_font_face_t *
+ cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
+ {
+- cairo_win32_font_face_t *font_face;
++ 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;
++ }
++
++ _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;
++ }
++
++ /* 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);
+- return (cairo_font_face_t *)&_cairo_font_face_nil;
++ goto FAIL;
+ }
+
+- font_face->logfont = *logfont;
+- font_face->hfont = font;
+-
++ _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);
++ 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 ();
++
+ return &font_face->base;
++
++FAIL:
++ _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
+ * fields of this structure are ignored.
+ *
+@@ -2176,8 +2319,14 @@ cairo_win32_scaled_font_get_device_to_lo
+ cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
+ if (! _cairo_scaled_font_is_win32 (scaled_font)) {
+ _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
+ cairo_matrix_init_identity (device_to_logical);
+ return;
+ }
+ *device_to_logical = win_font->device_to_logical;
+ }
++
++void
++_cairo_win32_font_reset_static_data (void)
++{
++ _cairo_win32_font_face_hash_table_destroy ();
++}
+diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h
+--- a/gfx/cairo/cairo/src/cairoint.h
++++ b/gfx/cairo/cairo/src/cairoint.h
+@@ -403,16 +403,19 @@ cairo_private void
+ _cairo_reset_static_data (void);
+
+ cairo_private void
+ _cairo_toy_font_face_reset_static_data (void);
+
+ cairo_private void
+ _cairo_ft_font_reset_static_data (void);
+
++cairo_private void
++_cairo_win32_font_reset_static_data (void);
++
+ /* the font backend interface */
+
+ struct _cairo_unscaled_font_backend {
+ void (*destroy) (void *unscaled_font);
+ };
+
+ /* #cairo_toy_font_face_t - simple family/slant/weight font faces used for
+ * the built-in font API