summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2021-08-14 07:06:34 +0000
committerAdrian Johnson <ajohnson@redneon.com>2021-08-14 07:06:34 +0000
commit1e446cb31e19c46118df7c2fdf96359a4f52ad0e (patch)
tree456bc7af299f7922094e3bce8ede2cca937d5309
parent6ea9ec75eda7461a51429ae8e40e365bdd2dbd6f (diff)
downloadcairo-1e446cb31e19c46118df7c2fdf96359a4f52ad0e.tar.gz
Fix color fonts when antialias == SUBPIXEL or NONE
-rw-r--r--src/cairo-ft-font.c147
-rw-r--r--src/cairo-surface.c1
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);