diff options
author | John Ralls <jralls@ceridwen.us> | 2020-11-30 15:13:41 -0800 |
---|---|---|
committer | John Ralls <jralls@ceridwen.us> | 2020-12-03 10:59:04 -0800 |
commit | b5e84a97833e8e1d082f4409383b09f9827ada09 (patch) | |
tree | 0724f46ef256a14e91b3defb92f0fda932810c71 /src/cairo-quartz-surface.c | |
parent | 32c12c617a2551e1238e52c570bd5c42a6c0cbef (diff) | |
download | cairo-b5e84a97833e8e1d082f4409383b09f9827ada09.tar.gz |
Quartz: Ensure that image data and surface are available to draw.
Snapshot the cairo_surface_t and copy the image data to provide to
the CGDataProvider so that it is independent of the cairo_surface_t's
lifetime.
Closes https://gitlab.freedesktop.org/cairo/cairo/-/issues/420
Diffstat (limited to 'src/cairo-quartz-surface.c')
-rw-r--r-- | src/cairo-quartz-surface.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index f697d157e..2fa376bb8 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -784,6 +784,7 @@ typedef struct { cairo_surface_t *surface; cairo_image_surface_t *image_out; void *image_extra; + void *image_data; } quartz_source_image_t; static void @@ -791,6 +792,8 @@ DataProviderReleaseCallback (void *info, const void *data, size_t size) { quartz_source_image_t *source_img = info; _cairo_surface_release_source_image (source_img->surface, source_img->image_out, source_img->image_extra); + cairo_surface_destroy (source_img->surface); + free (source_img->image_data); free (source_img); } @@ -830,7 +833,7 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, if (unlikely (source_img == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - source_img->surface = source; + source_img->surface = _cairo_surface_snapshot (source); if (source->type == CAIRO_SURFACE_TYPE_RECORDING) { image_surface = (cairo_image_surface_t *) @@ -853,7 +856,7 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, } source_img->image_out = image_surface; - source_img->image_extra = NULL; + source_img->image_data = NULL; cairo_matrix_init_identity (matrix); } @@ -867,6 +870,12 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, } } + source_img->image_data = malloc (source_img->image_out->height * source_img->image_out->stride); + if (unlikely (!source_img->image_data)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + memcpy (source_img->image_data, source_img->image_out->data, + source_img->image_out->height * source_img->image_out->stride); if (source_img->image_out->width == 0 || source_img->image_out->height == 0) { *image_out = NULL; DataProviderReleaseCallback (source_img, @@ -877,7 +886,7 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, source_img->image_out->width, source_img->image_out->height, source_img->image_out->stride, - source_img->image_out->data, + source_img->image_data, TRUE, NULL, DataProviderReleaseCallback, |