summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2008-01-11 12:28:49 -0800
committerCarl Worth <cworth@cworth.org>2008-01-11 12:55:41 -0800
commit35ed062a6269feeebae70c98000b60630a9ec3bd (patch)
tree2479b0132a74fe98f9a1d6b92adebdd908126df4
parent69549125feb24118ad35403a4be647f8bb692e86 (diff)
Migrate glyph mask to A8 in case of mixed-format glyphs.
This fixes the remaining image-backend problems with bug 13479: Ugly Courier New font with cairo 1.4.12 https://bugs.freedesktop.org/show_bug.cgi?id=13479 although the xlib-backend had been fixed previously. Specifically, if an A1 glyph is first encountered, then subsequent glyphs will still be rendered with antialiasing, (previously they would be rendered very poorly without antialiasing). Similarly, if the first glyph encountered has component-alpha sub-pixel antialiasing and then an A1 or A8 glyph is encountered then all glyphs will rendered in A8 (grayscale antialiasing). Previously, the non-subpixel-antialiased glyphs would not appear at all. Cherry picked from commit ecb895803b9d2a3fd142f4a2c694ca08c5581f0e
-rw-r--r--src/cairo-scaled-font.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ef70a389b..256899ba3 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1037,6 +1037,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
{
cairo_status_t status;
cairo_surface_t *mask = NULL;
+ cairo_format_t mask_format;
+ cairo_surface_pattern_t mask_pattern;
int i;
/* These operators aren't interpreted the same way by the backends;
@@ -1084,9 +1086,11 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
glyph_surface = scaled_glyph->surface;
- /* Create the mask using the format from the first glyph */
+ /* To start, create the mask using the format from the first
+ * glyph. Later we'll deal with different formats. */
if (mask == NULL) {
- mask = cairo_image_surface_create (glyph_surface->format,
+ mask_format = glyph_surface->format;
+ mask = cairo_image_surface_create (mask_format,
width, height);
if (mask->status) {
status = mask->status;
@@ -1100,10 +1104,51 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
width, height);
if (status)
goto CLEANUP_MASK;
- if (glyph_surface->format == CAIRO_FORMAT_ARGB32)
+ if (mask_format == CAIRO_FORMAT_ARGB32)
pixman_image_set_component_alpha (((cairo_image_surface_t*) mask)->
pixman_image, TRUE);
+ }
+
+ /* If we have glyphs of different formats, then the only thing
+ * we can easily do is to migrate to an A8 mask. This is
+ * sub-optimal if there are any component-alpha ARGB32 glyphs,
+ * but pixman doesn't actually give us anyoperators that will
+ * correctly ADD to a component-alpha mask. So here we are. */
+ if (glyph_surface->format != mask_format &&
+ mask_format != CAIRO_FORMAT_A8)
+ {
+ cairo_surface_t *new_mask;
+ cairo_surface_pattern_t mask_pattern;
+
+ mask_format = CAIRO_FORMAT_A8;
+ new_mask = cairo_image_surface_create (mask_format,
+ width, height);
+ if (new_mask->status) {
+ status = new_mask->status;
+ cairo_surface_destroy (new_mask);
+ goto CLEANUP_MASK;
+ }
+
+ _cairo_pattern_init_for_surface (&mask_pattern, mask);
+
+ status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
+ &mask_pattern.base,
+ NULL,
+ new_mask,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ width, height);
+
+ _cairo_pattern_fini (&mask_pattern.base);
+
+ if (status) {
+ cairo_surface_destroy (new_mask);
+ goto CLEANUP_MASK;
+ }
+ cairo_surface_destroy (mask);
+ mask = new_mask;
}
/* round glyph locations to the nearest pixel */