[cairo-commit] Branch '1.4' - src/cairo-scaled-font.c

Carl Worth cworth at kemper.freedesktop.org
Fri Jan 11 12:58:34 PST 2008


 src/cairo-scaled-font.c |   51 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 3 deletions(-)

New commits:
commit 35ed062a6269feeebae70c98000b60630a9ec3bd
Author: Carl Worth <cworth at cworth.org>
Date:   Fri Jan 11 12:28:49 2008 -0800

    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

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ef70a38..256899b 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 */


More information about the cairo-commit mailing list