1 diff --git a/gfx/cairo/cairo/src/cairo-ft-font.c b/gfx/cairo/cairo/src/cairo-ft-font.c
2 --- a/gfx/cairo/cairo/src/cairo-ft-font.c
3 +++ b/gfx/cairo/cairo/src/cairo-ft-font.c
6 #define MAX_OPEN_FACES 10
8 +extern void mozilla_AddRefSharedFTFace(void* aContext);
9 +extern void mozilla_ReleaseSharedFTFace(void* aContext, void* aOwner);
10 +/* Returns true if the face's state has been modified by another owner. */
11 +extern int mozilla_LockSharedFTFace(void* aContext, void* aOwner);
12 +extern void mozilla_UnlockSharedFTFace(void* aContext);
13 +extern FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
14 +extern void mozilla_LockFTLibrary(FT_Library aLibrary);
15 +extern void mozilla_UnlockFTLibrary(FT_Library aLibrary);
17 +#define CAIRO_FT_LOCK(unscaled) \
18 + ((unscaled)->face_context \
19 + ? (void)mozilla_LockSharedFTFace((unscaled)->face_context, NULL) \
20 + : (void)CAIRO_MUTEX_LOCK((unscaled)->mutex))
21 +#define CAIRO_FT_UNLOCK(unscaled) \
22 + ((unscaled)->face_context \
23 + ? mozilla_UnlockSharedFTFace((unscaled)->face_context) \
24 + : (void)CAIRO_MUTEX_UNLOCK((unscaled)->mutex))
28 * @Title: FreeType Fonts
29 @@ -154,6 +172,7 @@ struct _cairo_ft_unscaled_font {
31 cairo_bool_t from_face; /* was the FT_Face provided by user? */
32 FT_Face face; /* provided or cached face */
35 /* only set if from_face is false */
37 @@ -336,7 +355,9 @@ static void
38 _cairo_hash_table_remove (font_map->hash_table,
39 &unscaled->base.hash_entry);
41 - if (! unscaled->from_face)
42 + if (unscaled->from_face)
43 + mozilla_ReleaseSharedFTFace (unscaled->face_context, unscaled);
45 _font_map_release_face_lock_held (font_map, unscaled);
47 _cairo_ft_unscaled_font_fini (unscaled);
48 @@ -395,7 +416,8 @@ static void
49 cairo_bool_t from_face,
58 @@ -403,6 +425,7 @@ static void
59 key->filename = filename;
62 + key->face_context = face_context;
64 hash = _cairo_hash_string (filename);
65 /* the constants are just arbitrary primes */
66 @@ -438,7 +461,8 @@ static cairo_status_t
67 cairo_bool_t from_face,
74 _cairo_unscaled_font_init (&unscaled->base,
75 &cairo_ft_unscaled_font_backend);
76 @@ -447,7 +471,7 @@ static cairo_status_t
79 unscaled->from_face = TRUE;
80 - _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face);
81 + _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face, face_context);
84 unscaled->have_color = FT_HAS_COLOR (face) != 0;
85 @@ -474,12 +498,13 @@ static cairo_status_t
87 unscaled->from_face = FALSE;
88 unscaled->face = NULL;
89 + unscaled->face_context = NULL;
91 filename_copy = strdup (filename);
92 if (unlikely (filename_copy == NULL))
93 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
95 - _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL);
96 + _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL, NULL);
98 unscaled->have_color_set = FALSE;
100 @@ -528,7 +553,8 @@ static int
101 unscaled_a->from_face == unscaled_b->from_face)
103 if (unscaled_a->from_face)
104 - return unscaled_a->face == unscaled_b->face;
105 + return unscaled_a->face == unscaled_b->face &&
106 + unscaled_a->face_context == unscaled_b->face_context;
108 if (unscaled_a->filename == NULL && unscaled_b->filename == NULL)
110 @@ -549,6 +575,7 @@ static cairo_status_t
114 + void *face_context,
115 cairo_ft_unscaled_font_t **out)
117 cairo_ft_unscaled_font_t key, *unscaled;
118 @@ -559,7 +586,7 @@ static cairo_status_t
119 if (unlikely (font_map == NULL))
120 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
122 - _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face);
123 + _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face, face_context);
125 /* Return existing unscaled font if it exists in the hash table. */
126 unscaled = _cairo_hash_table_lookup (font_map->hash_table,
127 @@ -576,7 +603,7 @@ static cairo_status_t
128 goto UNWIND_FONT_MAP_LOCK;
131 - status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face);
132 + status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face, face_context);
133 if (unlikely (status))
134 goto UNWIND_UNSCALED_MALLOC;
136 @@ -586,6 +613,8 @@ static cairo_status_t
137 if (unlikely (status))
138 goto UNWIND_UNSCALED_FONT_INIT;
140 + mozilla_AddRefSharedFTFace (face_context);
143 _cairo_ft_unscaled_font_map_unlock ();
145 @@ -638,16 +667,17 @@ static cairo_status_t
148 return _cairo_ft_unscaled_font_create_internal (font_face != NULL,
149 - filename, id, font_face,
150 + filename, id, font_face, NULL,
155 static cairo_status_t
156 _cairo_ft_unscaled_font_create_from_face (FT_Face face,
157 + void *face_context,
158 cairo_ft_unscaled_font_t **out)
160 - return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, face->face_index, face, out);
161 + return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, face->face_index, face, face_context, out);
165 @@ -675,12 +705,16 @@ static cairo_bool_t
167 if (unscaled->faces && unscaled->faces->unscaled == NULL) {
168 assert (unscaled->faces->next == NULL);
169 + CAIRO_FT_LOCK (unscaled);
170 cairo_font_face_destroy (&unscaled->faces->base);
171 + CAIRO_FT_UNLOCK (unscaled);
173 + mozilla_ReleaseSharedFTFace (unscaled->face_context, unscaled);
175 _font_map_release_face_lock_held (font_map, unscaled);
177 unscaled->face = NULL;
178 + unscaled->face_context = NULL;
180 _cairo_ft_unscaled_font_map_unlock ();
182 @@ -709,7 +743,13 @@ static cairo_warn FT_Face
186 - CAIRO_MUTEX_LOCK (unscaled->mutex);
187 + if (unscaled->face_context) {
188 + if (!mozilla_LockSharedFTFace (unscaled->face_context, unscaled)) {
189 + unscaled->have_scale = FALSE;
192 + CAIRO_FT_LOCK (unscaled);
194 unscaled->lock_count++;
197 @@ -744,7 +784,7 @@ static cairo_warn FT_Face
200 unscaled->lock_count--;
201 - CAIRO_MUTEX_UNLOCK (unscaled->mutex);
202 + CAIRO_FT_UNLOCK (unscaled);
203 _cairo_error_throw (_ft_to_cairo_error (error));
206 @@ -769,7 +809,7 @@ static void
208 unscaled->lock_count--;
210 - CAIRO_MUTEX_UNLOCK (unscaled->mutex);
211 + CAIRO_FT_UNLOCK (unscaled);
215 @@ -3164,19 +3204,21 @@ static cairo_bool_t
216 * font_face <------- unscaled
219 - if (font_face->unscaled &&
220 - font_face->unscaled->from_face &&
221 - font_face->next == NULL &&
222 - font_face->unscaled->faces == font_face &&
223 - CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
225 - _cairo_unscaled_font_destroy (&font_face->unscaled->base);
226 - font_face->unscaled = NULL;
231 if (font_face->unscaled) {
232 + CAIRO_FT_LOCK (font_face->unscaled);
234 + if (font_face->unscaled->from_face &&
235 + font_face->next == NULL &&
236 + font_face->unscaled->faces == font_face &&
237 + CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
239 + CAIRO_FT_UNLOCK (font_face->unscaled);
240 + _cairo_unscaled_font_destroy (&font_face->unscaled->base);
241 + font_face->unscaled = NULL;
246 cairo_ft_font_face_t *tmp_face = NULL;
247 cairo_ft_font_face_t *last_face = NULL;
249 @@ -3195,6 +3237,7 @@ static cairo_bool_t
250 last_face = tmp_face;
253 + CAIRO_FT_UNLOCK (font_face->unscaled);
254 _cairo_unscaled_font_destroy (&font_face->unscaled->base);
255 font_face->unscaled = NULL;
257 @@ -3268,6 +3311,24 @@ static cairo_font_face_t *
258 return abstract_face;
262 +_cairo_ft_font_face_lock (void *abstract_face)
264 + cairo_ft_font_face_t *font_face = abstract_face;
265 + if (font_face->unscaled) {
266 + CAIRO_FT_LOCK (font_face->unscaled);
271 +_cairo_ft_font_face_unlock (void *abstract_face)
273 + cairo_ft_font_face_t *font_face = abstract_face;
274 + if (font_face->unscaled) {
275 + CAIRO_FT_UNLOCK (font_face->unscaled);
279 const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
281 #if CAIRO_HAS_FC_FONT
282 @@ -3277,7 +3338,11 @@ const cairo_font_face_backend_t _cairo_f
284 _cairo_ft_font_face_destroy,
285 _cairo_ft_font_face_scaled_font_create,
286 - _cairo_ft_font_face_get_implementation
287 + _cairo_ft_font_face_get_implementation,
289 + _cairo_ft_font_face_lock,
290 + _cairo_ft_font_face_unlock
294 #if CAIRO_HAS_FC_FONT
295 @@ -3320,6 +3385,8 @@ static cairo_font_face_t *
297 cairo_ft_font_face_t *font_face, **prev_font_face;
299 + CAIRO_FT_LOCK (unscaled);
301 /* Looked for an existing matching font face */
302 for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
304 @@ -3341,15 +3408,19 @@ static cairo_font_face_t *
305 * from owner to ownee. */
306 font_face->unscaled = unscaled;
307 _cairo_unscaled_font_reference (&unscaled->base);
308 - return &font_face->base;
310 - return cairo_font_face_reference (&font_face->base);
312 + cairo_font_face_reference (&font_face->base);
315 + CAIRO_FT_UNLOCK (unscaled);
316 + return &font_face->base;
320 /* No match found, create a new one */
321 font_face = _cairo_malloc (sizeof (cairo_ft_font_face_t));
322 if (unlikely (!font_face)) {
323 + CAIRO_FT_UNLOCK (unscaled);
324 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
325 return (cairo_font_face_t *)&_cairo_font_face_nil;
327 @@ -3376,6 +3447,7 @@ static cairo_font_face_t *
329 _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
331 + CAIRO_FT_UNLOCK (unscaled);
332 return &font_face->base;
335 @@ -3737,14 +3809,16 @@ cairo_ft_font_face_create_for_pattern (F
337 cairo_ft_font_face_create_for_ft_face (FT_Face face,
339 - unsigned int synth_flags)
340 + unsigned int synth_flags,
341 + void *face_context)
343 cairo_ft_unscaled_font_t *unscaled;
344 cairo_font_face_t *font_face;
345 cairo_ft_options_t ft_options;
346 cairo_status_t status;
348 - status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled);
349 + status = _cairo_ft_unscaled_font_create_from_face (face, face_context,
351 if (unlikely (status))
352 return (cairo_font_face_t *)&_cairo_font_face_nil;
354 @@ -3896,7 +3970,7 @@ cairo_ft_scaled_font_lock_face (cairo_sc
355 * opportunity for creating deadlock. This is obviously unsafe,
356 * but as documented, the user must add manual locking when using
358 - CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex);
359 + CAIRO_FT_UNLOCK (scaled_font->unscaled);
363 @@ -3929,7 +4003,7 @@ cairo_ft_scaled_font_unlock_face (cairo_
364 * cairo_ft_scaled_font_lock_face, so we have to acquire it again
365 * as _cairo_ft_unscaled_font_unlock_face expects it to be held
366 * when we call into it. */
367 - CAIRO_MUTEX_LOCK (scaled_font->unscaled->mutex);
368 + CAIRO_FT_LOCK (scaled_font->unscaled);
370 _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
372 diff --git a/gfx/cairo/cairo/src/cairo-ft.h b/gfx/cairo/cairo/src/cairo-ft.h
373 --- a/gfx/cairo/cairo/src/cairo-ft.h
374 +++ b/gfx/cairo/cairo/src/cairo-ft.h
375 @@ -55,7 +55,8 @@ CAIRO_BEGIN_DECLS
376 cairo_public cairo_font_face_t *
377 cairo_ft_font_face_create_for_ft_face (FT_Face face,
379 - unsigned int synth_flags);
380 + unsigned int synth_flags,
381 + void *face_context);
384 * cairo_ft_synthesize_t: