[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