michael@0: # HG changeset patch michael@0: # User Robert O'Callahan michael@0: # Date 1357107533 -46800 michael@0: # Node ID ed54dfdd2facb11a4d4158138b460a31de45e9f7 michael@0: # Parent ab6457cc16ec14ea07386dcfc57cad6b8a9ac55d michael@0: 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 michael@0: michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c michael@0: --- a/gfx/cairo/cairo/src/cairo-win32-font.c michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32-font.c michael@0: @@ -1941,16 +1942,21 @@ const cairo_font_face_backend_t _cairo_w michael@0: * The primary purpose of this mapping is to provide unique michael@0: * #cairo_font_face_t values so that our cache and mapping from michael@0: * #cairo_font_face_t => #cairo_scaled_font_t works. Once the michael@0: * corresponding #cairo_font_face_t objects fall out of downstream michael@0: * caches, we don't need them in this hash table anymore. michael@0: * michael@0: * Modifications to this hash table are protected by michael@0: * _cairo_win32_font_face_mutex. michael@0: + * michael@0: + * Only #cairo_font_face_t values with null 'hfont' (no michael@0: + * HFONT preallocated by caller) are stored in this table. We rely michael@0: + * on callers to manage the lifetime of the HFONT, and they can't michael@0: + * do that if we share #cairo_font_face_t values with other callers. michael@0: */ michael@0: michael@0: static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL; michael@0: michael@0: static int michael@0: _cairo_win32_font_face_keys_equal (const void *key_a, michael@0: const void *key_b); michael@0: michael@0: @@ -2036,22 +2042,24 @@ static int michael@0: } michael@0: michael@0: static void michael@0: _cairo_win32_font_face_destroy (void *abstract_face) michael@0: { michael@0: cairo_hash_table_t *hash_table; michael@0: cairo_win32_font_face_t *font_face = abstract_face; michael@0: michael@0: - hash_table = _cairo_win32_font_face_hash_table_lock (); michael@0: - if (unlikely (hash_table == NULL)) { michael@0: - return; michael@0: + if (!font_face->hfont) { michael@0: + hash_table = _cairo_win32_font_face_hash_table_lock (); michael@0: + if (unlikely (hash_table == NULL)) { michael@0: + return; michael@0: + } michael@0: + _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); michael@0: + _cairo_win32_font_face_hash_table_unlock (); michael@0: } michael@0: - _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); michael@0: - _cairo_win32_font_face_hash_table_unlock (); michael@0: } michael@0: michael@0: /** michael@0: * cairo_win32_font_face_create_for_logfontw_hfont: michael@0: * @logfont: A #LOGFONTW structure specifying the font to use. michael@0: * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement michael@0: * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and michael@0: * lfEscapement must be zero. michael@0: @@ -2070,55 +2078,63 @@ static void michael@0: **/ michael@0: cairo_font_face_t * michael@0: cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font) michael@0: { michael@0: cairo_win32_font_face_t *font_face, key; michael@0: cairo_hash_table_t *hash_table; michael@0: cairo_status_t status; michael@0: michael@0: - hash_table = _cairo_win32_font_face_hash_table_lock (); michael@0: - if (unlikely (hash_table == NULL)) { michael@0: - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); michael@0: - return (cairo_font_face_t *)&_cairo_font_face_nil; michael@0: - } michael@0: + if (!font) { michael@0: + hash_table = _cairo_win32_font_face_hash_table_lock (); michael@0: + if (unlikely (hash_table == NULL)) { michael@0: + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); michael@0: + return (cairo_font_face_t *)&_cairo_font_face_nil; michael@0: + } michael@0: michael@0: - _cairo_win32_font_face_init_key (&key, logfont, font); michael@0: + _cairo_win32_font_face_init_key (&key, logfont, font); michael@0: michael@0: - /* Return existing unscaled font if it exists in the hash table. */ michael@0: - font_face = _cairo_hash_table_lookup (hash_table, michael@0: - &key.base.hash_entry); michael@0: - if (font_face != NULL) { michael@0: - cairo_font_face_reference (&font_face->base); michael@0: - goto DONE; michael@0: + /* Return existing unscaled font if it exists in the hash table. */ michael@0: + font_face = _cairo_hash_table_lookup (hash_table, michael@0: + &key.base.hash_entry); michael@0: + if (font_face != NULL) { michael@0: + cairo_font_face_reference (&font_face->base); michael@0: + goto DONE; michael@0: + } michael@0: } michael@0: michael@0: /* Otherwise create it and insert into hash table. */ michael@0: font_face = malloc (sizeof (cairo_win32_font_face_t)); michael@0: if (!font_face) { michael@0: _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); michael@0: goto FAIL; michael@0: } michael@0: michael@0: _cairo_win32_font_face_init_key (font_face, logfont, font); michael@0: _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); michael@0: + assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); michael@0: michael@0: - assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); michael@0: - status = _cairo_hash_table_insert (hash_table, michael@0: - &font_face->base.hash_entry); michael@0: - if (unlikely (status)) michael@0: - goto FAIL; michael@0: + if (!font) { michael@0: + status = _cairo_hash_table_insert (hash_table, michael@0: + &font_face->base.hash_entry); michael@0: + if (unlikely (status)) michael@0: + goto FAIL; michael@0: + } michael@0: michael@0: DONE: michael@0: - _cairo_win32_font_face_hash_table_unlock (); michael@0: + if (!font) { michael@0: + _cairo_win32_font_face_hash_table_unlock (); michael@0: + } michael@0: michael@0: return &font_face->base; michael@0: michael@0: FAIL: michael@0: - _cairo_win32_font_face_hash_table_unlock (); michael@0: + if (!font) { michael@0: + _cairo_win32_font_face_hash_table_unlock (); michael@0: + } michael@0: michael@0: return (cairo_font_face_t *)&_cairo_font_face_nil; michael@0: } michael@0: michael@0: /** michael@0: * cairo_win32_font_face_create_for_logfontw: michael@0: * @logfont: A #LOGFONTW structure specifying the font to use. michael@0: * The lfHeight, lfWidth, lfOrientation and lfEscapement