summaryrefslogtreecommitdiff
path: root/src/cairo-ft-font.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-ft-font.c')
-rw-r--r--src/cairo-ft-font.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 9a412782..8db223ed 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -152,6 +152,19 @@ static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
CAIRO_MUTEX_DECLARE(cairo_ft_unscaled_font_map_mutex);
static void
+_font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
+ cairo_ft_unscaled_font_t *unscaled)
+{
+ if (unscaled->face) {
+ FT_Done_Face (unscaled->face);
+ unscaled->face = NULL;
+ unscaled->have_scale = FALSE;
+
+ font_map->num_open_faces--;
+ }
+}
+
+static void
_cairo_ft_unscaled_font_map_create (void)
{
cairo_ft_unscaled_font_map_t *font_map;
@@ -210,10 +223,14 @@ _cairo_ft_unscaled_font_map_destroy (void)
break;
_cairo_hash_table_remove (font_map->hash_table,
&unscaled->base.hash_entry);
+
+ _font_map_release_face_lock_held (font_map, unscaled);
_cairo_ft_unscaled_font_fini (unscaled);
free (unscaled);
}
+ assert (font_map->num_open_faces == 0);
+
FT_Done_FreeType (font_map->ft_library);
_cairo_hash_table_destroy (font_map->hash_table);
@@ -315,7 +332,7 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
_cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
}
- unscaled->have_scale = 0;
+ unscaled->have_scale = FALSE;
unscaled->lock = 0;
unscaled->faces = NULL;
@@ -329,18 +346,26 @@ _cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font)
return unscaled_font->backend == &cairo_ft_unscaled_font_backend;
}
+/**
+ * _cairo_ft_unscaled_font_fini:
+ *
+ * Free all data associated with a cairo_ft_unscaled_font_t.
+ *
+ * CAUTION: The unscaled->face field must be NULL before calling this
+ * function. This is because the cairo_ft_unscaled_font_map keeps a
+ * count of these faces (font_map->num_open_faces) so it maintains the
+ * unscaled->face field while it has its lock held. See
+ * _font_map_release_face_lock_held().
+ **/
static void
_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
{
+ assert (unscaled->face == NULL);
+
if (unscaled->filename) {
free (unscaled->filename);
unscaled->filename = NULL;
}
-
- if (unscaled->face) {
- FT_Done_Face (unscaled->face);
- unscaled->face = NULL;
- }
}
static int
@@ -460,9 +485,10 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
_cairo_hash_table_remove (font_map->hash_table,
&unscaled->base.hash_entry);
- _cairo_ft_unscaled_font_map_unlock ();
-
+ _font_map_release_face_lock_held (font_map, unscaled);
_cairo_ft_unscaled_font_fini (unscaled);
+
+ _cairo_ft_unscaled_font_map_unlock ();
}
}
@@ -507,11 +533,7 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
if (entry == NULL)
break;
- FT_Done_Face (entry->face);
- entry->face = NULL;
- entry->have_scale = 0;
-
- font_map->num_open_faces--;
+ _font_map_release_face_lock_held (font_map, entry);
}
if (FT_New_Face (font_map->ft_library,
@@ -593,7 +615,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
scale->yy == unscaled->current_scale.yy)
return;
- unscaled->have_scale = 1;
+ unscaled->have_scale = TRUE;
unscaled->current_scale = *scale;
_compute_transform (&sf, scale);