[cairo-commit] src/cairo-image-surface.c src/cairo-image-surface-private.h

Chris Wilson ickle at kemper.freedesktop.org
Fri Feb 1 08:36:11 PST 2013


 src/cairo-image-surface-private.h |    7 ++++
 src/cairo-image-surface.c         |   55 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

New commits:
commit c391093f40472c2300f38d0e5857858f85586b60
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Feb 1 16:31:49 2013 +0000

    image: Add a convenience function for creating an image from another's data
    
    The GL backend would like to extract a rectangle from another surface
    and convert it to a different pixel format. The
    _cairo_image_surface_create_from_image() does that by returning a new
    image that has the contents of the specified rectangle in the source
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-image-surface-private.h b/src/cairo-image-surface-private.h
index 6a159d8..8ca694c 100644
--- a/src/cairo-image-surface-private.h
+++ b/src/cairo-image-surface-private.h
@@ -226,6 +226,13 @@ cairo_private cairo_image_surface_t *
 _cairo_image_surface_clone_subimage (cairo_surface_t             *surface,
 				     const cairo_rectangle_int_t *extents);
 
+/* Similar to clone; but allow format conversion */
+cairo_private cairo_image_surface_t *
+_cairo_image_surface_create_from_image (cairo_image_surface_t *other,
+					pixman_format_code_t format,
+					int x, int y, int width, int height,
+					int stride);
+
 CAIRO_END_DECLS
 
 #endif /* CAIRO_IMAGE_SURFACE_PRIVATE_H */
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 20a1c03..49f6e18 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1088,6 +1088,61 @@ _cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface,
     return clone;
 }
 
+cairo_image_surface_t *
+_cairo_image_surface_create_from_image (cairo_image_surface_t *other,
+					pixman_format_code_t format,
+					int x, int y,
+					int width, int height, int stride)
+{
+    cairo_image_surface_t *surface;
+    cairo_status_t status;
+    pixman_image_t *image;
+    void *mem = NULL;
+
+    status = other->base.status;
+    if (unlikely (status))
+	goto cleanup;
+
+    if (stride) {
+	mem = _cairo_malloc_ab (height, stride);
+	if (unlikely (mem == NULL)) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    goto cleanup;
+	}
+    }
+
+    image = pixman_image_create_bits (format, width, height, mem, stride);
+    if (unlikely (image == NULL)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto cleanup_mem;
+    }
+
+    surface = (cairo_image_surface_t *)
+	_cairo_image_surface_create_for_pixman_image (image, format);
+    if (unlikely (surface->base.status)) {
+	status = surface->base.status;
+	goto cleanup_image;
+    }
+
+    pixman_image_composite32 (PIXMAN_OP_SRC,
+                              other->pixman_image, NULL, image,
+                              x, y,
+                              0, 0,
+                              0, 0,
+                              width, height);
+    surface->base.is_clear = FALSE;
+    surface->owns_data = mem != NULL;
+
+    return surface;
+
+cleanup_image:
+    pixman_image_unref (image);
+cleanup_mem:
+    free (mem);
+cleanup:
+    return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
+}
+
 cairo_image_transparency_t
 _cairo_image_analyze_transparency (cairo_image_surface_t *image)
 {


More information about the cairo-commit mailing list