summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/06-shared-ft-face.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/06-shared-ft-face.patch')
-rw-r--r--gfx/cairo/06-shared-ft-face.patch384
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: