зеркало из https://github.com/mozilla/gecko-dev.git
146 строки
5.2 KiB
Diff
146 строки
5.2 KiB
Diff
|
# 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
|