1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/win32-gdi-font-cache.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,375 @@ 1.4 +# HG changeset patch 1.5 +# User Andrea Canciani <ranma42@gmail.com>, Adrian Johnson <ajohnson@redneon.com> 1.6 +# Date 1354838294 -46800 1.7 +# Node ID 390df735b9d5c5ba07a4d3fe9ca2ebc9e7626a78 1.8 +# Parent e30a5b6a5a003b85fc1ca8b76719a56ef59d976e 1.9 +Bug 717178. Part 2: Import changesets eb29a25d, 6e3e3291 and 101fab7c from upstream. 1.10 +====== 1.11 + 1.12 +From 101fab7cd8a90f7cf3d8113c792b3f8c2a9afb7d Mon Sep 17 00:00:00 2001 1.13 +From: Andrea Canciani <ranma42@gmail.com> 1.14 +Date: Wed, 15 Jun 2011 09:37:36 +0000 1.15 +Subject: win32-font: Improve static data reset function 1.16 + 1.17 +The hashtable is guaranteed to only contain font faces which are 1.18 +currently referenced, hence there is no need to remove any font face 1.19 +when it is reset (just like for toy-font). 1.20 + 1.21 +This makes the function simpler and fixes the assertion 1.22 + 1.23 +Assertion failed: predicate != NULL, file cairo-hash.c, line 373 1.24 + 1.25 +hit by multiple tests (the first one being "clear"). 1.26 + 1.27 +See https://bugs.freedesktop.org/show_bug.cgi?id=38049 1.28 + 1.29 +====== 1.30 + 1.31 +From eb29a25dd6dddc511388bf883c9b95843ecdb823 Mon Sep 17 00:00:00 2001 1.32 +From: Adrian Johnson <ajohnson@redneon.com> 1.33 +Date: Tue, 16 Nov 2010 13:18:39 +0000 1.34 +Subject: win32: Use a font_face hash table to provide unique font faces 1.35 + 1.36 +Similar to the freetype and toy font backends, use a hash table 1.37 +to map logfont,hfont to font faces. 1.38 + 1.39 +This fixes the multiple embedding of the same font in PDF. 1.40 + 1.41 +https://bugs.freedesktop.org/show_bug.cgi?id=24849 1.42 + 1.43 +====== 1.44 + 1.45 +From 6e3e329170ab4b96bc0d587c8071e869e228e758 Mon Sep 17 00:00:00 2001 1.46 +From: Adrian Johnson <ajohnson@redneon.com> 1.47 +Date: Thu, 18 Nov 2010 12:37:45 +0000 1.48 +Subject: win32: fix font_face hashing 1.49 + 1.50 +some bugs were discovered while testing with firefox 1.51 + 1.52 +====== 1.53 + 1.54 +diff --git a/gfx/cairo/cairo/src/cairo-debug.c b/gfx/cairo/cairo/src/cairo-debug.c 1.55 +--- a/gfx/cairo/cairo/src/cairo-debug.c 1.56 ++++ b/gfx/cairo/cairo/src/cairo-debug.c 1.57 +@@ -64,16 +64,20 @@ cairo_debug_reset_static_data (void) 1.58 + _cairo_scaled_font_map_destroy (); 1.59 + 1.60 + _cairo_toy_font_face_reset_static_data (); 1.61 + 1.62 + #if CAIRO_HAS_FT_FONT 1.63 + _cairo_ft_font_reset_static_data (); 1.64 + #endif 1.65 + 1.66 ++#if CAIRO_HAS_WIN32_FONT 1.67 ++ _cairo_win32_font_reset_static_data (); 1.68 ++#endif 1.69 ++ 1.70 + _cairo_intern_string_reset_static_data (); 1.71 + 1.72 + _cairo_scaled_font_reset_static_data (); 1.73 + 1.74 + _cairo_pattern_reset_static_data (); 1.75 + 1.76 + _cairo_clip_reset_static_data (); 1.77 + 1.78 +diff --git a/gfx/cairo/cairo/src/cairo-mutex-list-private.h b/gfx/cairo/cairo/src/cairo-mutex-list-private.h 1.79 +--- a/gfx/cairo/cairo/src/cairo-mutex-list-private.h 1.80 ++++ b/gfx/cairo/cairo/src/cairo-mutex-list-private.h 1.81 +@@ -46,16 +46,20 @@ CAIRO_MUTEX_DECLARE (_cairo_intern_strin 1.82 + CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex) 1.83 + CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex) 1.84 + CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex) 1.85 + 1.86 + #if CAIRO_HAS_FT_FONT 1.87 + CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex) 1.88 + #endif 1.89 + 1.90 ++#if CAIRO_HAS_WIN32_FONT 1.91 ++CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex) 1.92 ++#endif 1.93 ++ 1.94 + #if CAIRO_HAS_XLIB_SURFACE 1.95 + CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex) 1.96 + #endif 1.97 + 1.98 + #if CAIRO_HAS_XCB_SURFACE 1.99 + CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex) 1.100 + #endif 1.101 + 1.102 +diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c 1.103 +--- a/gfx/cairo/cairo/src/cairo-win32-font.c 1.104 ++++ b/gfx/cairo/cairo/src/cairo-win32-font.c 1.105 +@@ -42,16 +42,18 @@ 1.106 + # define _WIN32_WINNT 0x0500 1.107 + #endif 1.108 + 1.109 + #include "cairoint.h" 1.110 + 1.111 + #include "cairo-win32-private.h" 1.112 + #include "cairo-error-private.h" 1.113 + 1.114 ++#include <wchar.h> 1.115 ++ 1.116 + #ifndef SPI_GETFONTSMOOTHINGTYPE 1.117 + #define SPI_GETFONTSMOOTHINGTYPE 0x200a 1.118 + #endif 1.119 + #ifndef FE_FONTSMOOTHINGCLEARTYPE 1.120 + #define FE_FONTSMOOTHINGCLEARTYPE 2 1.121 + #endif 1.122 + #ifndef CLEARTYPE_QUALITY 1.123 + #define CLEARTYPE_QUALITY 5 1.124 +@@ -1887,19 +1889,17 @@ struct _cairo_win32_font_face { 1.125 + cairo_font_face_t base; 1.126 + LOGFONTW logfont; 1.127 + HFONT hfont; 1.128 + }; 1.129 + 1.130 + /* implement the platform-specific interface */ 1.131 + 1.132 + static void 1.133 +-_cairo_win32_font_face_destroy (void *abstract_face) 1.134 +-{ 1.135 +-} 1.136 ++_cairo_win32_font_face_destroy (void *abstract_face); 1.137 + 1.138 + static cairo_bool_t 1.139 + _is_scale (const cairo_matrix_t *matrix, double scale) 1.140 + { 1.141 + return matrix->xx == scale && matrix->yy == scale && 1.142 + matrix->xy == 0. && matrix->yx == 0. && 1.143 + matrix->x0 == 0. && matrix->y0 == 0.; 1.144 + } 1.145 +@@ -1932,16 +1932,128 @@ static cairo_status_t 1.146 + 1.147 + const cairo_font_face_backend_t _cairo_win32_font_face_backend = { 1.148 + CAIRO_FONT_TYPE_WIN32, 1.149 + _cairo_win32_font_face_create_for_toy, 1.150 + _cairo_win32_font_face_destroy, 1.151 + _cairo_win32_font_face_scaled_font_create 1.152 + }; 1.153 + 1.154 ++/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t. 1.155 ++ * The primary purpose of this mapping is to provide unique 1.156 ++ * #cairo_font_face_t values so that our cache and mapping from 1.157 ++ * #cairo_font_face_t => #cairo_scaled_font_t works. Once the 1.158 ++ * corresponding #cairo_font_face_t objects fall out of downstream 1.159 ++ * caches, we don't need them in this hash table anymore. 1.160 ++ * 1.161 ++ * Modifications to this hash table are protected by 1.162 ++ * _cairo_win32_font_face_mutex. 1.163 ++ */ 1.164 ++ 1.165 ++static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL; 1.166 ++ 1.167 ++static int 1.168 ++_cairo_win32_font_face_keys_equal (const void *key_a, 1.169 ++ const void *key_b); 1.170 ++ 1.171 ++static void 1.172 ++_cairo_win32_font_face_hash_table_destroy (void) 1.173 ++{ 1.174 ++ cairo_hash_table_t *hash_table; 1.175 ++ 1.176 ++ /* We manually acquire the lock rather than calling 1.177 ++ * _cairo_win32_font_face_hash_table_lock simply to avoid creating 1.178 ++ * the table only to destroy it again. */ 1.179 ++ CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex); 1.180 ++ hash_table = cairo_win32_font_face_hash_table; 1.181 ++ cairo_win32_font_face_hash_table = NULL; 1.182 ++ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex); 1.183 ++ 1.184 ++ if (hash_table != NULL) 1.185 ++ _cairo_hash_table_destroy (hash_table); 1.186 ++} 1.187 ++ 1.188 ++static cairo_hash_table_t * 1.189 ++_cairo_win32_font_face_hash_table_lock (void) 1.190 ++{ 1.191 ++ CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex); 1.192 ++ 1.193 ++ if (unlikely (cairo_win32_font_face_hash_table == NULL)) 1.194 ++ { 1.195 ++ cairo_win32_font_face_hash_table = 1.196 ++ _cairo_hash_table_create (_cairo_win32_font_face_keys_equal); 1.197 ++ 1.198 ++ if (unlikely (cairo_win32_font_face_hash_table == NULL)) { 1.199 ++ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex); 1.200 ++ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 1.201 ++ return NULL; 1.202 ++ } 1.203 ++ } 1.204 ++ 1.205 ++ return cairo_win32_font_face_hash_table; 1.206 ++} 1.207 ++ 1.208 ++static void 1.209 ++_cairo_win32_font_face_hash_table_unlock (void) 1.210 ++{ 1.211 ++ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex); 1.212 ++} 1.213 ++ 1.214 ++static void 1.215 ++_cairo_win32_font_face_init_key (cairo_win32_font_face_t *key, 1.216 ++ LOGFONTW *logfont, 1.217 ++ HFONT font) 1.218 ++{ 1.219 ++ unsigned long hash = _CAIRO_HASH_INIT_VALUE; 1.220 ++ 1.221 ++ key->logfont = *logfont; 1.222 ++ key->hfont = font; 1.223 ++ 1.224 ++ hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName)); 1.225 ++ hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight)); 1.226 ++ hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic)); 1.227 ++ 1.228 ++ key->base.hash_entry.hash = hash; 1.229 ++} 1.230 ++ 1.231 ++static int 1.232 ++_cairo_win32_font_face_keys_equal (const void *key_a, 1.233 ++ const void *key_b) 1.234 ++{ 1.235 ++ const cairo_win32_font_face_t *face_a = key_a; 1.236 ++ const cairo_win32_font_face_t *face_b = key_b; 1.237 ++ 1.238 ++ if (face_a->logfont.lfWeight == face_b->logfont.lfWeight && 1.239 ++ face_a->logfont.lfItalic == face_b->logfont.lfItalic && 1.240 ++ face_a->logfont.lfUnderline == face_b->logfont.lfUnderline && 1.241 ++ face_a->logfont.lfStrikeOut == face_b->logfont.lfStrikeOut && 1.242 ++ face_a->logfont.lfCharSet == face_b->logfont.lfCharSet && 1.243 ++ face_a->logfont.lfOutPrecision == face_b->logfont.lfOutPrecision && 1.244 ++ face_a->logfont.lfClipPrecision == face_b->logfont.lfClipPrecision && 1.245 ++ face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily && 1.246 ++ (wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0)) 1.247 ++ return TRUE; 1.248 ++ else 1.249 ++ return FALSE; 1.250 ++} 1.251 ++ 1.252 ++static void 1.253 ++_cairo_win32_font_face_destroy (void *abstract_face) 1.254 ++{ 1.255 ++ cairo_hash_table_t *hash_table; 1.256 ++ cairo_win32_font_face_t *font_face = abstract_face; 1.257 ++ 1.258 ++ hash_table = _cairo_win32_font_face_hash_table_lock (); 1.259 ++ if (unlikely (hash_table == NULL)) { 1.260 ++ return; 1.261 ++ } 1.262 ++ _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); 1.263 ++ _cairo_win32_font_face_hash_table_unlock (); 1.264 ++} 1.265 ++ 1.266 + /** 1.267 + * cairo_win32_font_face_create_for_logfontw_hfont: 1.268 + * @logfont: A #LOGFONTW structure specifying the font to use. 1.269 + * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement 1.270 + * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and 1.271 + * lfEscapement must be zero. 1.272 + * @font: An #HFONT that can be used when the font matrix is a scale by 1.273 + * -lfHeight and the CTM is identity. 1.274 +@@ -1954,30 +2066,61 @@ const cairo_font_face_backend_t _cairo_w 1.275 + * and can be used with functions such as cairo_win32_scaled_font_select_font(). 1.276 + * 1.277 + * Return value: a newly created #cairo_font_face_t. Free with 1.278 + * cairo_font_face_destroy() when you are done using it. 1.279 + **/ 1.280 + cairo_font_face_t * 1.281 + cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font) 1.282 + { 1.283 +- cairo_win32_font_face_t *font_face; 1.284 ++ cairo_win32_font_face_t *font_face, key; 1.285 ++ cairo_hash_table_t *hash_table; 1.286 ++ cairo_status_t status; 1.287 + 1.288 ++ hash_table = _cairo_win32_font_face_hash_table_lock (); 1.289 ++ if (unlikely (hash_table == NULL)) { 1.290 ++ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 1.291 ++ return (cairo_font_face_t *)&_cairo_font_face_nil; 1.292 ++ } 1.293 ++ 1.294 ++ _cairo_win32_font_face_init_key (&key, logfont, font); 1.295 ++ 1.296 ++ /* Return existing unscaled font if it exists in the hash table. */ 1.297 ++ font_face = _cairo_hash_table_lookup (hash_table, 1.298 ++ &key.base.hash_entry); 1.299 ++ if (font_face != NULL) { 1.300 ++ cairo_font_face_reference (&font_face->base); 1.301 ++ goto DONE; 1.302 ++ } 1.303 ++ 1.304 ++ /* Otherwise create it and insert into hash table. */ 1.305 + font_face = malloc (sizeof (cairo_win32_font_face_t)); 1.306 + if (!font_face) { 1.307 + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 1.308 +- return (cairo_font_face_t *)&_cairo_font_face_nil; 1.309 ++ goto FAIL; 1.310 + } 1.311 + 1.312 +- font_face->logfont = *logfont; 1.313 +- font_face->hfont = font; 1.314 +- 1.315 ++ _cairo_win32_font_face_init_key (font_face, logfont, font); 1.316 + _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); 1.317 + 1.318 ++ assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); 1.319 ++ status = _cairo_hash_table_insert (hash_table, 1.320 ++ &font_face->base.hash_entry); 1.321 ++ if (unlikely (status)) 1.322 ++ goto FAIL; 1.323 ++ 1.324 ++DONE: 1.325 ++ _cairo_win32_font_face_hash_table_unlock (); 1.326 ++ 1.327 + return &font_face->base; 1.328 ++ 1.329 ++FAIL: 1.330 ++ _cairo_win32_font_face_hash_table_unlock (); 1.331 ++ 1.332 ++ return (cairo_font_face_t *)&_cairo_font_face_nil; 1.333 + } 1.334 + 1.335 + /** 1.336 + * cairo_win32_font_face_create_for_logfontw: 1.337 + * @logfont: A #LOGFONTW structure specifying the font to use. 1.338 + * The lfHeight, lfWidth, lfOrientation and lfEscapement 1.339 + * fields of this structure are ignored. 1.340 + * 1.341 +@@ -2176,8 +2319,14 @@ cairo_win32_scaled_font_get_device_to_lo 1.342 + cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font; 1.343 + if (! _cairo_scaled_font_is_win32 (scaled_font)) { 1.344 + _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH); 1.345 + cairo_matrix_init_identity (device_to_logical); 1.346 + return; 1.347 + } 1.348 + *device_to_logical = win_font->device_to_logical; 1.349 + } 1.350 ++ 1.351 ++void 1.352 ++_cairo_win32_font_reset_static_data (void) 1.353 ++{ 1.354 ++ _cairo_win32_font_face_hash_table_destroy (); 1.355 ++} 1.356 +diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h 1.357 +--- a/gfx/cairo/cairo/src/cairoint.h 1.358 ++++ b/gfx/cairo/cairo/src/cairoint.h 1.359 +@@ -403,16 +403,19 @@ cairo_private void 1.360 + _cairo_reset_static_data (void); 1.361 + 1.362 + cairo_private void 1.363 + _cairo_toy_font_face_reset_static_data (void); 1.364 + 1.365 + cairo_private void 1.366 + _cairo_ft_font_reset_static_data (void); 1.367 + 1.368 ++cairo_private void 1.369 ++_cairo_win32_font_reset_static_data (void); 1.370 ++ 1.371 + /* the font backend interface */ 1.372 + 1.373 + struct _cairo_unscaled_font_backend { 1.374 + void (*destroy) (void *unscaled_font); 1.375 + }; 1.376 + 1.377 + /* #cairo_toy_font_face_t - simple family/slant/weight font faces used for 1.378 + * the built-in font API