diff options
-rw-r--r-- | src/cairo-font-face.c | 34 | ||||
-rw-r--r-- | src/cairo-ft-font.c | 2 | ||||
-rw-r--r-- | src/cairo-quartz-font.c | 55 | ||||
-rw-r--r-- | src/cairo-scaled-font.c | 11 | ||||
-rw-r--r-- | src/cairo-user-font.c | 37 | ||||
-rw-r--r-- | src/cairo-win32-font.c | 2 | ||||
-rw-r--r-- | src/cairoint.h | 8 |
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, |