|
1 # HG changeset patch |
|
2 # User Robert O'Callahan <robert@ocallahan.org> |
|
3 # Date 1357107533 -46800 |
|
4 # Node ID ed54dfdd2facb11a4d4158138b460a31de45e9f7 |
|
5 # Parent ab6457cc16ec14ea07386dcfc57cad6b8a9ac55d |
|
6 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 |
|
7 |
|
8 diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c |
|
9 --- a/gfx/cairo/cairo/src/cairo-win32-font.c |
|
10 +++ b/gfx/cairo/cairo/src/cairo-win32-font.c |
|
11 @@ -1941,16 +1942,21 @@ const cairo_font_face_backend_t _cairo_w |
|
12 * The primary purpose of this mapping is to provide unique |
|
13 * #cairo_font_face_t values so that our cache and mapping from |
|
14 * #cairo_font_face_t => #cairo_scaled_font_t works. Once the |
|
15 * corresponding #cairo_font_face_t objects fall out of downstream |
|
16 * caches, we don't need them in this hash table anymore. |
|
17 * |
|
18 * Modifications to this hash table are protected by |
|
19 * _cairo_win32_font_face_mutex. |
|
20 + * |
|
21 + * Only #cairo_font_face_t values with null 'hfont' (no |
|
22 + * HFONT preallocated by caller) are stored in this table. We rely |
|
23 + * on callers to manage the lifetime of the HFONT, and they can't |
|
24 + * do that if we share #cairo_font_face_t values with other callers. |
|
25 */ |
|
26 |
|
27 static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL; |
|
28 |
|
29 static int |
|
30 _cairo_win32_font_face_keys_equal (const void *key_a, |
|
31 const void *key_b); |
|
32 |
|
33 @@ -2036,22 +2042,24 @@ static int |
|
34 } |
|
35 |
|
36 static void |
|
37 _cairo_win32_font_face_destroy (void *abstract_face) |
|
38 { |
|
39 cairo_hash_table_t *hash_table; |
|
40 cairo_win32_font_face_t *font_face = abstract_face; |
|
41 |
|
42 - hash_table = _cairo_win32_font_face_hash_table_lock (); |
|
43 - if (unlikely (hash_table == NULL)) { |
|
44 - return; |
|
45 + if (!font_face->hfont) { |
|
46 + hash_table = _cairo_win32_font_face_hash_table_lock (); |
|
47 + if (unlikely (hash_table == NULL)) { |
|
48 + return; |
|
49 + } |
|
50 + _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); |
|
51 + _cairo_win32_font_face_hash_table_unlock (); |
|
52 } |
|
53 - _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); |
|
54 - _cairo_win32_font_face_hash_table_unlock (); |
|
55 } |
|
56 |
|
57 /** |
|
58 * cairo_win32_font_face_create_for_logfontw_hfont: |
|
59 * @logfont: A #LOGFONTW structure specifying the font to use. |
|
60 * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement |
|
61 * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and |
|
62 * lfEscapement must be zero. |
|
63 @@ -2070,55 +2078,63 @@ static void |
|
64 **/ |
|
65 cairo_font_face_t * |
|
66 cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font) |
|
67 { |
|
68 cairo_win32_font_face_t *font_face, key; |
|
69 cairo_hash_table_t *hash_table; |
|
70 cairo_status_t status; |
|
71 |
|
72 - hash_table = _cairo_win32_font_face_hash_table_lock (); |
|
73 - if (unlikely (hash_table == NULL)) { |
|
74 - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); |
|
75 - return (cairo_font_face_t *)&_cairo_font_face_nil; |
|
76 - } |
|
77 + if (!font) { |
|
78 + hash_table = _cairo_win32_font_face_hash_table_lock (); |
|
79 + if (unlikely (hash_table == NULL)) { |
|
80 + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); |
|
81 + return (cairo_font_face_t *)&_cairo_font_face_nil; |
|
82 + } |
|
83 |
|
84 - _cairo_win32_font_face_init_key (&key, logfont, font); |
|
85 + _cairo_win32_font_face_init_key (&key, logfont, font); |
|
86 |
|
87 - /* Return existing unscaled font if it exists in the hash table. */ |
|
88 - font_face = _cairo_hash_table_lookup (hash_table, |
|
89 - &key.base.hash_entry); |
|
90 - if (font_face != NULL) { |
|
91 - cairo_font_face_reference (&font_face->base); |
|
92 - goto DONE; |
|
93 + /* Return existing unscaled font if it exists in the hash table. */ |
|
94 + font_face = _cairo_hash_table_lookup (hash_table, |
|
95 + &key.base.hash_entry); |
|
96 + if (font_face != NULL) { |
|
97 + cairo_font_face_reference (&font_face->base); |
|
98 + goto DONE; |
|
99 + } |
|
100 } |
|
101 |
|
102 /* Otherwise create it and insert into hash table. */ |
|
103 font_face = malloc (sizeof (cairo_win32_font_face_t)); |
|
104 if (!font_face) { |
|
105 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); |
|
106 goto FAIL; |
|
107 } |
|
108 |
|
109 _cairo_win32_font_face_init_key (font_face, logfont, font); |
|
110 _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); |
|
111 + assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); |
|
112 |
|
113 - assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); |
|
114 - status = _cairo_hash_table_insert (hash_table, |
|
115 - &font_face->base.hash_entry); |
|
116 - if (unlikely (status)) |
|
117 - goto FAIL; |
|
118 + if (!font) { |
|
119 + status = _cairo_hash_table_insert (hash_table, |
|
120 + &font_face->base.hash_entry); |
|
121 + if (unlikely (status)) |
|
122 + goto FAIL; |
|
123 + } |
|
124 |
|
125 DONE: |
|
126 - _cairo_win32_font_face_hash_table_unlock (); |
|
127 + if (!font) { |
|
128 + _cairo_win32_font_face_hash_table_unlock (); |
|
129 + } |
|
130 |
|
131 return &font_face->base; |
|
132 |
|
133 FAIL: |
|
134 - _cairo_win32_font_face_hash_table_unlock (); |
|
135 + if (!font) { |
|
136 + _cairo_win32_font_face_hash_table_unlock (); |
|
137 + } |
|
138 |
|
139 return (cairo_font_face_t *)&_cairo_font_face_nil; |
|
140 } |
|
141 |
|
142 /** |
|
143 * cairo_win32_font_face_create_for_logfontw: |
|
144 * @logfont: A #LOGFONTW structure specifying the font to use. |
|
145 * The lfHeight, lfWidth, lfOrientation and lfEscapement |