diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-10-22 15:43:56 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-10-22 16:38:12 +0100 |
commit | 954ebacb71071c53c4e4092b469417f01478bc2d (patch) | |
tree | ce0e43ee87f713d85a8e93a9b5fb72d083ba3162 /src/cairo-font-face.c | |
parent | 5e4a1cb0b830f069d99c9512563c82ad628587e3 (diff) |
Map toy font face to implementation.
Quartz fonts and user fonts use an indirect font face when creating a
scaled font for the toy font face. This means that they insert a scaled
font into the font map that has a different font face to the one that is
initially searched upon. The result is that when we try to create an
identical scaled font, we fail to find the existing scaled font and
attempt to insert a duplicate into the hash table - which triggers an
assert.
In order to avoid creating duplicate fonts, we add a new method to the
font backends that allows cairo_scaled_font_create() to peek at the
font_face that will be used to actually implement the scaled font
constructor - thus we are able to use the correct font_face as part of the
hash key.
Diffstat (limited to 'src/cairo-font-face.c')
-rw-r--r-- | src/cairo-font-face.c | 34 |
1 files changed, 34 insertions, 0 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 }; |