From 3e69c38fe642be467fee0cad166b83006741d55c Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Sun, 24 Jan 2010 21:59:32 +0100 Subject: [PATCH] [quartz] Fix surface to CGImage conversion Snapshotting a surface doesn't produce a cairo_image_surface_t. Acquiring (and later releasing) the surface is needed to access its image data. --- src/cairo-quartz-surface.c | 73 +++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index a7a94b454..904cbb8f2 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -920,11 +920,18 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface, /* Obtain a CGImageRef from a #cairo_surface_t * */ +typedef struct { + cairo_surface_t *surface; + cairo_image_surface_t *image_out; + void *image_extra; +} quartz_source_image_t; + static void DataProviderReleaseCallback (void *info, const void *data, size_t size) { - cairo_surface_t *surface = (cairo_surface_t *) info; - cairo_surface_destroy (surface); + quartz_source_image_t *source_img = info; + _cairo_surface_release_source_image (source_img->surface, source_img->image_out, source_img->image_extra); + free (source_img); } static cairo_status_t @@ -932,11 +939,9 @@ _cairo_surface_to_cgimage (cairo_surface_t *target, cairo_surface_t *source, CGImageRef *image_out) { - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_surface_type_t stype = cairo_surface_get_type (source); - cairo_image_surface_t *isurf; - CGImageRef image; - void *image_extra; + cairo_status_t status; + quartz_source_image_t *source_img; + cairo_surface_type_t stype = source->backend->type; if (stype == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) { cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source; @@ -958,43 +963,39 @@ _cairo_surface_to_cgimage (cairo_surface_t *target, } } - if (stype != CAIRO_SURFACE_TYPE_IMAGE) { - status = _cairo_surface_acquire_source_image (source, - &isurf, &image_extra); - if (status) - return status; - } else { - isurf = (cairo_image_surface_t *) source; + source_img = malloc (sizeof (quartz_source_image_t)); + if (source_img == NULL) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + source_img->surface = source; + + status = _cairo_surface_acquire_source_image (source_img->surface, &source_img->image_out, &source_img->image_extra); + if (status) { + free (source_img); + return status; } - if (isurf->width == 0 || isurf->height == 0) { + if (source_img->image_out->width == 0 || source_img->image_out->height == 0) { *image_out = NULL; + DataProviderReleaseCallback (source_img, + source_img->image_out->data, + source_img->image_out->height * source_img->image_out->stride); } else { - cairo_image_surface_t *isurf_snap = NULL; + *image_out = _cairo_quartz_create_cgimage (source_img->image_out->format, + source_img->image_out->width, + source_img->image_out->height, + source_img->image_out->stride, + source_img->image_out->data, + TRUE, + NULL, + DataProviderReleaseCallback, + source_img); - isurf_snap = (cairo_image_surface_t*) - _cairo_surface_snapshot (&isurf->base); - if (isurf_snap->base.status) - return isurf_snap->base.status; - - image = _cairo_quartz_create_cgimage (isurf_snap->format, - isurf_snap->width, - isurf_snap->height, - isurf_snap->stride, - isurf_snap->data, - TRUE, - NULL, - DataProviderReleaseCallback, - isurf_snap); - - *image_out = image; - if (image == NULL) + /* TODO: differentiate memory error and unsupported surface type */ + if (*image_out == NULL) status = CAIRO_INT_STATUS_UNSUPPORTED; } - if (&isurf->base != source) - _cairo_surface_release_source_image (source, isurf, image_extra); - return status; }