gfx/cairo/win32-gdi-font-cache.patch

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 # HG changeset patch
michael@0 2 # User Andrea Canciani <ranma42@gmail.com>, Adrian Johnson <ajohnson@redneon.com>
michael@0 3 # Date 1354838294 -46800
michael@0 4 # Node ID 390df735b9d5c5ba07a4d3fe9ca2ebc9e7626a78
michael@0 5 # Parent e30a5b6a5a003b85fc1ca8b76719a56ef59d976e
michael@0 6 Bug 717178. Part 2: Import changesets eb29a25d, 6e3e3291 and 101fab7c from upstream.
michael@0 7 ======
michael@0 8
michael@0 9 From 101fab7cd8a90f7cf3d8113c792b3f8c2a9afb7d Mon Sep 17 00:00:00 2001
michael@0 10 From: Andrea Canciani <ranma42@gmail.com>
michael@0 11 Date: Wed, 15 Jun 2011 09:37:36 +0000
michael@0 12 Subject: win32-font: Improve static data reset function
michael@0 13
michael@0 14 The hashtable is guaranteed to only contain font faces which are
michael@0 15 currently referenced, hence there is no need to remove any font face
michael@0 16 when it is reset (just like for toy-font).
michael@0 17
michael@0 18 This makes the function simpler and fixes the assertion
michael@0 19
michael@0 20 Assertion failed: predicate != NULL, file cairo-hash.c, line 373
michael@0 21
michael@0 22 hit by multiple tests (the first one being "clear").
michael@0 23
michael@0 24 See https://bugs.freedesktop.org/show_bug.cgi?id=38049
michael@0 25
michael@0 26 ======
michael@0 27
michael@0 28 From eb29a25dd6dddc511388bf883c9b95843ecdb823 Mon Sep 17 00:00:00 2001
michael@0 29 From: Adrian Johnson <ajohnson@redneon.com>
michael@0 30 Date: Tue, 16 Nov 2010 13:18:39 +0000
michael@0 31 Subject: win32: Use a font_face hash table to provide unique font faces
michael@0 32
michael@0 33 Similar to the freetype and toy font backends, use a hash table
michael@0 34 to map logfont,hfont to font faces.
michael@0 35
michael@0 36 This fixes the multiple embedding of the same font in PDF.
michael@0 37
michael@0 38 https://bugs.freedesktop.org/show_bug.cgi?id=24849
michael@0 39
michael@0 40 ======
michael@0 41
michael@0 42 From 6e3e329170ab4b96bc0d587c8071e869e228e758 Mon Sep 17 00:00:00 2001
michael@0 43 From: Adrian Johnson <ajohnson@redneon.com>
michael@0 44 Date: Thu, 18 Nov 2010 12:37:45 +0000
michael@0 45 Subject: win32: fix font_face hashing
michael@0 46
michael@0 47 some bugs were discovered while testing with firefox
michael@0 48
michael@0 49 ======
michael@0 50
michael@0 51 diff --git a/gfx/cairo/cairo/src/cairo-debug.c b/gfx/cairo/cairo/src/cairo-debug.c
michael@0 52 --- a/gfx/cairo/cairo/src/cairo-debug.c
michael@0 53 +++ b/gfx/cairo/cairo/src/cairo-debug.c
michael@0 54 @@ -64,16 +64,20 @@ cairo_debug_reset_static_data (void)
michael@0 55 _cairo_scaled_font_map_destroy ();
michael@0 56
michael@0 57 _cairo_toy_font_face_reset_static_data ();
michael@0 58
michael@0 59 #if CAIRO_HAS_FT_FONT
michael@0 60 _cairo_ft_font_reset_static_data ();
michael@0 61 #endif
michael@0 62
michael@0 63 +#if CAIRO_HAS_WIN32_FONT
michael@0 64 + _cairo_win32_font_reset_static_data ();
michael@0 65 +#endif
michael@0 66 +
michael@0 67 _cairo_intern_string_reset_static_data ();
michael@0 68
michael@0 69 _cairo_scaled_font_reset_static_data ();
michael@0 70
michael@0 71 _cairo_pattern_reset_static_data ();
michael@0 72
michael@0 73 _cairo_clip_reset_static_data ();
michael@0 74
michael@0 75 diff --git a/gfx/cairo/cairo/src/cairo-mutex-list-private.h b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
michael@0 76 --- a/gfx/cairo/cairo/src/cairo-mutex-list-private.h
michael@0 77 +++ b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
michael@0 78 @@ -46,16 +46,20 @@ CAIRO_MUTEX_DECLARE (_cairo_intern_strin
michael@0 79 CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex)
michael@0 80 CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex)
michael@0 81 CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
michael@0 82
michael@0 83 #if CAIRO_HAS_FT_FONT
michael@0 84 CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
michael@0 85 #endif
michael@0 86
michael@0 87 +#if CAIRO_HAS_WIN32_FONT
michael@0 88 +CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex)
michael@0 89 +#endif
michael@0 90 +
michael@0 91 #if CAIRO_HAS_XLIB_SURFACE
michael@0 92 CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
michael@0 93 #endif
michael@0 94
michael@0 95 #if CAIRO_HAS_XCB_SURFACE
michael@0 96 CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex)
michael@0 97 #endif
michael@0 98
michael@0 99 diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c
michael@0 100 --- a/gfx/cairo/cairo/src/cairo-win32-font.c
michael@0 101 +++ b/gfx/cairo/cairo/src/cairo-win32-font.c
michael@0 102 @@ -42,16 +42,18 @@
michael@0 103 # define _WIN32_WINNT 0x0500
michael@0 104 #endif
michael@0 105
michael@0 106 #include "cairoint.h"
michael@0 107
michael@0 108 #include "cairo-win32-private.h"
michael@0 109 #include "cairo-error-private.h"
michael@0 110
michael@0 111 +#include <wchar.h>
michael@0 112 +
michael@0 113 #ifndef SPI_GETFONTSMOOTHINGTYPE
michael@0 114 #define SPI_GETFONTSMOOTHINGTYPE 0x200a
michael@0 115 #endif
michael@0 116 #ifndef FE_FONTSMOOTHINGCLEARTYPE
michael@0 117 #define FE_FONTSMOOTHINGCLEARTYPE 2
michael@0 118 #endif
michael@0 119 #ifndef CLEARTYPE_QUALITY
michael@0 120 #define CLEARTYPE_QUALITY 5
michael@0 121 @@ -1887,19 +1889,17 @@ struct _cairo_win32_font_face {
michael@0 122 cairo_font_face_t base;
michael@0 123 LOGFONTW logfont;
michael@0 124 HFONT hfont;
michael@0 125 };
michael@0 126
michael@0 127 /* implement the platform-specific interface */
michael@0 128
michael@0 129 static void
michael@0 130 -_cairo_win32_font_face_destroy (void *abstract_face)
michael@0 131 -{
michael@0 132 -}
michael@0 133 +_cairo_win32_font_face_destroy (void *abstract_face);
michael@0 134
michael@0 135 static cairo_bool_t
michael@0 136 _is_scale (const cairo_matrix_t *matrix, double scale)
michael@0 137 {
michael@0 138 return matrix->xx == scale && matrix->yy == scale &&
michael@0 139 matrix->xy == 0. && matrix->yx == 0. &&
michael@0 140 matrix->x0 == 0. && matrix->y0 == 0.;
michael@0 141 }
michael@0 142 @@ -1932,16 +1932,128 @@ static cairo_status_t
michael@0 143
michael@0 144 const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
michael@0 145 CAIRO_FONT_TYPE_WIN32,
michael@0 146 _cairo_win32_font_face_create_for_toy,
michael@0 147 _cairo_win32_font_face_destroy,
michael@0 148 _cairo_win32_font_face_scaled_font_create
michael@0 149 };
michael@0 150
michael@0 151 +/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
michael@0 152 + * The primary purpose of this mapping is to provide unique
michael@0 153 + * #cairo_font_face_t values so that our cache and mapping from
michael@0 154 + * #cairo_font_face_t => #cairo_scaled_font_t works. Once the
michael@0 155 + * corresponding #cairo_font_face_t objects fall out of downstream
michael@0 156 + * caches, we don't need them in this hash table anymore.
michael@0 157 + *
michael@0 158 + * Modifications to this hash table are protected by
michael@0 159 + * _cairo_win32_font_face_mutex.
michael@0 160 + */
michael@0 161 +
michael@0 162 +static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
michael@0 163 +
michael@0 164 +static int
michael@0 165 +_cairo_win32_font_face_keys_equal (const void *key_a,
michael@0 166 + const void *key_b);
michael@0 167 +
michael@0 168 +static void
michael@0 169 +_cairo_win32_font_face_hash_table_destroy (void)
michael@0 170 +{
michael@0 171 + cairo_hash_table_t *hash_table;
michael@0 172 +
michael@0 173 + /* We manually acquire the lock rather than calling
michael@0 174 + * _cairo_win32_font_face_hash_table_lock simply to avoid creating
michael@0 175 + * the table only to destroy it again. */
michael@0 176 + CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
michael@0 177 + hash_table = cairo_win32_font_face_hash_table;
michael@0 178 + cairo_win32_font_face_hash_table = NULL;
michael@0 179 + CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
michael@0 180 +
michael@0 181 + if (hash_table != NULL)
michael@0 182 + _cairo_hash_table_destroy (hash_table);
michael@0 183 +}
michael@0 184 +
michael@0 185 +static cairo_hash_table_t *
michael@0 186 +_cairo_win32_font_face_hash_table_lock (void)
michael@0 187 +{
michael@0 188 + CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
michael@0 189 +
michael@0 190 + if (unlikely (cairo_win32_font_face_hash_table == NULL))
michael@0 191 + {
michael@0 192 + cairo_win32_font_face_hash_table =
michael@0 193 + _cairo_hash_table_create (_cairo_win32_font_face_keys_equal);
michael@0 194 +
michael@0 195 + if (unlikely (cairo_win32_font_face_hash_table == NULL)) {
michael@0 196 + CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
michael@0 197 + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
michael@0 198 + return NULL;
michael@0 199 + }
michael@0 200 + }
michael@0 201 +
michael@0 202 + return cairo_win32_font_face_hash_table;
michael@0 203 +}
michael@0 204 +
michael@0 205 +static void
michael@0 206 +_cairo_win32_font_face_hash_table_unlock (void)
michael@0 207 +{
michael@0 208 + CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
michael@0 209 +}
michael@0 210 +
michael@0 211 +static void
michael@0 212 +_cairo_win32_font_face_init_key (cairo_win32_font_face_t *key,
michael@0 213 + LOGFONTW *logfont,
michael@0 214 + HFONT font)
michael@0 215 +{
michael@0 216 + unsigned long hash = _CAIRO_HASH_INIT_VALUE;
michael@0 217 +
michael@0 218 + key->logfont = *logfont;
michael@0 219 + key->hfont = font;
michael@0 220 +
michael@0 221 + hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName));
michael@0 222 + hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight));
michael@0 223 + hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic));
michael@0 224 +
michael@0 225 + key->base.hash_entry.hash = hash;
michael@0 226 +}
michael@0 227 +
michael@0 228 +static int
michael@0 229 +_cairo_win32_font_face_keys_equal (const void *key_a,
michael@0 230 + const void *key_b)
michael@0 231 +{
michael@0 232 + const cairo_win32_font_face_t *face_a = key_a;
michael@0 233 + const cairo_win32_font_face_t *face_b = key_b;
michael@0 234 +
michael@0 235 + if (face_a->logfont.lfWeight == face_b->logfont.lfWeight &&
michael@0 236 + face_a->logfont.lfItalic == face_b->logfont.lfItalic &&
michael@0 237 + face_a->logfont.lfUnderline == face_b->logfont.lfUnderline &&
michael@0 238 + face_a->logfont.lfStrikeOut == face_b->logfont.lfStrikeOut &&
michael@0 239 + face_a->logfont.lfCharSet == face_b->logfont.lfCharSet &&
michael@0 240 + face_a->logfont.lfOutPrecision == face_b->logfont.lfOutPrecision &&
michael@0 241 + face_a->logfont.lfClipPrecision == face_b->logfont.lfClipPrecision &&
michael@0 242 + face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily &&
michael@0 243 + (wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0))
michael@0 244 + return TRUE;
michael@0 245 + else
michael@0 246 + return FALSE;
michael@0 247 +}
michael@0 248 +
michael@0 249 +static void
michael@0 250 +_cairo_win32_font_face_destroy (void *abstract_face)
michael@0 251 +{
michael@0 252 + cairo_hash_table_t *hash_table;
michael@0 253 + cairo_win32_font_face_t *font_face = abstract_face;
michael@0 254 +
michael@0 255 + hash_table = _cairo_win32_font_face_hash_table_lock ();
michael@0 256 + if (unlikely (hash_table == NULL)) {
michael@0 257 + return;
michael@0 258 + }
michael@0 259 + _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
michael@0 260 + _cairo_win32_font_face_hash_table_unlock ();
michael@0 261 +}
michael@0 262 +
michael@0 263 /**
michael@0 264 * cairo_win32_font_face_create_for_logfontw_hfont:
michael@0 265 * @logfont: A #LOGFONTW structure specifying the font to use.
michael@0 266 * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
michael@0 267 * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
michael@0 268 * lfEscapement must be zero.
michael@0 269 * @font: An #HFONT that can be used when the font matrix is a scale by
michael@0 270 * -lfHeight and the CTM is identity.
michael@0 271 @@ -1954,30 +2066,61 @@ const cairo_font_face_backend_t _cairo_w
michael@0 272 * and can be used with functions such as cairo_win32_scaled_font_select_font().
michael@0 273 *
michael@0 274 * Return value: a newly created #cairo_font_face_t. Free with
michael@0 275 * cairo_font_face_destroy() when you are done using it.
michael@0 276 **/
michael@0 277 cairo_font_face_t *
michael@0 278 cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
michael@0 279 {
michael@0 280 - cairo_win32_font_face_t *font_face;
michael@0 281 + cairo_win32_font_face_t *font_face, key;
michael@0 282 + cairo_hash_table_t *hash_table;
michael@0 283 + cairo_status_t status;
michael@0 284
michael@0 285 + hash_table = _cairo_win32_font_face_hash_table_lock ();
michael@0 286 + if (unlikely (hash_table == NULL)) {
michael@0 287 + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
michael@0 288 + return (cairo_font_face_t *)&_cairo_font_face_nil;
michael@0 289 + }
michael@0 290 +
michael@0 291 + _cairo_win32_font_face_init_key (&key, logfont, font);
michael@0 292 +
michael@0 293 + /* Return existing unscaled font if it exists in the hash table. */
michael@0 294 + font_face = _cairo_hash_table_lookup (hash_table,
michael@0 295 + &key.base.hash_entry);
michael@0 296 + if (font_face != NULL) {
michael@0 297 + cairo_font_face_reference (&font_face->base);
michael@0 298 + goto DONE;
michael@0 299 + }
michael@0 300 +
michael@0 301 + /* Otherwise create it and insert into hash table. */
michael@0 302 font_face = malloc (sizeof (cairo_win32_font_face_t));
michael@0 303 if (!font_face) {
michael@0 304 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
michael@0 305 - return (cairo_font_face_t *)&_cairo_font_face_nil;
michael@0 306 + goto FAIL;
michael@0 307 }
michael@0 308
michael@0 309 - font_face->logfont = *logfont;
michael@0 310 - font_face->hfont = font;
michael@0 311 -
michael@0 312 + _cairo_win32_font_face_init_key (font_face, logfont, font);
michael@0 313 _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
michael@0 314
michael@0 315 + assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
michael@0 316 + status = _cairo_hash_table_insert (hash_table,
michael@0 317 + &font_face->base.hash_entry);
michael@0 318 + if (unlikely (status))
michael@0 319 + goto FAIL;
michael@0 320 +
michael@0 321 +DONE:
michael@0 322 + _cairo_win32_font_face_hash_table_unlock ();
michael@0 323 +
michael@0 324 return &font_face->base;
michael@0 325 +
michael@0 326 +FAIL:
michael@0 327 + _cairo_win32_font_face_hash_table_unlock ();
michael@0 328 +
michael@0 329 + return (cairo_font_face_t *)&_cairo_font_face_nil;
michael@0 330 }
michael@0 331
michael@0 332 /**
michael@0 333 * cairo_win32_font_face_create_for_logfontw:
michael@0 334 * @logfont: A #LOGFONTW structure specifying the font to use.
michael@0 335 * The lfHeight, lfWidth, lfOrientation and lfEscapement
michael@0 336 * fields of this structure are ignored.
michael@0 337 *
michael@0 338 @@ -2176,8 +2319,14 @@ cairo_win32_scaled_font_get_device_to_lo
michael@0 339 cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
michael@0 340 if (! _cairo_scaled_font_is_win32 (scaled_font)) {
michael@0 341 _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
michael@0 342 cairo_matrix_init_identity (device_to_logical);
michael@0 343 return;
michael@0 344 }
michael@0 345 *device_to_logical = win_font->device_to_logical;
michael@0 346 }
michael@0 347 +
michael@0 348 +void
michael@0 349 +_cairo_win32_font_reset_static_data (void)
michael@0 350 +{
michael@0 351 + _cairo_win32_font_face_hash_table_destroy ();
michael@0 352 +}
michael@0 353 diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h
michael@0 354 --- a/gfx/cairo/cairo/src/cairoint.h
michael@0 355 +++ b/gfx/cairo/cairo/src/cairoint.h
michael@0 356 @@ -403,16 +403,19 @@ cairo_private void
michael@0 357 _cairo_reset_static_data (void);
michael@0 358
michael@0 359 cairo_private void
michael@0 360 _cairo_toy_font_face_reset_static_data (void);
michael@0 361
michael@0 362 cairo_private void
michael@0 363 _cairo_ft_font_reset_static_data (void);
michael@0 364
michael@0 365 +cairo_private void
michael@0 366 +_cairo_win32_font_reset_static_data (void);
michael@0 367 +
michael@0 368 /* the font backend interface */
michael@0 369
michael@0 370 struct _cairo_unscaled_font_backend {
michael@0 371 void (*destroy) (void *unscaled_font);
michael@0 372 };
michael@0 373
michael@0 374 /* #cairo_toy_font_face_t - simple family/slant/weight font faces used for
michael@0 375 * the built-in font API

mercurial