mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 07:38:22 +02:00
[ft] Substitute twin if there are no fonts
Fixes bug 22356 -- Spurious "out of memory" error on system without fonts https://bugs.freedesktop.org/show_bug.cgi?id=22356 If FcFontMatch() fails, then it means that there are no fonts available on the system (or it may have been a malloc error, we have no way of telling). Instead of report NO_MEMORY and disabling all drawing, one of the rationales for including a builtin font was so that we could continue even in the face of this error and show *something* to the user. (This being a last resort (and especially important for demos!) and hopefully easier to diagnose than no output at all.)
This commit is contained in:
parent
6d8b353658
commit
d3330d7beb
3 changed files with 66 additions and 18 deletions
|
|
@ -283,11 +283,11 @@ face_props_parse (twin_face_properties_t *props,
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
|
||||
cairo_toy_font_face_t *toy_face)
|
||||
twin_font_face_create_properties (cairo_font_face_t *twin_face,
|
||||
twin_face_properties_t **props_out)
|
||||
{
|
||||
cairo_status_t status;
|
||||
twin_face_properties_t *props;
|
||||
cairo_status_t status;
|
||||
|
||||
props = malloc (sizeof (twin_face_properties_t));
|
||||
if (unlikely (props == NULL))
|
||||
|
|
@ -297,22 +297,37 @@ twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
|
|||
props->monospace = FALSE;
|
||||
props->smallcaps = FALSE;
|
||||
|
||||
status = cairo_font_face_set_user_data (twin_face,
|
||||
&twin_properties_key,
|
||||
props, free);
|
||||
if (unlikely (status)) {
|
||||
free (props);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (props_out)
|
||||
*props_out = props;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
|
||||
cairo_toy_font_face_t *toy_face)
|
||||
{
|
||||
cairo_status_t status;
|
||||
twin_face_properties_t *props;
|
||||
|
||||
status = twin_font_face_create_properties (twin_face, &props);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
props->slant = toy_face->slant;
|
||||
props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ?
|
||||
TWIN_WEIGHT_NORMAL : TWIN_WEIGHT_BOLD;
|
||||
face_props_parse (props, toy_face->family);
|
||||
|
||||
status = cairo_font_face_set_user_data (twin_face,
|
||||
&twin_properties_key,
|
||||
props, free);
|
||||
if (unlikely (status))
|
||||
goto FREE_PROPS;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FREE_PROPS:
|
||||
free (props);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -694,6 +709,35 @@ twin_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
|
|||
* Face constructor
|
||||
*/
|
||||
|
||||
static cairo_font_face_t *
|
||||
_cairo_font_face_twin_create_internal (void)
|
||||
{
|
||||
cairo_font_face_t *twin_font_face;
|
||||
|
||||
twin_font_face = cairo_user_font_face_create ();
|
||||
cairo_user_font_face_set_init_func (twin_font_face, twin_scaled_font_init);
|
||||
cairo_user_font_face_set_render_glyph_func (twin_font_face, twin_scaled_font_render_glyph);
|
||||
cairo_user_font_face_set_unicode_to_glyph_func (twin_font_face, twin_scaled_font_unicode_to_glyph);
|
||||
|
||||
return twin_font_face;
|
||||
}
|
||||
|
||||
cairo_font_face_t *
|
||||
_cairo_font_face_twin_create_fallback (void)
|
||||
{
|
||||
cairo_font_face_t *twin_font_face;
|
||||
cairo_status_t status;
|
||||
|
||||
twin_font_face = _cairo_font_face_twin_create_internal ();
|
||||
status = twin_font_face_create_properties (twin_font_face, NULL);
|
||||
if (status) {
|
||||
cairo_font_face_destroy (twin_font_face);
|
||||
return (cairo_font_face_t *) &_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
return twin_font_face;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
|
||||
cairo_font_face_t **font_face)
|
||||
|
|
@ -701,10 +745,7 @@ _cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
|
|||
cairo_status_t status;
|
||||
cairo_font_face_t *twin_font_face;
|
||||
|
||||
twin_font_face = cairo_user_font_face_create ();
|
||||
cairo_user_font_face_set_init_func (twin_font_face, twin_scaled_font_init);
|
||||
cairo_user_font_face_set_render_glyph_func (twin_font_face, twin_scaled_font_render_glyph);
|
||||
cairo_user_font_face_set_unicode_to_glyph_func (twin_font_face, twin_scaled_font_unicode_to_glyph);
|
||||
twin_font_face = _cairo_font_face_twin_create_internal ();
|
||||
status = twin_font_face_set_properties_from_toy (twin_font_face, toy_face);
|
||||
if (status) {
|
||||
cairo_font_face_destroy (twin_font_face);
|
||||
|
|
|
|||
|
|
@ -2601,7 +2601,11 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
|||
|
||||
resolved = FcFontMatch (NULL, pattern, &result);
|
||||
if (!resolved) {
|
||||
font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
/* We failed to find any font. Substitute twin so that the user can
|
||||
* see something (and hopefully recognise that the font is missing)
|
||||
* and not just receive a NO_MEMORY error during rendering.
|
||||
*/
|
||||
font_face = _cairo_font_face_twin_create_fallback ();
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1435,6 +1435,9 @@ _cairo_unscaled_font_destroy (cairo_unscaled_font_t *font);
|
|||
|
||||
/* cairo-font-face-twin.c */
|
||||
|
||||
cairo_private cairo_font_face_t *
|
||||
_cairo_font_face_twin_create_fallback (void);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
|
||||
cairo_font_face_t **font_face);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue