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.c951
1 files changed, 547 insertions, 404 deletions
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index afe80df..e1bcdd7 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -76,31 +76,31 @@
* factors so that hinting works right
*/
-typedef struct {
+typedef struct _cairo_ft_font_transform {
double x_scale, y_scale;
double shape[2][2];
-} ft_font_transform_t;
+} cairo_ft_font_transform_t;
/*
* We create an object that corresponds to a single font on the disk;
* (identified by a filename/id pair) these are shared between all
- * fonts using that file. For cairo_ft_scaled_font_create_for_ft_face(), we
+ * fonts using that file. For cairo_ft_font_face_create_for_ft_face(), we
* just create a one-off version with a permanent face value.
*/
-typedef struct _ft_font_face ft_font_face_t;
+typedef struct _cairo_ft_font_face cairo_ft_font_face_t;
-typedef struct {
+struct _cairo_ft_unscaled_font {
cairo_unscaled_font_t base;
- cairo_bool_t from_face; /* from cairo_ft_scaled_font_create_for_ft_face()? */
+ cairo_bool_t from_face; /* from cairo_ft_font_face_create_for_ft_face()? */
FT_Face face; /* provided or cached face */
/* only set if from_face is false */
char *filename;
int id;
- /* We temporarily scale the unscaled font as neede */
+ /* We temporarily scale the unscaled font as needed */
cairo_bool_t have_scale;
cairo_matrix_t current_scale;
double x_scale; /* Extracted X scale factor */
@@ -109,286 +109,377 @@ typedef struct {
int lock; /* count of how many times this font has been locked */
- ft_font_face_t *faces; /* Linked list of faces for this font */
-} ft_unscaled_font_t;
+ cairo_ft_font_face_t *faces; /* Linked list of faces for this font */
+};
+
+static int
+_cairo_ft_unscaled_font_keys_equal (void *key_a,
+ void *key_b);
+
+static void
+_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
-struct _ft_font_face {
+struct _cairo_ft_font_face {
cairo_font_face_t base;
- ft_unscaled_font_t *unscaled;
+ cairo_ft_unscaled_font_t *unscaled;
int load_flags;
- ft_font_face_t *next_face;
+ cairo_ft_font_face_t *next;
};
const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend;
-static ft_unscaled_font_t *
-_ft_unscaled_font_create_from_face (FT_Face face)
-{
- ft_unscaled_font_t *unscaled = malloc (sizeof(ft_unscaled_font_t));
- if (!unscaled)
- return NULL;
-
- unscaled->from_face = 1;
- unscaled->face = face;
+/*
+ * We maintain a hash table to map file/id => cairo_ft_unscaled_font_t.
+ * The hash table itself isn't limited in size. However, we limit the
+ * number of FT_Face objects we keep around; when we've exceeeded that
+ * limit and need to create a new FT_Face, we dump the FT_Face from a
+ * random cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
+ * there are any).
+ */
- unscaled->filename = NULL;
- unscaled->id = 0;
-
- unscaled->have_scale = 0;
- unscaled->lock = 0;
+typedef struct _cairo_ft_unscaled_font_map {
+ cairo_hash_table_t *hash_table;
+ FT_Library ft_library;
+ int num_open_faces;
+} cairo_ft_unscaled_font_map_t;
- unscaled->faces = NULL;
+static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
- _cairo_unscaled_font_init (&unscaled->base,
- &cairo_ft_unscaled_font_backend);
- return unscaled;
-}
+CAIRO_MUTEX_DECLARE(cairo_ft_unscaled_font_map_mutex);
-cairo_bool_t
-_cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font)
+static void
+_cairo_ft_unscaled_font_map_create (void)
{
- return unscaled_font->backend == &cairo_ft_unscaled_font_backend;
-}
+ cairo_ft_unscaled_font_map_t *font_map;
-static ft_unscaled_font_t *
-_ft_unscaled_font_create_from_filename (const char *filename,
- int id)
-{
- ft_unscaled_font_t *unscaled;
- char *new_filename;
-
- new_filename = strdup (filename);
- if (!new_filename)
- return NULL;
+ /* This function is only intended to be called from
+ * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
+ * detect some other call path. */
+ assert (cairo_ft_unscaled_font_map == NULL);
- unscaled = malloc (sizeof (ft_unscaled_font_t));
- if (!unscaled) {
- free (new_filename);
- return NULL;
- }
-
- unscaled->from_face = 0;
- unscaled->face = NULL;
+ font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
+ if (font_map == NULL)
+ goto FAIL;
- unscaled->filename = new_filename;
- unscaled->id = id;
-
- unscaled->have_scale = 0;
- unscaled->lock = 0;
-
- unscaled->faces = NULL;
+ font_map->hash_table =
+ _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal);
- _cairo_unscaled_font_init (&unscaled->base,
- &cairo_ft_unscaled_font_backend);
- return unscaled;
-}
+ if (font_map->hash_table == NULL)
+ goto FAIL;
-/*
- * We keep a global cache from [file/id] => [ft_unscaled_font_t]. This
- * hash isn't limited in size. However, we limit the number of
- * FT_Face objects we keep around; when we've exceeeded that
- * limit and need to create a new FT_Face, we dump the FT_Face from
- * a random ft_unscaled_font_t.
- */
+ if (FT_Init_FreeType (&font_map->ft_library))
+ goto FAIL;
-typedef struct {
- cairo_cache_entry_base_t base;
- char *filename;
- int id;
-} cairo_ft_cache_key_t;
+ font_map->num_open_faces = 0;
-typedef struct {
- cairo_ft_cache_key_t key;
- ft_unscaled_font_t *unscaled;
-} cairo_ft_cache_entry_t;
+ cairo_ft_unscaled_font_map = font_map;
+ return;
-typedef struct {
- cairo_cache_t base;
- FT_Library lib;
- int n_faces; /* Number of open FT_Face objects */
-} ft_cache_t;
+FAIL:
+ if (font_map) {
+ if (font_map->hash_table)
+ _cairo_hash_table_destroy (font_map->hash_table);
+ free (font_map);
+ }
+ cairo_ft_unscaled_font_map = NULL;
+}
-static unsigned long
-_ft_font_cache_hash (void *cache, void *key)
+static void
+_cairo_ft_unscaled_font_map_destroy (void)
{
- cairo_ft_cache_key_t *in = (cairo_ft_cache_key_t *) key;
- unsigned long hash;
+ cairo_ft_unscaled_font_t *unscaled;
+ cairo_ft_unscaled_font_map_t *font_map;
+
+ CAIRO_MUTEX_LOCK (cairo_ft_unscaled_font_map_mutex);
+
+ if (cairo_ft_unscaled_font_map) {
+ font_map = cairo_ft_unscaled_font_map;
+
+ /* This is rather inefficient, but destroying the hash table
+ * is something we only do during debugging, (during
+ * cairo_debug_reset_static_data), when efficiency is not
+ * relevant. */
+ while (1) {
+ unscaled = _cairo_hash_table_random_entry (font_map->hash_table,
+ NULL);
+ if (unscaled == NULL)
+ break;
+ _cairo_hash_table_remove (font_map->hash_table,
+ &unscaled->base.hash_entry);
+ _cairo_ft_unscaled_font_fini (unscaled);
+ free (unscaled);
+ }
- /* 1607 is just a random prime. */
- hash = _cairo_hash_string (in->filename);
- hash += ((unsigned long) in->id) * 1607;
-
- return hash;
-}
+ FT_Done_FreeType (font_map->ft_library);
-static int
-_ft_font_cache_keys_equal (void *cache,
- void *k1,
- void *k2)
-{
- cairo_ft_cache_key_t *a;
- cairo_ft_cache_key_t *b;
- a = (cairo_ft_cache_key_t *) k1;
- b = (cairo_ft_cache_key_t *) k2;
+ _cairo_hash_table_destroy (font_map->hash_table);
+
+ free (font_map);
- return strcmp (a->filename, b->filename) == 0 &&
- a->id == b->id;
+ cairo_ft_unscaled_font_map = NULL;
+ }
+
+ CAIRO_MUTEX_UNLOCK (cairo_ft_unscaled_font_map_mutex);
}
-static cairo_status_t
-_ft_font_cache_create_entry (void *cache,
- void *key,
- void **return_entry)
+static cairo_ft_unscaled_font_map_t *
+_cairo_ft_unscaled_font_map_lock (void)
{
- cairo_ft_cache_key_t *k = key;
- cairo_ft_cache_entry_t *entry;
+ CAIRO_MUTEX_LOCK (cairo_ft_unscaled_font_map_mutex);
- entry = malloc (sizeof (cairo_ft_cache_entry_t));
- if (entry == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ if (cairo_ft_unscaled_font_map == NULL)
+ {
+ _cairo_ft_unscaled_font_map_create ();
- entry->unscaled = _ft_unscaled_font_create_from_filename (k->filename,
- k->id);
- if (!entry->unscaled) {
- free (entry);
- return CAIRO_STATUS_NO_MEMORY;
+ if (cairo_ft_unscaled_font_map == NULL) {
+ CAIRO_MUTEX_UNLOCK (cairo_ft_unscaled_font_map_mutex);
+ return NULL;
+ }
}
-
- entry->key.base.memory = 0;
- entry->key.filename = entry->unscaled->filename;
- entry->key.id = entry->unscaled->id;
-
- *return_entry = entry;
- return CAIRO_STATUS_SUCCESS;
+ return cairo_ft_unscaled_font_map;
}
-/* Entries are never spontaneously destroyed; but only when
- * we remove them from the cache specifically. We free entry->unscaled
- * in the code that removes the entry from the cache
- */
static void
-_ft_font_cache_destroy_entry (void *cache,
- void *entry)
-{
- cairo_ft_cache_entry_t *e = (cairo_ft_cache_entry_t *) entry;
-
- free (e);
+_cairo_ft_unscaled_font_map_unlock (void)
+{
+ CAIRO_MUTEX_UNLOCK (cairo_ft_unscaled_font_map_mutex);
}
-static void
-_ft_font_cache_destroy_cache (void *cache)
+static void
+_cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t *key,
+ char *filename,
+ int id)
{
- ft_cache_t *fc = (ft_cache_t *) cache;
+ unsigned long hash;
- FT_Done_FreeType (fc->lib);
- free (fc);
+ key->filename = filename;
+ key->id = id;
+
+ /* 1607 is just an arbitrary prime. */
+ hash = _cairo_hash_string (filename);
+ hash += ((unsigned long) id) * 1607;
+
+ key->base.hash_entry.hash = hash;
}
-static const cairo_cache_backend_t _ft_font_cache_backend = {
- _ft_font_cache_hash,
- _ft_font_cache_keys_equal,
- _ft_font_cache_create_entry,
- _ft_font_cache_destroy_entry,
- _ft_font_cache_destroy_cache
-};
+/**
+ * _cairo_ft_unscaled_font_init:
+ *
+ * Initialize a cairo_ft_unscaled_font_t.
+ *
+ * There are two basic flavors of cairo_ft_unscaled_font_t, one
+ * created from an FT_Face and the other created from a filename/id
+ * pair. These two flavors are identified as from_face and !from_face.
+ *
+ * To initialize a from_face font, pass filename==NULL, id=0 and the
+ * desired face.
+ *
+ * To initialize a !from_face font, pass the filename/id as desired
+ * and face==NULL.
+ *
+ * Note that the code handles these two flavors in very distinct
+ * ways. For example there is a hash_table mapping
+ * filename/id->cairo_unscaled_font_t in the !from_face case, but no
+ * parallel in the from_face case, (where the calling code would have
+ * to do its own mapping to ensure similar sharing).
+ **/
+static cairo_status_t
+_cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
+ const char *filename,
+ int id,
+ FT_Face face)
+{
+ char *filename_copy = NULL;
-static ft_cache_t *_global_ft_cache = NULL;
+ if (filename) {
+ filename_copy = strdup (filename);
+ if (filename_copy == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+ }
-CAIRO_MUTEX_DECLARE(_global_ft_cache_mutex);
+ _cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
-static void
-_lock_global_ft_cache (void)
+ if (face) {
+ unscaled->from_face = 1;
+ unscaled->face = face;
+ } else {
+ unscaled->from_face = 0;
+ unscaled->face = NULL;
+ }
+
+ unscaled->have_scale = 0;
+ unscaled->lock = 0;
+
+ unscaled->faces = NULL;
+
+ _cairo_unscaled_font_init (&unscaled->base,
+ &cairo_ft_unscaled_font_backend);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_bool_t
+_cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font)
{
- CAIRO_MUTEX_LOCK(_global_ft_cache_mutex);
+ return unscaled_font->backend == &cairo_ft_unscaled_font_backend;
}
static void
-_unlock_global_ft_cache (void)
+_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
{
- CAIRO_MUTEX_UNLOCK(_global_ft_cache_mutex);
+ if (unscaled->filename) {
+ free (unscaled->filename);
+ unscaled->filename = NULL;
+ }
+
+ if (unscaled->face) {
+ FT_Done_Face (unscaled->face);
+ unscaled->face = NULL;
+ }
}
-static cairo_cache_t *
-_get_global_ft_cache (void)
+static int
+_cairo_ft_unscaled_font_keys_equal (void *key_a,
+ void *key_b)
{
- if (_global_ft_cache == NULL)
- {
- _global_ft_cache = malloc (sizeof(ft_cache_t));
- if (!_global_ft_cache)
- goto FAIL;
-
- if (_cairo_cache_init (&_global_ft_cache->base,
- &_ft_font_cache_backend,
- 0)) /* No memory limit */
- goto FAIL;
-
- if (FT_Init_FreeType (&_global_ft_cache->lib))
- goto FAIL;
- _global_ft_cache->n_faces = 0;
- }
- return &_global_ft_cache->base;
+ cairo_ft_unscaled_font_t *unscaled_a = key_a;
+ cairo_ft_unscaled_font_t *unscaled_b = key_b;
- FAIL:
- if (_global_ft_cache)
- free (_global_ft_cache);
- _global_ft_cache = NULL;
- return NULL;
+ return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0 &&
+ unscaled_a->id == unscaled_b->id);
}
-/* Finds or creates a ft_unscaled_font for the filename/id from pattern.
- * Returns a new reference to the unscaled font.
+/* Finds or creates a cairo_ft_unscaled_font for the filename/id from
+ * pattern. Returns a new reference to the unscaled font.
*/
-static ft_unscaled_font_t *
-_ft_unscaled_font_get_for_pattern (FcPattern *pattern)
+static cairo_ft_unscaled_font_t *
+_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
{
- cairo_ft_cache_entry_t *entry;
- cairo_ft_cache_key_t key;
- cairo_cache_t *cache;
+ cairo_ft_unscaled_font_t key, *unscaled;
+ cairo_ft_unscaled_font_map_t *font_map;
cairo_status_t status;
- FcChar8 *filename;
- int created_entry;
+ FcChar8 *fc_filename;
+ char *filename;
+ int id;
- if (FcPatternGetString (pattern, FC_FILE, 0, &filename) != FcResultMatch)
- return NULL;
- key.filename = (char *)filename;
-
- if (FcPatternGetInteger (pattern, FC_INDEX, 0, &key.id) != FcResultMatch)
- return NULL;
+ if (FcPatternGetString (pattern, FC_FILE, 0, &fc_filename) != FcResultMatch)
+ goto UNWIND;
+ filename = (char *) fc_filename;
+
+ if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch)
+ goto UNWIND;
- _lock_global_ft_cache ();
- cache = _get_global_ft_cache ();
- if (cache == NULL) {
- _unlock_global_ft_cache ();
- return NULL;
+ font_map = _cairo_ft_unscaled_font_map_lock ();
+ if (font_map == NULL)
+ goto UNWIND;
+
+ _cairo_ft_unscaled_font_init_key (&key, filename, id);
+
+ /* Return exsiting unscaled font if it exists in the hash table. */
+ if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry,
+ (cairo_hash_entry_t **) &unscaled))
+ {
+ _cairo_ft_unscaled_font_map_unlock ();
+ _cairo_unscaled_font_reference (&unscaled->base);
+ return unscaled;
}
- status = _cairo_cache_lookup (cache, &key, (void **) &entry, &created_entry);
- if (status == CAIRO_STATUS_SUCCESS && !created_entry)
- _cairo_unscaled_font_reference (&entry->unscaled->base);
+ /* Otherwise create it and insert into hash table. */
+ unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
+ if (unscaled == NULL)
+ goto UNWIND_FONT_MAP_LOCK;
+
+ status = _cairo_ft_unscaled_font_init (unscaled, filename, id, NULL);
+ if (status)
+ goto UNWIND_UNSCALED_MALLOC;
- _unlock_global_ft_cache ();
+ status = _cairo_hash_table_insert (font_map->hash_table,
+ &unscaled->base.hash_entry);
if (status)
+ goto UNWIND_UNSCALED_FONT_INIT;
+
+ _cairo_ft_unscaled_font_map_unlock ();
+
+ return unscaled;
+
+UNWIND_UNSCALED_FONT_INIT:
+ _cairo_ft_unscaled_font_fini (unscaled);
+UNWIND_UNSCALED_MALLOC:
+ free (unscaled);
+UNWIND_FONT_MAP_LOCK:
+ _cairo_ft_unscaled_font_map_unlock ();
+UNWIND:
+ return NULL;
+}
+
+static cairo_ft_unscaled_font_t *
+_cairo_ft_unscaled_font_create_from_face (FT_Face face)
+{
+ cairo_status_t status;
+ cairo_ft_unscaled_font_t *unscaled;
+
+ unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
+ if (unscaled == NULL)
return NULL;
- return entry->unscaled;
+ status = _cairo_ft_unscaled_font_init (unscaled, NULL, 0, face);
+ if (status) {
+ free (unscaled);
+ return NULL;
+ }
+
+ return unscaled;
}
-static int
+static void
+_cairo_ft_unscaled_font_destroy (void *abstract_font)
+{
+ cairo_ft_unscaled_font_t *unscaled = abstract_font;
+
+ if (unscaled == NULL)
+ return;
+
+ if (unscaled->from_face) {
+ /* See comments in _ft_font_face_destroy about the "zombie" state
+ * for a _ft_font_face.
+ */
+ if (unscaled->faces && !unscaled->faces->unscaled)
+ cairo_font_face_destroy (&unscaled->faces->base);
+ } else {
+ cairo_ft_unscaled_font_map_t *font_map;
+
+ font_map = _cairo_ft_unscaled_font_map_lock ();
+ /* All created objects must have been mapped in the font map. */
+ assert (font_map != NULL);
+
+ _cairo_hash_table_remove (font_map->hash_table,
+ &unscaled->base.hash_entry);
+
+ _cairo_ft_unscaled_font_map_unlock ();
+
+ _cairo_ft_unscaled_font_fini (unscaled);
+ }
+}
+
+static cairo_bool_t
_has_unlocked_face (void *entry)
{
- cairo_ft_cache_entry_t *e = entry;
+ cairo_ft_unscaled_font_t *unscaled = entry;
- return (e->unscaled->lock == 0 && e->unscaled->face);
+ return (unscaled->lock == 0 && unscaled->face);
}
/* Ensures that an unscaled font has a face object. If we exceed
* MAX_OPEN_FACES, try to close some.
+ *
+ * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
+ * set the scale on the face, but just returns it at the last scale.
*/
-static FT_Face
-_ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled)
+FT_Face
+_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
{
- ft_cache_t *ftcache;
+ cairo_ft_unscaled_font_map_t *font_map;
FT_Face face = NULL;
if (unscaled->face) {
@@ -396,27 +487,30 @@ _ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled)
return unscaled->face;
}
+ /* If this unscaled font was created from an FT_Face then we just
+ * returned it above. */
assert (!unscaled->from_face);
- _lock_global_ft_cache ();
- ftcache = (ft_cache_t *) _get_global_ft_cache ();
- assert (ftcache != NULL);
+ font_map = _cairo_ft_unscaled_font_map_lock ();
+ assert (font_map != NULL);
- while (ftcache->n_faces >= MAX_OPEN_FACES) {
- cairo_ft_cache_entry_t *entry;
+ while (font_map->num_open_faces >= MAX_OPEN_FACES)
+ {
+ cairo_ft_unscaled_font_t *entry;
- entry = _cairo_cache_random_entry ((cairo_cache_t *)ftcache, _has_unlocked_face);
- if (entry) {
- FT_Done_Face (entry->unscaled->face);
- entry->unscaled->face = NULL;
- entry->unscaled->have_scale = 0;
- ftcache->n_faces--;
- } else {
+ entry = _cairo_hash_table_random_entry (font_map->hash_table,
+ _has_unlocked_face);
+ if (entry == NULL)
break;
- }
+
+ FT_Done_Face (entry->face);
+ unscaled->face = NULL;
+ unscaled->have_scale = 0;
+
+ font_map->num_open_faces--;
}
- if (FT_New_Face (ftcache->lib,
+ if (FT_New_Face (font_map->ft_library,
unscaled->filename,
unscaled->id,
&face) != FT_Err_Ok)
@@ -424,17 +518,19 @@ _ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled)
unscaled->face = face;
unscaled->lock++;
- ftcache->n_faces++;
+
+ font_map->num_open_faces++;
FAIL:
- _unlock_global_ft_cache ();
+ _cairo_ft_unscaled_font_map_unlock ();
+
return face;
}
-/* Unlock unscaled font locked with _ft_unscaled_font_lock_face
+/* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
*/
-static void
-_ft_unscaled_font_unlock_face (ft_unscaled_font_t *unscaled)
+void
+_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
{
assert (unscaled->lock > 0);
@@ -442,7 +538,7 @@ _ft_unscaled_font_unlock_face (ft_unscaled_font_t *unscaled)
}
static void
-_compute_transform (ft_font_transform_t *sf,
+_compute_transform (cairo_ft_font_transform_t *sf,
cairo_matrix_t *scale)
{
cairo_matrix_t normalized = *scale;
@@ -476,10 +572,10 @@ _compute_transform (ft_font_transform_t *sf,
* scaling to the same size, since changing a FT_Face is expensive.
*/
static void
-_ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled,
- cairo_matrix_t *scale)
+_cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
+ cairo_matrix_t *scale)
{
- ft_font_transform_t sf;
+ cairo_ft_font_transform_t sf;
FT_Matrix mat;
FT_UInt pixel_width, pixel_height;
FT_Error error;
@@ -528,7 +624,11 @@ _ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled,
pixel_width = pixel_height = 0;
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
+#if HAVE_FT_BITMAP_SIZE_Y_PPEM
double size = unscaled->face->available_sizes[i].y_ppem / 64.;
+#else
+ double size = unscaled->face->available_sizes[i].height;
+#endif
double distance = fabs (size - sf.y_scale);
if (distance <= min_distance) {
@@ -536,11 +636,13 @@ _ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled,
best_i = i;
}
}
+#if HAVE_FT_BITMAP_SIZE_Y_PPEM
error = FT_Set_Char_Size (unscaled->face,
unscaled->face->available_sizes[best_i].x_ppem,
unscaled->face->available_sizes[best_i].y_ppem,
0, 0);
- if (error )
+ if (error)
+#endif
error = FT_Set_Pixel_Sizes (unscaled->face,
unscaled->face->available_sizes[best_i].width,
unscaled->face->available_sizes[best_i].height);
@@ -549,43 +651,6 @@ _ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled,
assert (error == 0);
}
-static void
-_cairo_ft_unscaled_font_destroy (void *abstract_font)
-{
- ft_unscaled_font_t *unscaled = abstract_font;
-
- if (unscaled == NULL)
- return;
-
- if (unscaled->from_face) {
- /* See comments in _ft_font_face_destroy about the "zombie" state
- * for a _ft_font_face.
- */
- if (unscaled->faces && !unscaled->faces->unscaled)
- cairo_font_face_destroy (&unscaled->faces->base);
- } else {
- cairo_cache_t *cache;
- cairo_ft_cache_key_t key;
-
- _lock_global_ft_cache ();
- cache = _get_global_ft_cache ();
- assert (cache);
-
- key.filename = unscaled->filename;
- key.id = unscaled->id;
-
- _cairo_cache_remove (cache, &key);
-
- _unlock_global_ft_cache ();
-
- if (unscaled->filename)
- free (unscaled->filename);
-
- if (unscaled->face)
- FT_Done_Face (unscaled->face);
- }
-}
-
/* Empirically-derived subpixel filtering values thanks to Keith
* Packard and libXft. */
static const int filters[3][3] = {
@@ -990,7 +1055,7 @@ _render_glyph_bitmap (FT_Face face,
static cairo_status_t
_transform_glyph_bitmap (cairo_image_glyph_cache_entry_t *val)
{
- ft_font_transform_t sf;
+ cairo_ft_font_transform_t sf;
cairo_matrix_t original_to_transformed;
cairo_matrix_t transformed_to_original;
cairo_image_surface_t *old_image;
@@ -1110,21 +1175,21 @@ static cairo_status_t
_cairo_ft_unscaled_font_create_glyph (void *abstract_font,
cairo_image_glyph_cache_entry_t *val)
{
- ft_unscaled_font_t *unscaled = abstract_font;
+ cairo_ft_unscaled_font_t *unscaled = abstract_font;
FT_GlyphSlot glyphslot;
FT_Face face;
FT_Glyph_Metrics *metrics;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
double x_factor, y_factor;
- face = _ft_unscaled_font_lock_face (unscaled);
+ face = _cairo_ft_unscaled_font_lock_face (unscaled);
if (!face)
return CAIRO_STATUS_NO_MEMORY;
glyphslot = face->glyph;
metrics = &glyphslot->metrics;
- _ft_unscaled_font_set_scale (unscaled, &val->key.scale);
+ _cairo_ft_unscaled_font_set_scale (unscaled, &val->key.scale);
if (FT_Load_Glyph (face, val->key.index, val->key.flags & ~PRIVATE_FLAGS_MASK) != 0) {
status = CAIRO_STATUS_NO_MEMORY;
@@ -1203,7 +1268,7 @@ _cairo_ft_unscaled_font_create_glyph (void *abstract_
val->image = NULL;
}
- _ft_unscaled_font_unlock_face (unscaled);
+ _cairo_ft_unscaled_font_unlock_face (unscaled);
return status;
}
@@ -1215,11 +1280,10 @@ const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
/* cairo_ft_scaled_font_t */
-typedef struct {
+typedef struct _cairo_ft_scaled_font {
cairo_scaled_font_t base;
+ cairo_ft_unscaled_font_t *unscaled;
int load_flags;
- cairo_font_options_t options;
- ft_unscaled_font_t *unscaled;
} cairo_ft_scaled_font_t;
const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;
@@ -1370,31 +1434,33 @@ _get_options_load_flags (const cairo_font_options_t *options)
}
static cairo_scaled_font_t *
-_ft_scaled_font_create (ft_unscaled_font_t *unscaled,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- int load_flags)
+_cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
+ cairo_font_face_t *font_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ int load_flags)
{
- cairo_ft_scaled_font_t *f = NULL;
+ cairo_ft_scaled_font_t *scaled_font = NULL;
- f = malloc (sizeof(cairo_ft_scaled_font_t));
- if (f == NULL)
+ scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
+ if (scaled_font == NULL)
return NULL;
- f->unscaled = unscaled;
+ _cairo_scaled_font_init (&scaled_font->base,
+ font_face,
+ font_matrix, ctm, options,
+ &cairo_ft_scaled_font_backend);
+
_cairo_unscaled_font_reference (&unscaled->base);
-
- f->options = *options;
+ scaled_font->unscaled = unscaled;
if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
load_flags |= PRIVATE_FLAG_HINT_METRICS;
- f->load_flags = load_flags;
-
- _cairo_scaled_font_init (&f->base, font_matrix, ctm, &cairo_ft_scaled_font_backend);
+ scaled_font->load_flags = load_flags;
- return (cairo_scaled_font_t *)f;
+ return &scaled_font->base;
}
cairo_bool_t
@@ -1404,28 +1470,28 @@ _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font)
}
static cairo_status_t
-_cairo_ft_scaled_font_create (const char *family,
- cairo_font_slant_t slant,
- cairo_font_weight_t weight,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- cairo_scaled_font_t **font)
+_cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_scaled_font_t **font)
{
FcPattern *pattern, *resolved;
- ft_unscaled_font_t *unscaled;
- cairo_scaled_font_t *new_font;
+ cairo_ft_unscaled_font_t *unscaled;
+ cairo_scaled_font_t *new_font = NULL;
FcResult result;
int fcslant;
int fcweight;
cairo_matrix_t scale;
- ft_font_transform_t sf;
+ cairo_ft_font_transform_t sf;
+ int load_flags;
+ unsigned char *family = (unsigned char*) toy_face->family;
pattern = FcPatternCreate ();
if (!pattern)
return CAIRO_STATUS_NO_MEMORY;
- switch (weight)
+ switch (toy_face->weight)
{
case CAIRO_FONT_WEIGHT_BOLD:
fcweight = FC_WEIGHT_BOLD;
@@ -1436,7 +1502,7 @@ _cairo_ft_scaled_font_create (const char *family,
break;
}
- switch (slant)
+ switch (toy_face->slant)
{
case CAIRO_FONT_SLANT_ITALIC:
fcslant = FC_SLANT_ITALIC;
@@ -1450,7 +1516,7 @@ _cairo_ft_scaled_font_create (const char *family,
break;
}
- if (!FcPatternAddString (pattern, FC_FAMILY, (unsigned char *) family))
+ if (!FcPatternAddString (pattern, FC_FAMILY, family))
goto FREE_PATTERN;
if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant))
goto FREE_PATTERN;
@@ -1470,36 +1536,35 @@ _cairo_ft_scaled_font_create (const char *family,
if (!resolved)
goto FREE_PATTERN;
- unscaled = _ft_unscaled_font_get_for_pattern (resolved);
+ unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);
if (!unscaled)
goto FREE_RESOLVED;
-
- new_font = _ft_scaled_font_create (unscaled,
- font_matrix, ctm,
- options, _get_pattern_load_flags (pattern));
+
+ load_flags = _get_pattern_load_flags (pattern);
+
+ new_font = _cairo_ft_scaled_font_create (unscaled,
+ &toy_face->base,
+ font_matrix, ctm,
+ options, load_flags);
+
_cairo_unscaled_font_destroy (&unscaled->base);
+ FREE_RESOLVED:
FcPatternDestroy (resolved);
+
+ FREE_PATTERN:
FcPatternDestroy (pattern);
if (new_font) {
*font = new_font;
return CAIRO_STATUS_SUCCESS;
} else {
- return CAIRO_STATUS_NO_MEMORY; /* A guess */
+ return CAIRO_STATUS_NO_MEMORY;
}
-
- FREE_RESOLVED:
- FcPatternDestroy (resolved);
-
- FREE_PATTERN:
- FcPatternDestroy (pattern);
-
- return CAIRO_STATUS_NO_MEMORY;
}
static void
-_cairo_ft_scaled_font_destroy (void *abstract_font)
+_cairo_ft_scaled_font_fini (void *abstract_font)
{
cairo_ft_scaled_font_t *scaled_font = abstract_font;
@@ -1599,19 +1664,20 @@ _cairo_ft_scaled_font_font_extents (void *abstract_font,
FT_Face face;
FT_Size_Metrics *metrics;
- face = _ft_unscaled_font_lock_face (scaled_font->unscaled);
+ face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
if (!face)
return CAIRO_STATUS_NO_MEMORY;
metrics = &face->size->metrics;
- _ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale);
+ _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+ &scaled_font->base.scale);
/*
* Get to unscaled metrics so that the upper level can get back to
* user space
*/
- if (scaled_font->options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
+ if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
double x_factor, y_factor;
if (scaled_font->unscaled->x_scale == 0)
@@ -1640,7 +1706,7 @@ _cairo_ft_scaled_font_font_extents (void *abstract_font,
/* FIXME: this doesn't do vertical layout atm. */
extents->max_y_advance = 0.0;
- _ft_unscaled_font_unlock_face (scaled_font->unscaled);
+ _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
return CAIRO_STATUS_SUCCESS;
}
@@ -1697,7 +1763,7 @@ _cairo_ft_scaled_font_glyph_extents (void *abstract_font,
/* XXX: Need to add code here to check the font's FcPattern
for FC_VERTICAL_LAYOUT and if set get vertBearingX/Y
instead. This will require that
- cairo_ft_scaled_font_create_for_ft_face accept an
+ cairo_ft_font_face_create_for_ft_face accept an
FcPattern. */
glyph_min.x = glyphs[i].x + img->extents.x_bearing;
glyph_min.y = glyphs[i].y + img->extents.y_bearing;
@@ -1793,6 +1859,26 @@ _cairo_ft_scaled_font_glyph_bbox (void *abstract_font,
return CAIRO_STATUS_SUCCESS;
}
+static cairo_format_t
+_select_text_mask_format (cairo_bool_t have_a1_glyphs,
+ cairo_bool_t have_a8_glyphs,
+ cairo_bool_t have_argb32_glyphs)
+{
+ if (have_a8_glyphs)
+ return CAIRO_FORMAT_A8;
+
+ if (have_a1_glyphs && have_argb32_glyphs)
+ return CAIRO_FORMAT_A8;
+
+ if (have_a1_glyphs)
+ return CAIRO_FORMAT_A1;
+
+ if (have_argb32_glyphs)
+ return CAIRO_FORMAT_ARGB32;
+
+ /* when there are no glyphs to draw, just pick something */
+ return CAIRO_FORMAT_A8;
+}
static cairo_status_t
_cairo_ft_scaled_font_show_glyphs (void *abstract_font,
@@ -1808,12 +1894,16 @@ _cairo_ft_scaled_font_show_glyphs (void *abstract_font,
const cairo_glyph_t *glyphs,
int num_glyphs)
{
- cairo_image_glyph_cache_entry_t *img;
+ cairo_image_glyph_cache_entry_t **entries;
cairo_cache_t *cache;
cairo_glyph_cache_key_t key;
cairo_ft_scaled_font_t *scaled_font = abstract_font;
cairo_surface_pattern_t glyph_pattern;
- cairo_status_t status;
+ cairo_surface_t *mask;
+ cairo_surface_pattern_t mask_pattern;
+ cairo_format_t mask_format = CAIRO_FORMAT_A1;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_bool_t have_a1_glyphs, have_a8_glyphs, have_argb32_glyphs;
int x, y;
int i;
@@ -1833,44 +1923,98 @@ _cairo_ft_scaled_font_show_glyphs (void *abstract_font,
key.scale = scaled_font->base.scale;
key.flags = scaled_font->load_flags;
+ entries = malloc (num_glyphs * sizeof (cairo_image_glyph_cache_entry_t));
+ if (!entries)
+ goto CLEANUP_CACHE;
+
+ have_a1_glyphs = FALSE;
+ have_a8_glyphs = FALSE;
+ have_argb32_glyphs = FALSE;
+
for (i = 0; i < num_glyphs; i++)
{
- img = NULL;
+ entries[i] = NULL;
key.index = glyphs[i].index;
- if (_cairo_cache_lookup (cache, &key, (void **) &img, NULL)
- != CAIRO_STATUS_SUCCESS
- || img == NULL
- || img->image == NULL)
+ if (_cairo_cache_lookup (cache, &key, (void **) &entries[i], NULL) != CAIRO_STATUS_SUCCESS)
+ continue;
+
+ switch (entries[i]->image->format) {
+ case CAIRO_FORMAT_A1:
+ have_a1_glyphs = TRUE;
+ break;
+ case CAIRO_FORMAT_A8:
+ have_a8_glyphs = TRUE;
+ break;
+ case CAIRO_FORMAT_ARGB32:
+ have_argb32_glyphs = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ mask_format = _select_text_mask_format (have_a1_glyphs, have_a8_glyphs, have_argb32_glyphs);
+
+ mask = cairo_image_surface_create (mask_format, width, height);
+ if (!mask)
+ goto CLEANUP_ENTRIES;
+
+ status = _cairo_surface_fill_rectangle (mask, CAIRO_OPERATOR_SOURCE,
+ CAIRO_COLOR_TRANSPARENT,
+ 0, 0, width, height);
+ if (status)
+ goto CLEANUP_MASK;
+
+ for (i = 0; i < num_glyphs; i++)
+ {
+ if (entries[i] == NULL
+ || entries[i]->image == NULL)
continue;
x = (int) floor (glyphs[i].x + 0.5);
y = (int) floor (glyphs[i].y + 0.5);
- _cairo_pattern_init_for_surface (&glyph_pattern, &(img->image->base));
+ _cairo_pattern_init_for_surface (&glyph_pattern, &(entries[i]->image->base));
- status = _cairo_surface_composite (operator, pattern,
+ status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, pattern,
&glyph_pattern.base,
- surface,
- x + img->size.x,
- y + img->size.y,
+ mask,
+ x + entries[i]->size.x,
+ y + entries[i]->size.y,
0, 0,
- x + img->size.x,
- y + img->size.y,
- (double) img->size.width,
- (double) img->size.height);
+ x + entries[i]->size.x - dest_x,
+ y + entries[i]->size.y - dest_y,
+ entries[i]->size.width,
+ entries[i]->size.height);
_cairo_pattern_fini (&glyph_pattern.base);
- if (status) {
- _cairo_unlock_global_image_glyph_cache ();
- return status;
- }
- }
+ if (status)
+ goto CLEANUP_MASK;
+ }
+ _cairo_pattern_init_for_surface (&mask_pattern, mask);
+
+ status = _cairo_surface_composite (operator, pattern, &mask_pattern.base,
+ surface,
+ source_x, source_y,
+ 0, 0,
+ dest_x, dest_y,
+ width, height);
+
+ _cairo_pattern_fini (&mask_pattern.base);
+
+ CLEANUP_MASK:
+ cairo_surface_destroy (mask);
+
+ CLEANUP_ENTRIES:
+ free (entries);
+
+ CLEANUP_CACHE:
_cairo_unlock_global_image_glyph_cache ();
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
@@ -2018,26 +2162,26 @@ _cairo_ft_scaled_font_glyph_path (void *abstract_font,
}
const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
- _cairo_ft_scaled_font_create,
- _cairo_ft_scaled_font_destroy,
+ _cairo_ft_scaled_font_create_toy,
+ _cairo_ft_scaled_font_fini,
_cairo_ft_scaled_font_font_extents,
_cairo_ft_scaled_font_text_to_glyphs,
_cairo_ft_scaled_font_glyph_extents,
_cairo_ft_scaled_font_glyph_bbox,
_cairo_ft_scaled_font_show_glyphs,
_cairo_ft_scaled_font_glyph_path,
- _cairo_ft_scaled_font_get_glyph_cache_key,
+ _cairo_ft_scaled_font_get_glyph_cache_key
};
-/* ft_font_face_t */
+/* cairo_ft_font_face_t */
static void
-_ft_font_face_destroy (void *abstract_face)
+_cairo_ft_font_face_destroy (void *abstract_face)
{
- ft_font_face_t *font_face = abstract_face;
+ cairo_ft_font_face_t *font_face = abstract_face;
- ft_font_face_t *tmp_face = NULL;
- ft_font_face_t *last_face = NULL;
+ cairo_ft_font_face_t *tmp_face = NULL;
+ cairo_ft_font_face_t *last_face = NULL;
if (font_face == NULL)
return;
@@ -2058,7 +2202,8 @@ _ft_font_face_destroy (void *abstract_face)
if (font_face->unscaled &&
font_face->unscaled->from_face &&
- font_face->unscaled->base.ref_count > 1) {
+ font_face->unscaled->base.ref_count > 1)
+ {
cairo_font_face_reference (&font_face->base);
_cairo_unscaled_font_destroy (&font_face->unscaled->base);
@@ -2069,12 +2214,15 @@ _ft_font_face_destroy (void *abstract_face)
if (font_face->unscaled) {
/* Remove face from linked list */
- for (tmp_face = font_face->unscaled->faces; tmp_face; tmp_face = tmp_face->next_face) {
+ for (tmp_face = font_face->unscaled->faces;
+ tmp_face;
+ tmp_face = tmp_face->next)
+ {
if (tmp_face == font_face) {
if (last_face)
- last_face->next_face = tmp_face->next_face;
+ last_face->next = tmp_face->next;
else
- font_face->unscaled->faces = tmp_face->next_face;
+ font_face->unscaled->faces = tmp_face->next;
}
last_face = tmp_face;
@@ -2086,13 +2234,13 @@ _ft_font_face_destroy (void *abstract_face)
}
static cairo_status_t
-_ft_font_face_create_font (void *abstract_face,
- const cairo_matrix_t *font_matrix,
- const cairo_matrix_t *ctm,
- const cairo_font_options_t *options,
- cairo_scaled_font_t **scaled_font)
+_cairo_ft_font_face_scaled_font_create (void *abstract_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_scaled_font_t **scaled_font)
{
- ft_font_face_t *font_face = abstract_face;
+ cairo_ft_font_face_t *font_face = abstract_face;
int load_flags;
/* The handling of font options is different depending on how the
@@ -2109,36 +2257,38 @@ _ft_font_face_create_font (void *abstract_face,
else
load_flags = font_face->load_flags;
- *scaled_font = _ft_scaled_font_create (font_face->unscaled,
- font_matrix, ctm,
- options, load_flags);
+ *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
+ &font_face->base,
+ font_matrix, ctm,
+ options, load_flags);
if (*scaled_font)
return CAIRO_STATUS_SUCCESS;
else
return CAIRO_STATUS_NO_MEMORY;
}
-static const cairo_font_face_backend_t _ft_font_face_backend = {
- _ft_font_face_destroy,
- _ft_font_face_create_font,
+static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
+ _cairo_ft_font_face_destroy,
+ _cairo_ft_font_face_scaled_font_create
};
static cairo_font_face_t *
-_ft_font_face_create (ft_unscaled_font_t *unscaled,
- int load_flags)
+_cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
+ int load_flags)
{
- ft_font_face_t *font_face;
+ cairo_ft_font_face_t *font_face;
/* Looked for an existing matching font face */
- for (font_face = unscaled->faces; font_face; font_face = font_face->next_face) {
- if (font_face->load_flags == load_flags) {
- cairo_font_face_reference (&font_face->base);
- return &font_face->base;
- }
+ for (font_face = unscaled->faces;
+ font_face;
+ font_face = font_face->next)
+ {
+ if (font_face->load_flags == load_flags)
+ return cairo_font_face_reference (&font_face->base);
}
/* No match found, create a new one */
- font_face = malloc (sizeof (ft_font_face_t));
+ font_face = malloc (sizeof (cairo_ft_font_face_t));
if (!font_face)
return NULL;
@@ -2147,10 +2297,10 @@ _ft_font_face_create (ft_unscaled_font_t *unscaled,
font_face->load_flags = load_flags;
- font_face->next_face = unscaled->faces;
+ font_face->next = unscaled->faces;
unscaled->faces = font_face;
- _cairo_font_face_init (&font_face->base, &_ft_font_face_backend);
+ _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
return &font_face->base;
}
@@ -2272,16 +2422,17 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
cairo_font_face_t *
cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
{
- ft_unscaled_font_t *unscaled;
+ cairo_ft_unscaled_font_t *unscaled;
cairo_font_face_t *font_face;
- unscaled = _ft_unscaled_font_get_for_pattern (pattern);
+ unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
if (unscaled == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
- font_face = _ft_font_face_create (unscaled, _get_pattern_load_flags (pattern));
+ font_face = _cairo_ft_font_face_create (unscaled,
+ _get_pattern_load_flags (pattern));
_cairo_unscaled_font_destroy (&unscaled->base);
if (font_face)
@@ -2321,16 +2472,16 @@ cairo_font_face_t *
cairo_ft_font_face_create_for_ft_face (FT_Face face,
int load_flags)
{
- ft_unscaled_font_t *unscaled;
+ cairo_ft_unscaled_font_t *unscaled;
cairo_font_face_t *font_face;
- unscaled = _ft_unscaled_font_create_from_face (face);
+ unscaled = _cairo_ft_unscaled_font_create_from_face (face);
if (unscaled == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
- font_face = _ft_font_face_create (unscaled, load_flags);
+ font_face = _cairo_ft_font_face_create (unscaled, load_flags);
_cairo_unscaled_font_destroy (&unscaled->base);
if (font_face) {
@@ -2379,13 +2530,14 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
if (scaled_font->base.status)
return NULL;
- face = _ft_unscaled_font_lock_face (scaled_font->unscaled);
+ face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
if (face == NULL) {
_cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
return NULL;
}
- _ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale);
+ _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+ &scaled_font->base.scale);
return face;
}
@@ -2408,7 +2560,7 @@ cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
if (scaled_font->base.status)
return;
- _ft_unscaled_font_unlock_face (scaled_font->unscaled);
+ _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
}
/* We expose our unscaled font implementation internally for the the
@@ -2423,17 +2575,8 @@ _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *abstract_font)
return &scaled_font->unscaled->base;
}
-/* This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
- * set the scale on the face, but just returns it at the last scale.
- */
-FT_Face
-_cairo_ft_unscaled_font_lock_face (cairo_unscaled_font_t *unscaled_font)
-{
- return _ft_unscaled_font_lock_face ((ft_unscaled_font_t *)unscaled_font);
-}
-
void
-_cairo_ft_unscaled_font_unlock_face (cairo_unscaled_font_t *unscaled_font)
+_cairo_ft_font_reset_static_data (void)
{
- _ft_unscaled_font_unlock_face ((ft_unscaled_font_t *)unscaled_font);
+ _cairo_ft_unscaled_font_map_destroy ();
}