diff --git a/gfx/cairo/cairo/src/cairo-compositor-private.h b/gfx/cairo/cairo/src/cairo-compositor-private.h --- a/gfx/cairo/cairo/src/cairo-compositor-private.h +++ b/gfx/cairo/cairo/src/cairo-compositor-private.h @@ -85,7 +85,8 @@ struct cairo_compositor { cairo_scaled_font_t *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, - cairo_bool_t overlap); + cairo_bool_t overlap, + cairo_bool_t permit_subpixel_antialiasing); }; struct cairo_mask_compositor { diff --git a/gfx/cairo/cairo/src/cairo-compositor.c b/gfx/cairo/cairo/src/cairo-compositor.c --- a/gfx/cairo/cairo/src/cairo-compositor.c +++ b/gfx/cairo/cairo/src/cairo-compositor.c @@ -248,7 +248,8 @@ cairo_int_status_t compositor = compositor->delegate; status = compositor->glyphs (compositor, &extents, - scaled_font, glyphs, num_glyphs, overlap); + scaled_font, glyphs, num_glyphs, overlap, + surface->permit_subpixel_antialiasing); compositor = compositor->delegate; } while (status == CAIRO_INT_STATUS_UNSUPPORTED); diff --git a/gfx/cairo/cairo/src/cairo-no-compositor.c b/gfx/cairo/cairo/src/cairo-no-compositor.c --- a/gfx/cairo/cairo/src/cairo-no-compositor.c +++ b/gfx/cairo/cairo/src/cairo-no-compositor.c @@ -91,7 +91,8 @@ static cairo_int_status_t cairo_scaled_font_t *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, - cairo_bool_t overlap) + cairo_bool_t overlap, + cairo_bool_t permit_subpixel_antialiasing) { ASSERT_NOT_REACHED; return CAIRO_INT_STATUS_NOTHING_TO_DO; diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c @@ -1947,7 +1947,8 @@ static cairo_int_status_t cairo_scaled_font_t *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, - cairo_bool_t overlap) + cairo_bool_t overlap, + cairo_bool_t permit_subpixel_antialiasing) { CGAffineTransform textTransform, invTextTransform; CGGlyph glyphs_static[CAIRO_STACK_ARRAY_LENGTH (CGSize)]; @@ -1963,6 +1964,7 @@ static cairo_int_status_t CGFontRef cgfref = NULL; cairo_bool_t didForceFontSmoothing = FALSE; + cairo_antialias_t effective_antialiasing; if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_QUARTZ) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1983,7 +1985,12 @@ static cairo_int_status_t CGContextSetFont (state.cgMaskContext, cgfref); CGContextSetFontSize (state.cgMaskContext, 1.0); - switch (scaled_font->options.antialias) { + effective_antialiasing = scaled_font->options.antialias; + if (effective_antialiasing == CAIRO_ANTIALIAS_SUBPIXEL && + !permit_subpixel_antialiasing) { + effective_antialiasing = CAIRO_ANTIALIAS_GRAY; + } + switch (effective_antialiasing) { case CAIRO_ANTIALIAS_SUBPIXEL: case CAIRO_ANTIALIAS_BEST: CGContextSetShouldAntialias (state.cgMaskContext, TRUE); diff --git a/gfx/cairo/cairo/src/cairo-surface-private.h b/gfx/cairo/cairo/src/cairo-surface-private.h --- a/gfx/cairo/cairo/src/cairo-surface-private.h +++ b/gfx/cairo/cairo/src/cairo-surface-private.h @@ -71,6 +71,7 @@ struct _cairo_surface { unsigned has_font_options : 1; unsigned owns_device : 1; unsigned is_vector : 1; + unsigned permit_subpixel_antialiasing : 1; cairo_user_data_array_t user_data; cairo_user_data_array_t mime_data; diff --git a/gfx/cairo/cairo/src/cairo-surface.c b/gfx/cairo/cairo/src/cairo-surface.c --- a/gfx/cairo/cairo/src/cairo-surface.c +++ b/gfx/cairo/cairo/src/cairo-surface.c @@ -115,6 +115,7 @@ const cairo_surface_t name = { \ FALSE, /* has_font_options */ \ FALSE, /* owns_device */ \ FALSE, /* is_vector */ \ + FALSE, /* permit_subpixel_antialiasing */ \ { 0, 0, 0, NULL, }, /* user_data */ \ { 0, 0, 0, NULL, }, /* mime_data */ \ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ \ @@ -421,6 +422,7 @@ void surface->serial = 0; surface->damage = NULL; surface->owns_device = (device != NULL); + surface->permit_subpixel_antialiasing = TRUE; _cairo_user_data_array_init (&surface->user_data); _cairo_user_data_array_init (&surface->mime_data); @@ -452,6 +454,8 @@ static void _cairo_surface_set_font_options (surface, &options); } + surface->permit_subpixel_antialiasing = other->permit_subpixel_antialiasing; + cairo_surface_set_fallback_resolution (surface, other->x_fallback_resolution, other->y_fallback_resolution); @@ -1619,6 +1623,51 @@ cairo_surface_get_font_options (cairo_su } slim_hidden_def (cairo_surface_get_font_options); +/** + * cairo_surface_set_subpixel_antialiasing: + * @surface: a #cairo_surface_t + * + * Sets whether the surface permits subpixel antialiasing. By default, + * surfaces permit subpixel antialiasing. + * + * Enabling subpixel antialiasing for CONTENT_COLOR_ALPHA surfaces generally + * requires that the pixels in the areas under a subpixel antialiasing + * operation already be opaque. + **/ +void +cairo_surface_set_subpixel_antialiasing (cairo_surface_t *surface, + cairo_subpixel_antialiasing_t enabled) +{ + if (surface->status) + return; + + if (surface->finished) { + _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); + return; + } + + surface->permit_subpixel_antialiasing = + enabled == CAIRO_SUBPIXEL_ANTIALIASING_ENABLED; +} + +/** + * cairo_surface_get_subpixel_antialiasing: + * @surface: a #cairo_surface_t + * + * Gets whether the surface supports subpixel antialiasing. By default, + * CAIRO_CONTENT_COLOR surfaces support subpixel antialiasing but other + * surfaces do not. + **/ +cairo_subpixel_antialiasing_t +cairo_surface_get_subpixel_antialiasing (cairo_surface_t *surface) +{ + if (surface->status) + return CAIRO_SUBPIXEL_ANTIALIASING_DISABLED; + + return surface->permit_subpixel_antialiasing ? + CAIRO_SUBPIXEL_ANTIALIASING_ENABLED : CAIRO_SUBPIXEL_ANTIALIASING_DISABLED; +} + cairo_status_t _cairo_surface_flush (cairo_surface_t *surface, unsigned flags) { diff --git a/gfx/cairo/cairo/src/cairo-xcb-private.h b/gfx/cairo/cairo/src/cairo-xcb-private.h --- a/gfx/cairo/cairo/src/cairo-xcb-private.h +++ b/gfx/cairo/cairo/src/cairo-xcb-private.h @@ -453,7 +453,8 @@ cairo_private cairo_int_status_t cairo_scaled_font_t *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, - cairo_bool_t overlap); + cairo_bool_t overlap, + cairo_bool_t permit_subpixel_antialiasing); cairo_private void _cairo_xcb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font); diff --git a/gfx/cairo/cairo/src/cairo-xcb-surface-render.c b/gfx/cairo/cairo/src/cairo-xcb-surface-render.c --- a/gfx/cairo/cairo/src/cairo-xcb-surface-render.c +++ b/gfx/cairo/cairo/src/cairo-xcb-surface-render.c @@ -4816,7 +4816,8 @@ cairo_int_status_t cairo_scaled_font_t *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, - cairo_bool_t overlap) + cairo_bool_t overlap, + cairo_bool_t permit_subpixel_antialiasing) { cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) composite->surface; cairo_operator_t op = composite->op; diff --git a/gfx/cairo/cairo/src/cairo-xcb-surface.c b/gfx/cairo/cairo/src/cairo-xcb-surface.c --- a/gfx/cairo/cairo/src/cairo-xcb-surface.c +++ b/gfx/cairo/cairo/src/cairo-xcb-surface.c @@ -912,7 +912,8 @@ static cairo_int_status_t cairo_scaled_font_t *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, - cairo_bool_t overlap) + cairo_bool_t overlap, + cairo_bool_t permit_subpixel_antialiasing) { cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) extents->surface; cairo_surface_t *fallback = _cairo_xcb_surface_fallback (surface, extents); diff --git a/gfx/cairo/cairo/src/cairo.h b/gfx/cairo/cairo/src/cairo.h --- a/gfx/cairo/cairo/src/cairo.h +++ b/gfx/cairo/cairo/src/cairo.h @@ -2573,6 +2573,26 @@ cairo_surface_show_page (cairo_surface_t cairo_public cairo_bool_t cairo_surface_has_show_text_glyphs (cairo_surface_t *surface); +/** + * _cairo_subpixel_antialiasing_t: + * @CAIRO_SUBPIXEL_ANTIALIASING_ENABLED: subpixel antialiasing is enabled + * for this surface. + * @CAIRO_SUBPIXEL_ANTIALIASING_DISABLED: subpixel antialiasing is disabled + * for this surface. + */ +typedef enum _cairo_subpixel_antialiasing_t { + CAIRO_SUBPIXEL_ANTIALIASING_ENABLED, + CAIRO_SUBPIXEL_ANTIALIASING_DISABLED +} cairo_subpixel_antialiasing_t; + +cairo_public void +cairo_surface_set_subpixel_antialiasing (cairo_surface_t *surface, + cairo_subpixel_antialiasing_t enabled); + +cairo_public cairo_subpixel_antialiasing_t +cairo_surface_get_subpixel_antialiasing (cairo_surface_t *surface); + + /* Image-surface functions */ cairo_public cairo_surface_t *