diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2021-08-14 07:06:34 +0000 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2021-08-14 07:06:34 +0000 |
commit | 1e446cb31e19c46118df7c2fdf96359a4f52ad0e (patch) | |
tree | 456bc7af299f7922094e3bce8ede2cca937d5309 | |
parent | 6ea9ec75eda7461a51429ae8e40e365bdd2dbd6f (diff) | |
download | cairo-1e446cb31e19c46118df7c2fdf96359a4f52ad0e.tar.gz |
Fix color fonts when antialias == SUBPIXEL or NONE
-rw-r--r-- | src/cairo-ft-font.c | 147 | ||||
-rw-r--r-- | src/cairo-surface.c | 1 |
2 files changed, 86 insertions, 62 deletions
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 2adc979bc..adfb445df 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2475,6 +2475,76 @@ _cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font, } static cairo_int_status_t +_cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font, + cairo_scaled_glyph_t *scaled_glyph, + cairo_scaled_glyph_info_t info, + FT_Face face, + cairo_bool_t vertical_layout, + int load_flags) +{ + cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; + FT_GlyphSlot glyph; + cairo_status_t status; + cairo_image_surface_t *surface; + + if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) { + if (!unscaled->have_color) + return CAIRO_INT_STATUS_UNSUPPORTED; + + load_flags &= ~FT_LOAD_MONOCHROME; + /* clear load target mode */ + load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(load_flags))); + load_flags |= FT_LOAD_TARGET_NORMAL; +#ifdef FT_LOAD_COLOR + load_flags |= FT_LOAD_COLOR; +#endif + } else { +#ifdef FT_LOAD_COLOR + load_flags &= ~FT_LOAD_COLOR; +#endif + } + + status = _cairo_ft_scaled_glyph_load_glyph (scaled_font, + scaled_glyph, + face, + load_flags, + FALSE, + vertical_layout); + if (unlikely (status)) + return status; + + glyph = face->glyph; + + if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) { + status = _render_glyph_outline (face, &scaled_font->ft_options.base, + &surface); + } else { + status = _render_glyph_bitmap (face, &scaled_font->ft_options.base, + &surface); + if (likely (status == CAIRO_STATUS_SUCCESS) && unscaled->have_shape) { + status = _transform_glyph_bitmap (&unscaled->current_shape, + &surface); + if (unlikely (status)) + cairo_surface_destroy (&surface->base); + } + if (unlikely (status)) + return status; + } + if (pixman_image_get_format (surface->pixman_image) == PIXMAN_a8r8g8b8 && + !pixman_image_get_component_alpha (surface->pixman_image)) { + _cairo_scaled_glyph_set_color_surface (scaled_glyph, + &scaled_font->base, + surface); + } else { + _cairo_scaled_glyph_set_surface (scaled_glyph, + &scaled_font->base, + surface); + } + + return status; +} + +static cairo_int_status_t _cairo_ft_scaled_glyph_init (void *abstract_font, cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_glyph_info_t info) @@ -2513,11 +2583,6 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, vertical_layout = TRUE; } -#ifdef FT_LOAD_COLOR - load_flags |= FT_LOAD_COLOR; -#endif - - if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) { cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF; @@ -2628,66 +2693,26 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, &fs_metrics); } -LOAD: - if (info & (CAIRO_SCALED_GLYPH_INFO_SURFACE | CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) { - cairo_image_surface_t *surface; - - if (!scaled_glyph_loaded) { - status = _cairo_ft_scaled_glyph_load_glyph (scaled_font, - scaled_glyph, - face, - load_flags, - FALSE, - vertical_layout); - if (unlikely (status)) - goto FAIL; - - glyph = face->glyph; - scaled_glyph_loaded = TRUE; - } - - if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) { - status = _render_glyph_outline (face, &scaled_font->ft_options.base, - &surface); - } else { - status = _render_glyph_bitmap (face, &scaled_font->ft_options.base, - &surface); - if (likely (status == CAIRO_STATUS_SUCCESS) && - unscaled->have_shape) - { - status = _transform_glyph_bitmap (&unscaled->current_shape, - &surface); - if (unlikely (status)) - cairo_surface_destroy (&surface->base); - } - } + if (info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) { + status = _cairo_ft_scaled_glyph_init_surface (scaled_font, + scaled_glyph, + CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE, + face, + vertical_layout, + load_flags); if (unlikely (status)) goto FAIL; - - if (pixman_image_get_format (surface->pixman_image) == PIXMAN_a8r8g8b8 && - !pixman_image_get_component_alpha (surface->pixman_image)) { - _cairo_scaled_glyph_set_color_surface (scaled_glyph, - &scaled_font->base, - surface); - } else { - _cairo_scaled_glyph_set_surface (scaled_glyph, - &scaled_font->base, - surface); - } } - if (((info & (CAIRO_SCALED_GLYPH_INFO_SURFACE | CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) != 0) && - ((scaled_glyph->has_info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)) { - /* - * A kludge -- load again, without color. - * No need to load the metrics again, though - */ - scaled_glyph_loaded = FALSE; - info &= ~CAIRO_SCALED_GLYPH_INFO_METRICS; -#ifdef FT_LOAD_COLOR - load_flags &= ~FT_LOAD_COLOR; -#endif - goto LOAD; + if (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) { + status = _cairo_ft_scaled_glyph_init_surface (scaled_font, + scaled_glyph, + CAIRO_SCALED_GLYPH_INFO_SURFACE, + face, + vertical_layout, + load_flags); + if (unlikely (status)) + goto FAIL; } if (info & CAIRO_SCALED_GLYPH_INFO_PATH) { diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 3029e2cf0..a4a43a027 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2623,7 +2623,6 @@ ensure_scaled_glyph (cairo_scaled_font_t *scaled_font, CAIRO_SCALED_GLYPH_INFO_METRICS, scaled_glyph); } - if (unlikely (status)) status = _cairo_scaled_font_set_error (scaled_font, status); |