1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
# 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
|