[cairo] patch [1/1] invert image in _cairo_gl_surrface_map_to_image
Henry (Yu) Song - SISA
hsong at sisa.samsung.com
Tue Jan 3 16:56:08 PST 2012
Date: Fri Dec 30 11:24:54 2011 -0800
gl: Add support to invert non texture gl surface image that does not have
GL_MESA_pack_invert when map from gl surface to image surface
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 8f69033..8b8f196 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -1001,6 +1001,10 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
unsigned int cpp;
cairo_bool_t invert;
cairo_status_t status;
+ cairo_t *inv_cr = NULL;
+ cairo_image_surface_t *inv_image = NULL;
+ cairo_pattern_t *inv_pattern = NULL;
+ cairo_matrix_t inv_matrix;
/* Want to use a switch statement here but the compiler gets whiny. */
if (surface->base.content == CAIRO_CONTENT_COLOR_ALPHA) {
@@ -1093,6 +1097,50 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
image = (cairo_image_surface_t *)
_cairo_surface_create_in_error (status);
}
+
+ /*
+ * FIXME: we must invert the image if it is non texture surface,
+ * and it does not have GL_MESA_pack_invert.
+ * Is there more efficient way to invert image?
+ */
+
+ if (! _cairo_gl_surface_is_texture (surface) && ! invert) {
+ inv_image = (cairo_image_surface_t*)
+ _cairo_image_surface_create_with_pixman_format (NULL,
+ pixman_format,
+ extents->width,
+ extents->height,
+ -1);
+ if (unlikely (inv_image->base.status)) {
+ goto CLEAR_IMAGE;
+ }
+
+ image->base.is_clear = FALSE;
+ inv_pattern = cairo_pattern_create_for_surface (&image->base);
+ if (unlikely (inv_pattern->status)) {
+ goto CLEAR_PATTERN;
+ }
+ cairo_matrix_init_scale (&inv_matrix, 1.0, -1.0);
+ cairo_matrix_translate (&inv_matrix, 0, -(extents->height));
+ cairo_pattern_set_matrix (inv_pattern, &inv_matrix);
+
+ inv_cr = cairo_create (&inv_image->base);
+ if (unlikely (inv_cr->status)) {
+ goto CLEAR_CAIRO;
+ }
+ cairo_set_source (inv_cr, inv_pattern);
+ cairo_set_operator (inv_cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (inv_cr);
+ cairo_surface_destroy (&image->base);
+ image = (cairo_image_surface_t *)cairo_surface_reference (&inv_image->base);
+ }
+
+CLEAR_CAIRO:
+ cairo_destroy (inv_cr);
+CLEAR_PATTERN:
+ cairo_pattern_destroy (inv_pattern);
+CLEAR_IMAGE:
+ cairo_surface_destroy (&inv_image->base);
return &image->base;
}
More information about the cairo
mailing list