[cairo] patch: gl - invert image during map_to_image() in cairo-gl-surface.c

Henry (Yu) Song - SISA hsong at sisa.samsung.com
Thu Mar 15 09:48:46 PDT 2012


I tried to use negative stride as suggested by andrea and experimented his approach as his code sample shows.  However, the image came out is still inverted.  So I decided use matrix translation.

commit 080f4e082b45a320296fe10d6816a3b3d22c5e32
Author: Henry Song <henry.song at samsung.com>
Date:   Thu Mar 15 09:43:19 2012 -0700

    gl: invert image in map_to_image() when the gl surface is non-texture and
    GL does not support GLX_MESA_pack_invert

diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 43e4bfc..7e86da2 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -1075,6 +1075,48 @@ _cairo_gl_surface_map_to_image (void      *abstract_surface,
 	    _cairo_surface_create_in_error (status);
     }
 
+    /* We must invert image if it is non-texture surface and it does
+     * not support GL_MESA_pack_invert
+     */
+    if (! _cairo_gl_surface_is_texture (surface) && ! invert) {
+	cairo_matrix_t inv_matrix;
+	cairo_image_surface_t *inv_image;
+	cairo_t *inv_cr;
+
+	int inv_width = cairo_image_surface_get_width (&image->base);
+	int inv_height = cairo_image_surface_get_height (&image->base);
+	cairo_format_t inv_format = cairo_image_surface_get_format (&image->base);
+	int inv_stride = cairo_format_stride_for_width (inv_format,
+							inv_width);
+	
+	cairo_pattern_t *inv_pattern = cairo_pattern_create_for_surface (&image->base);
+	if (unlikely (inv_pattern->status)) {
+	    cairo_pattern_destroy (inv_pattern);
+	    return &image->base;
+	}
+	
+	inv_image = (cairo_image_surface_t *)
+		cairo_image_surface_create_for_data (NULL, inv_format,
+						     inv_width,
+						     inv_height,
+						     inv_stride);
+
+	cairo_matrix_init_scale (&inv_matrix, 1.0, -1.0);
+	cairo_matrix_translate (&inv_matrix, 0, -inv_height);
+	cairo_pattern_set_matrix (inv_pattern, &inv_matrix);
+
+	image->base.is_clear = FALSE;
+	inv_cr = cairo_create (&inv_image->base);
+	cairo_set_source (inv_cr, inv_pattern);
+	cairo_set_operator (inv_cr, CAIRO_OPERATOR_SOURCE);
+	cairo_paint (inv_cr);
+
+	cairo_destroy (inv_cr);
+	cairo_pattern_destroy (inv_pattern);
+	cairo_surface_destroy (&image->base);
+	image = inv_image;
+    }
+
     return &image->base;
 }
 


More information about the cairo mailing list