summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo-font-face.c34
-rw-r--r--src/cairo-ft-font.c2
-rw-r--r--src/cairo-quartz-font.c55
-rw-r--r--src/cairo-scaled-font.c11
-rw-r--r--src/cairo-user-font.c37
-rw-r--r--src/cairo-win32-font.c2
-rw-r--r--src/cairoint.h8
7 files changed, 128 insertions, 21 deletions
diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c
index a260378b..6cea3958 100644
--- a/src/cairo-font-face.c
+++ b/src/cairo-font-face.c
@@ -569,6 +569,39 @@ _cairo_toy_font_face_destroy (void *abstract_face)
}
static cairo_status_t
+_cairo_toy_font_face_scaled_font_get_implementation (void *abstract_font_face,
+ cairo_font_face_t **font_face_out)
+{
+ cairo_toy_font_face_t *font_face = abstract_font_face;
+ cairo_status_t status;
+
+ if (font_face->base.status)
+ return font_face->base.status;
+
+ if (CAIRO_SCALED_FONT_BACKEND_DEFAULT != &_cairo_user_scaled_font_backend &&
+ 0 != strcmp (font_face->family, CAIRO_USER_FONT_FAMILY_DEFAULT))
+ {
+ const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
+
+ if (backend->get_implementation == NULL) {
+ *font_face_out = &font_face->base;
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ status = backend->get_implementation (font_face,
+ font_face_out);
+
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return _cairo_font_face_set_error (&font_face->base, status);
+ }
+
+ status = _cairo_user_scaled_font_backend.get_implementation (font_face,
+ font_face_out);
+
+ return _cairo_font_face_set_error (&font_face->base, status);
+}
+
+static cairo_status_t
_cairo_toy_font_face_scaled_font_create (void *abstract_font_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
@@ -689,6 +722,7 @@ slim_hidden_def (cairo_toy_font_face_get_weight);
static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
CAIRO_FONT_TYPE_TOY,
_cairo_toy_font_face_destroy,
+ _cairo_toy_font_face_scaled_font_get_implementation,
_cairo_toy_font_face_scaled_font_create
};
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 7075b5db..cd112532 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2211,6 +2211,7 @@ _cairo_ft_index_to_ucs4(void *abstract_font,
const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
CAIRO_FONT_TYPE_FT,
+ NULL,
_cairo_ft_scaled_font_create_toy,
_cairo_ft_scaled_font_fini,
_cairo_ft_scaled_glyph_init,
@@ -2317,6 +2318,7 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face,
static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
CAIRO_FONT_TYPE_FT,
_cairo_ft_font_face_destroy,
+ NULL, /* direct implementation */
_cairo_ft_font_face_scaled_font_create
};
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index c6898008..2bca3720 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -225,6 +225,7 @@ FINISH:
static const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
CAIRO_FONT_TYPE_QUARTZ,
_cairo_quartz_font_face_destroy,
+ NULL, /* direct implementation */
_cairo_quartz_font_face_scaled_font_create
};
@@ -277,24 +278,27 @@ _cairo_quartz_scaled_to_face (void *abstract_font)
}
static cairo_status_t
-_cairo_quartz_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_out)
+_cairo_quartz_font_get_implementation (cairo_toy_font_face_t *toy_face,
+ cairo_scaled_font_t **font_face_out)
{
+ static cairo_user_data_key_t impl_font_face_key;
+ cairo_font_face_t *face;
+ cairo_status_t status;
const char *family = toy_face->family;
char *full_name = malloc(strlen(family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
CFStringRef cgFontName = NULL;
CGFontRef cgFont = NULL;
int loop;
- cairo_status_t status;
- cairo_font_face_t *face;
- cairo_scaled_font_t *scaled_font;
+ face = cairo_font_face_get_user_data (&toy_face->base,
+ &impl_font_face_key);
+ if (face) {
+ *font_face_out = face;
+ return CAIRO_STATUS_SUCCESS;
+ }
quartz_font_ensure_symbols();
- if (!_cairo_quartz_font_symbols_present)
+ if (! _cairo_quartz_font_symbols_present)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/* handle CSS-ish faces */
@@ -345,7 +349,7 @@ _cairo_quartz_font_create_toy(cairo_toy_font_face_t *toy_face,
if (!cgFont) {
/* Give up */
- return CAIRO_STATUS_NO_MEMORY;
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
face = cairo_quartz_font_face_create_for_cgfont (cgFont);
@@ -354,6 +358,35 @@ _cairo_quartz_font_create_toy(cairo_toy_font_face_t *toy_face,
if (face->status)
return face->status;
+ status = cairo_font_face_set_user_data (&toy_face->base,
+ &impl_font_face_key,
+ face,
+ (cairo_destroy_func_t) cairo_font_face_destroy);
+
+ if (status) {
+ cairo_font_face_destroy (face);
+ return status;
+ }
+
+ *font_face_out = face;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_quartz_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_out)
+{
+ cairo_font_face_t *face;
+ cairo_scaled_font_t *scaled_font;
+ cairo_status_t status;
+
+ status = _cairo_quartz_font_get_implementation (toy_face, &face);
+ if (status)
+ return status;
+
status = _cairo_quartz_font_face_scaled_font_create (face,
font_matrix, ctm,
options,
@@ -363,7 +396,6 @@ _cairo_quartz_font_create_toy(cairo_toy_font_face_t *toy_face,
return status;
*font_out = scaled_font;
-
return CAIRO_STATUS_SUCCESS;
}
@@ -743,6 +775,7 @@ _cairo_quartz_ucs4_to_index (void *abstract_font,
const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend = {
CAIRO_FONT_TYPE_QUARTZ,
+ _cairo_quartz_font_get_implementation,
_cairo_quartz_font_create_toy,
_cairo_quartz_font_fini,
_cairo_quartz_font_scaled_glyph_init,
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index d312a4c8..3ec07d54 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -772,6 +772,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
const cairo_font_options_t *options)
{
cairo_status_t status;
+ cairo_font_face_t *impl_face;
cairo_scaled_font_map_t *font_map;
cairo_scaled_font_t key, *old = NULL, *scaled_font = NULL;
@@ -785,11 +786,19 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
/* Note that degenerate ctm or font_matrix *are* allowed.
* We want to support a font size of 0. */
+ if (font_face->backend->get_implementation != NULL) {
+ /* indirect implementation, lookup the face that is used for the key */
+ status = font_face->backend->get_implementation (font_face, &impl_face);
+ if (status)
+ return _cairo_scaled_font_create_in_error (status);
+ } else
+ impl_face = font_face;
+
font_map = _cairo_scaled_font_map_lock ();
if (font_map == NULL)
return _cairo_scaled_font_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- _cairo_scaled_font_init_key (&key, font_face,
+ _cairo_scaled_font_init_key (&key, impl_face,
font_matrix, ctm, options);
scaled_font = font_map->mru_scaled_font;
if (scaled_font != NULL &&
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index 385b8414..ddcbc77c 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -337,17 +337,14 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
cairo_scaled_font_t **scaled_font);
static cairo_status_t
-_cairo_user_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 *font_options,
- cairo_scaled_font_t **font)
+_cairo_user_scaled_font_get_implementation (cairo_toy_font_face_t *toy_face,
+ cairo_font_face_t **font_face_out)
{
- cairo_status_t status;
- cairo_font_face_t *face;
-
static cairo_user_data_key_t twin_font_face_key;
+ cairo_font_face_t *face;
+ cairo_status_t status;
+
face = cairo_font_face_get_user_data (&toy_face->base,
&twin_font_face_key);
if (!face) {
@@ -365,17 +362,38 @@ _cairo_user_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
}
}
+ *font_face_out = face;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_user_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 *font_options,
+ cairo_scaled_font_t **font)
+{
+ cairo_font_face_t *face;
+ cairo_status_t status;
+
+ status = _cairo_user_scaled_font_get_implementation (toy_face, &face);
+ if (status)
+ return status;
+
status = _cairo_user_font_face_scaled_font_create (face,
font_matrix,
ctm,
font_options,
font);
+ if (status)
+ return status;
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
const cairo_scaled_font_backend_t _cairo_user_scaled_font_backend = {
CAIRO_FONT_TYPE_USER,
+ _cairo_user_scaled_font_get_implementation,
_cairo_user_scaled_font_create_toy, /* create_toy */
NULL, /* scaled_font_fini */
_cairo_user_scaled_glyph_init,
@@ -501,6 +519,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
static const cairo_font_face_backend_t _cairo_user_font_face_backend = {
CAIRO_FONT_TYPE_USER,
NULL, /* destroy */
+ NULL, /* direct implementation */
_cairo_user_font_face_scaled_font_create
};
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index dc937585..7f6d4351 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -1835,6 +1835,7 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font
const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = {
CAIRO_FONT_TYPE_WIN32,
+ NULL,
_cairo_win32_scaled_font_create_toy,
_cairo_win32_scaled_font_fini,
_cairo_win32_scaled_font_glyph_init,
@@ -1904,6 +1905,7 @@ _cairo_win32_font_face_scaled_font_create (void *abstract_face,
static const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
CAIRO_FONT_TYPE_WIN32,
_cairo_win32_font_face_destroy,
+ NULL, /* direct implementation */
_cairo_win32_font_face_scaled_font_create
};
diff --git a/src/cairoint.h b/src/cairoint.h
index a60de51d..a1d3f3d4 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -412,6 +412,10 @@ struct _cairo_scaled_font_backend {
cairo_font_type_t type;
cairo_warn cairo_status_t
+ (*get_implementation) (cairo_toy_font_face_t *toy_face,
+ cairo_font_face_t **font_face);
+
+ cairo_warn cairo_status_t
(*create_toy) (cairo_toy_font_face_t *toy_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,
@@ -484,6 +488,10 @@ struct _cairo_font_face_backend {
(*destroy) (void *font_face);
cairo_warn cairo_status_t
+ (*get_implementation) (void *font_face,
+ cairo_font_face_t **font_face_out);
+
+ cairo_warn cairo_status_t
(*scaled_font_create) (void *font_face,
const cairo_matrix_t *font_matrix,
const cairo_matrix_t *ctm,