diff options
author | monojenkins <jo.shields+jenkins@xamarin.com> | 2020-07-24 12:00:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-24 12:00:28 +0300 |
commit | f44d61c9bc7bd75ffb3afa867b1b1dacc3e4cf70 (patch) | |
tree | 0870ea50caa9fa38a7cd5ef1af1b918cdc52b10a | |
parent | 1722231c68d6fd5f505e89a2d33b50e9bb0fb3dc (diff) |
[Cairo] Fix Cairo on BigSur (#163)2019-12
BigSur's CoreGraphics seems to need a copy of the data to stick around longer than the surface,
so we provide it a copy of the data instead.
Co-authored-by: iain holmes <iain@xamarin.com>
-rw-r--r-- | packages/cairo.py | 1 | ||||
-rw-r--r-- | packages/patches/cairo-bigsur.patch | 122 |
2 files changed, 123 insertions, 0 deletions
diff --git a/packages/cairo.py b/packages/cairo.py index 9a3aa92..da0960f 100644 --- a/packages/cairo.py +++ b/packages/cairo.py @@ -6,6 +6,7 @@ class CairoPackage (CairoGraphicsXzPackage): 'patches/cairo-quartz-crash.patch', 'patches/cairo-fix-color-bitmap-fonts.patch', 'patches/cairo-fix-CGFontGetGlyphPath-deprecation.patch', + 'patches/cairo-bigsur.patch', # 'patches/cairo-cglayer.patch', ]) diff --git a/packages/patches/cairo-bigsur.patch b/packages/patches/cairo-bigsur.patch new file mode 100644 index 0000000..ba0276b --- /dev/null +++ b/packages/patches/cairo-bigsur.patch @@ -0,0 +1,122 @@ +diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c +index 1e2bbec..f096e8d 100644 +--- a/src/cairo-quartz-surface.c ++++ b/src/cairo-quartz-surface.c +@@ -211,8 +211,13 @@ CairoQuartzCreateCGImage (cairo_format_t format, + return NULL; + } + ++ void *data_copy = malloc (height * stride); ++ if (unlikely (!data_copy)) ++ return NULL; ++ memcpy (data_copy, data, height * stride); ++ + dataProvider = CGDataProviderCreateWithData (releaseInfo, +- data, ++ data_copy, + height * stride, + releaseCallback); + +@@ -768,18 +773,10 @@ CairoQuartzCreateGradientFunction (const cairo_gradient_pattern_t *gradient, + + /* 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) + { +- 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); ++ free (data); + } + + static cairo_status_t +@@ -791,7 +788,6 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, + CGImageRef *image_out) + { + cairo_status_t status; +- quartz_source_image_t *source_img; + cairo_image_surface_t *image_surface; + + if (source->backend && source->backend->type == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) { +@@ -814,11 +810,8 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, + } + } + +- source_img = malloc (sizeof (quartz_source_image_t)); +- if (unlikely (source_img == NULL)) +- return _cairo_error (CAIRO_STATUS_NO_MEMORY); +- +- source_img->surface = source; ++ cairo_image_surface_t *cimage_out; ++ void *image_extra; + + if (source->type == CAIRO_SURFACE_TYPE_RECORDING) { + image_surface = (cairo_image_surface_t *) +@@ -826,7 +819,6 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, + if (unlikely (image_surface->base.status)) { + status = image_surface->base.status; + cairo_surface_destroy (&image_surface->base); +- free (source_img); + return status; + } + +@@ -836,40 +828,35 @@ _cairo_surface_to_cgimage (cairo_surface_t *source, + NULL); + if (unlikely (status)) { + cairo_surface_destroy (&image_surface->base); +- free (source_img); + return status; + } + +- source_img->image_out = image_surface; +- source_img->image_extra = NULL; ++ cimage_out = image_surface; ++ image_extra = NULL; + + cairo_matrix_init_identity (matrix); + } + else { +- status = _cairo_surface_acquire_source_image (source_img->surface, +- &source_img->image_out, +- &source_img->image_extra); ++ status = _cairo_surface_acquire_source_image (source, ++ &cimage_out, ++ &image_extra); + if (unlikely (status)) { +- free (source_img); + return status; + } + } + +- if (source_img->image_out->width == 0 || source_img->image_out->height == 0) { ++ if (cimage_out->width == 0 || cimage_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 { +- *image_out = CairoQuartzCreateCGImage (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, ++ *image_out = CairoQuartzCreateCGImage (cimage_out->format, ++ cimage_out->width, ++ cimage_out->height, ++ cimage_out->stride, ++ cimage_out->data, + TRUE, + NULL, + DataProviderReleaseCallback, +- source_img); ++ NULL); + + /* TODO: differentiate memory error and unsupported surface type */ + if (unlikely (*image_out == NULL)) |