diff options
Diffstat (limited to 'gfx/cairo/06-shared-ft-face.patch')
-rw-r--r-- | gfx/cairo/06-shared-ft-face.patch | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/gfx/cairo/06-shared-ft-face.patch b/gfx/cairo/06-shared-ft-face.patch new file mode 100644 index 0000000000..f98714db18 --- /dev/null +++ b/gfx/cairo/06-shared-ft-face.patch @@ -0,0 +1,384 @@ +diff --git a/gfx/cairo/cairo/src/cairo-ft-font.c b/gfx/cairo/cairo/src/cairo-ft-font.c +--- a/gfx/cairo/cairo/src/cairo-ft-font.c ++++ b/gfx/cairo/cairo/src/cairo-ft-font.c +@@ -101,6 +101,24 @@ + */ + #define MAX_OPEN_FACES 10 + ++extern void mozilla_AddRefSharedFTFace(void* aContext); ++extern void mozilla_ReleaseSharedFTFace(void* aContext, void* aOwner); ++/* Returns true if the face's state has been modified by another owner. */ ++extern int mozilla_LockSharedFTFace(void* aContext, void* aOwner); ++extern void mozilla_UnlockSharedFTFace(void* aContext); ++extern FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags); ++extern void mozilla_LockFTLibrary(FT_Library aLibrary); ++extern void mozilla_UnlockFTLibrary(FT_Library aLibrary); ++ ++#define CAIRO_FT_LOCK(unscaled) \ ++ ((unscaled)->face_context \ ++ ? (void)mozilla_LockSharedFTFace((unscaled)->face_context, NULL) \ ++ : (void)CAIRO_MUTEX_LOCK((unscaled)->mutex)) ++#define CAIRO_FT_UNLOCK(unscaled) \ ++ ((unscaled)->face_context \ ++ ? mozilla_UnlockSharedFTFace((unscaled)->face_context) \ ++ : (void)CAIRO_MUTEX_UNLOCK((unscaled)->mutex)) ++ + /** + * SECTION:cairo-ft + * @Title: FreeType Fonts +@@ -154,6 +172,7 @@ struct _cairo_ft_unscaled_font { + + cairo_bool_t from_face; /* was the FT_Face provided by user? */ + FT_Face face; /* provided or cached face */ ++ void *face_context; + + /* only set if from_face is false */ + char *filename; +@@ -336,7 +355,9 @@ static void + _cairo_hash_table_remove (font_map->hash_table, + &unscaled->base.hash_entry); + +- if (! unscaled->from_face) ++ if (unscaled->from_face) ++ mozilla_ReleaseSharedFTFace (unscaled->face_context, unscaled); ++ else + _font_map_release_face_lock_held (font_map, unscaled); + + _cairo_ft_unscaled_font_fini (unscaled); +@@ -395,7 +416,8 @@ static void + cairo_bool_t from_face, + char *filename, + int id, +- FT_Face face) ++ FT_Face face, ++ void *face_context) + { + unsigned long hash; + +@@ -403,6 +425,7 @@ static void + key->filename = filename; + key->id = id; + key->face = face; ++ key->face_context = face_context; + + hash = _cairo_hash_string (filename); + /* the constants are just arbitrary primes */ +@@ -438,7 +461,8 @@ static cairo_status_t + cairo_bool_t from_face, + const char *filename, + int id, +- FT_Face face) ++ FT_Face face, ++ void *face_context) + { + _cairo_unscaled_font_init (&unscaled->base, + &cairo_ft_unscaled_font_backend); +@@ -447,7 +471,7 @@ static cairo_status_t + + if (from_face) { + unscaled->from_face = TRUE; +- _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face); ++ _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face, face_context); + + + unscaled->have_color = FT_HAS_COLOR (face) != 0; +@@ -474,12 +498,13 @@ static cairo_status_t + + unscaled->from_face = FALSE; + unscaled->face = NULL; ++ unscaled->face_context = NULL; + + filename_copy = strdup (filename); + if (unlikely (filename_copy == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + +- _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL); ++ _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL, NULL); + + unscaled->have_color_set = FALSE; + } +@@ -528,7 +553,8 @@ static int + unscaled_a->from_face == unscaled_b->from_face) + { + if (unscaled_a->from_face) +- return unscaled_a->face == unscaled_b->face; ++ return unscaled_a->face == unscaled_b->face && ++ unscaled_a->face_context == unscaled_b->face_context; + + if (unscaled_a->filename == NULL && unscaled_b->filename == NULL) + return TRUE; +@@ -549,6 +575,7 @@ static cairo_status_t + char *filename, + int id, + FT_Face font_face, ++ void *face_context, + cairo_ft_unscaled_font_t **out) + { + cairo_ft_unscaled_font_t key, *unscaled; +@@ -559,7 +586,7 @@ static cairo_status_t + if (unlikely (font_map == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + +- _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face); ++ _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face, face_context); + + /* Return existing unscaled font if it exists in the hash table. */ + unscaled = _cairo_hash_table_lookup (font_map->hash_table, +@@ -576,7 +603,7 @@ static cairo_status_t + goto UNWIND_FONT_MAP_LOCK; + } + +- status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face); ++ status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face, face_context); + if (unlikely (status)) + goto UNWIND_UNSCALED_MALLOC; + +@@ -586,6 +613,8 @@ static cairo_status_t + if (unlikely (status)) + goto UNWIND_UNSCALED_FONT_INIT; + ++ mozilla_AddRefSharedFTFace (face_context); ++ + DONE: + _cairo_ft_unscaled_font_map_unlock (); + *out = unscaled; +@@ -638,16 +667,17 @@ static cairo_status_t + + DONE: + return _cairo_ft_unscaled_font_create_internal (font_face != NULL, +- filename, id, font_face, ++ filename, id, font_face, NULL, + out); + } + #endif + + static cairo_status_t + _cairo_ft_unscaled_font_create_from_face (FT_Face face, ++ void *face_context, + cairo_ft_unscaled_font_t **out) + { +- return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, face->face_index, face, out); ++ return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, face->face_index, face, face_context, out); + } + + static cairo_bool_t +@@ -675,12 +705,16 @@ static cairo_bool_t + */ + if (unscaled->faces && unscaled->faces->unscaled == NULL) { + assert (unscaled->faces->next == NULL); ++ CAIRO_FT_LOCK (unscaled); + cairo_font_face_destroy (&unscaled->faces->base); ++ CAIRO_FT_UNLOCK (unscaled); + } ++ mozilla_ReleaseSharedFTFace (unscaled->face_context, unscaled); + } else { + _font_map_release_face_lock_held (font_map, unscaled); + } + unscaled->face = NULL; ++ unscaled->face_context = NULL; + + _cairo_ft_unscaled_font_map_unlock (); + +@@ -709,7 +743,13 @@ static cairo_warn FT_Face + FT_Face face = NULL; + FT_Error error; + +- CAIRO_MUTEX_LOCK (unscaled->mutex); ++ if (unscaled->face_context) { ++ if (!mozilla_LockSharedFTFace (unscaled->face_context, unscaled)) { ++ unscaled->have_scale = FALSE; ++ } ++ } else { ++ CAIRO_FT_LOCK (unscaled); ++ } + unscaled->lock_count++; + + if (unscaled->face) +@@ -744,7 +784,7 @@ static cairo_warn FT_Face + if (error) + { + unscaled->lock_count--; +- CAIRO_MUTEX_UNLOCK (unscaled->mutex); ++ CAIRO_FT_UNLOCK (unscaled); + _cairo_error_throw (_ft_to_cairo_error (error)); + return NULL; + } +@@ -769,7 +809,7 @@ static void + + unscaled->lock_count--; + +- CAIRO_MUTEX_UNLOCK (unscaled->mutex); ++ CAIRO_FT_UNLOCK (unscaled); + } + + +@@ -3164,19 +3204,21 @@ static cairo_bool_t + * font_face <------- unscaled + */ + +- if (font_face->unscaled && +- font_face->unscaled->from_face && +- font_face->next == NULL && +- font_face->unscaled->faces == font_face && +- CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) +- { +- _cairo_unscaled_font_destroy (&font_face->unscaled->base); +- font_face->unscaled = NULL; +- +- return FALSE; +- } +- + if (font_face->unscaled) { ++ CAIRO_FT_LOCK (font_face->unscaled); ++ ++ if (font_face->unscaled->from_face && ++ font_face->next == NULL && ++ font_face->unscaled->faces == font_face && ++ CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) ++ { ++ CAIRO_FT_UNLOCK (font_face->unscaled); ++ _cairo_unscaled_font_destroy (&font_face->unscaled->base); ++ font_face->unscaled = NULL; ++ ++ return FALSE; ++ } ++ + cairo_ft_font_face_t *tmp_face = NULL; + cairo_ft_font_face_t *last_face = NULL; + +@@ -3195,6 +3237,7 @@ static cairo_bool_t + last_face = tmp_face; + } + ++ CAIRO_FT_UNLOCK (font_face->unscaled); + _cairo_unscaled_font_destroy (&font_face->unscaled->base); + font_face->unscaled = NULL; + } +@@ -3268,6 +3311,24 @@ static cairo_font_face_t * + return abstract_face; + } + ++static void ++_cairo_ft_font_face_lock (void *abstract_face) ++{ ++ cairo_ft_font_face_t *font_face = abstract_face; ++ if (font_face->unscaled) { ++ CAIRO_FT_LOCK (font_face->unscaled); ++ } ++} ++ ++static void ++_cairo_ft_font_face_unlock (void *abstract_face) ++{ ++ cairo_ft_font_face_t *font_face = abstract_face; ++ if (font_face->unscaled) { ++ CAIRO_FT_UNLOCK (font_face->unscaled); ++ } ++} ++ + const cairo_font_face_backend_t _cairo_ft_font_face_backend = { + CAIRO_FONT_TYPE_FT, + #if CAIRO_HAS_FC_FONT +@@ -3277,7 +3338,11 @@ const cairo_font_face_backend_t _cairo_f + #endif + _cairo_ft_font_face_destroy, + _cairo_ft_font_face_scaled_font_create, +- _cairo_ft_font_face_get_implementation ++ _cairo_ft_font_face_get_implementation, ++/* ++ _cairo_ft_font_face_lock, ++ _cairo_ft_font_face_unlock ++*/ + }; + + #if CAIRO_HAS_FC_FONT +@@ -3320,6 +3385,8 @@ static cairo_font_face_t * + { + cairo_ft_font_face_t *font_face, **prev_font_face; + ++ CAIRO_FT_LOCK (unscaled); ++ + /* Looked for an existing matching font face */ + for (font_face = unscaled->faces, prev_font_face = &unscaled->faces; + font_face; +@@ -3341,15 +3408,19 @@ static cairo_font_face_t * + * from owner to ownee. */ + font_face->unscaled = unscaled; + _cairo_unscaled_font_reference (&unscaled->base); +- return &font_face->base; +- } else +- return cairo_font_face_reference (&font_face->base); ++ } else { ++ cairo_font_face_reference (&font_face->base); ++ } ++ ++ CAIRO_FT_UNLOCK (unscaled); ++ return &font_face->base; + } + } + + /* No match found, create a new one */ + font_face = _cairo_malloc (sizeof (cairo_ft_font_face_t)); + if (unlikely (!font_face)) { ++ CAIRO_FT_UNLOCK (unscaled); + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); + return (cairo_font_face_t *)&_cairo_font_face_nil; + } +@@ -3376,6 +3447,7 @@ static cairo_font_face_t * + + _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend); + ++ CAIRO_FT_UNLOCK (unscaled); + return &font_face->base; + } + +@@ -3737,14 +3809,16 @@ cairo_ft_font_face_create_for_pattern (F + cairo_font_face_t * + cairo_ft_font_face_create_for_ft_face (FT_Face face, + int load_flags, +- unsigned int synth_flags) ++ unsigned int synth_flags, ++ void *face_context) + { + cairo_ft_unscaled_font_t *unscaled; + cairo_font_face_t *font_face; + cairo_ft_options_t ft_options; + cairo_status_t status; + +- status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled); ++ status = _cairo_ft_unscaled_font_create_from_face (face, face_context, ++ &unscaled); + if (unlikely (status)) + return (cairo_font_face_t *)&_cairo_font_face_nil; + +@@ -3896,7 +3970,7 @@ cairo_ft_scaled_font_lock_face (cairo_sc + * opportunity for creating deadlock. This is obviously unsafe, + * but as documented, the user must add manual locking when using + * this function. */ +- CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex); ++ CAIRO_FT_UNLOCK (scaled_font->unscaled); + + return face; + } +@@ -3929,7 +4003,7 @@ cairo_ft_scaled_font_unlock_face (cairo_ + * cairo_ft_scaled_font_lock_face, so we have to acquire it again + * as _cairo_ft_unscaled_font_unlock_face expects it to be held + * when we call into it. */ +- CAIRO_MUTEX_LOCK (scaled_font->unscaled->mutex); ++ CAIRO_FT_LOCK (scaled_font->unscaled); + + _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled); + } +diff --git a/gfx/cairo/cairo/src/cairo-ft.h b/gfx/cairo/cairo/src/cairo-ft.h +--- a/gfx/cairo/cairo/src/cairo-ft.h ++++ b/gfx/cairo/cairo/src/cairo-ft.h +@@ -55,7 +55,8 @@ CAIRO_BEGIN_DECLS + cairo_public cairo_font_face_t * + cairo_ft_font_face_create_for_ft_face (FT_Face face, + int load_flags, +- unsigned int synth_flags); ++ unsigned int synth_flags, ++ void *face_context); + + /** + * cairo_ft_synthesize_t: |