[quartz] ensure that the copy region is fully enclosed by the drawn surface.

This commit is contained in:
John Ralls
2022-06-05 15:23:56 -07:00
parent 8d4c4cdca4
commit a5ad547b8b

View File

@ -351,20 +351,22 @@ cairo_rect_from_nsrect (cairo_rectangle_int_t *rect, NSRect *nsrect)
static cairo_status_t
copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
cairo_rectangle_int_t *rect)
cairo_region_t *region)
{
cairo_surface_t *source_img, *dest_img;
cairo_status_t status;
cairo_format_t format;
int height, width, stride;
cairo_rectangle_int_t extents;
source_img = cairo_surface_map_to_image (source, rect);
cairo_region_get_extents (region, &extents);
source_img = cairo_surface_map_to_image (source, &extents);
status = cairo_surface_status (source_img);
if (status)
{
g_warning ("Failed to map source image surface, %d %d %d %d on %d %d: %s\n",
rect->x, rect->y, rect->width, rect->height,
extents.x, extents.y, extents.width, extents.height,
cairo_image_surface_get_width (source),
cairo_image_surface_get_height (source),
cairo_status_to_string (status));
@ -372,13 +374,13 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
}
format = cairo_image_surface_get_format (source_img);
dest_img = cairo_surface_map_to_image (dest, rect);
dest_img = cairo_surface_map_to_image (dest, &extents);
status = cairo_surface_status (dest_img);
if (status)
{
g_warning ("Failed to map destination image surface, %d %d %d %d on %d %d: %s\n",
rect->x, rect->y, rect->width, rect->height,
extents.x, extents.y, extents.width, extents.height,
cairo_image_surface_get_width (dest),
cairo_image_surface_get_height (dest),
cairo_status_to_string (status));
@ -401,17 +403,19 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
-(void)updateLayer
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (gdk_window->impl);
cairo_rectangle_int_t impl_rect = {0, 0, 0, 0};
CGRect layer_bounds = [self.layer bounds];
CGRect backing_bounds = [self convertRectToBacking: layer_bounds];
cairo_rectangle_int_t extents;
cairo_rectangle_int_t bounds_rect;
cairo_region_t *bounds_region;
cairo_surface_t *cvpb_surface;
if (GDK_WINDOW_DESTROYED (gdk_window))
return;
++impl->in_paint_rect_count;
cairo_rect_from_nsrect (&extents, &backing_bounds);
cairo_rect_from_nsrect (&bounds_rect, &backing_bounds);
bounds_region = cairo_region_create_rectangle (&bounds_rect);
if (impl->needs_display_region)
{
cairo_region_t *region = impl->needs_display_region;
@ -433,6 +437,8 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
if (!impl || !impl->cairo_surface)
return;
impl_rect.width = cairo_image_surface_get_width (impl->cairo_surface);
impl_rect.height = cairo_image_surface_get_height (impl->cairo_surface);
CVPixelBufferLockBaseAddress (pixels, 0);
cvpb_surface =
cairo_image_surface_create_for_data (CVPixelBufferGetBaseAddress (pixels),
@ -441,9 +447,12 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
(int)CVPixelBufferGetHeight (pixels),
(int)CVPixelBufferGetBytesPerRow (pixels));
copy_rectangle_argb32 (cvpb_surface, impl->cairo_surface, &extents);
cairo_region_intersect_rectangle (bounds_region, &impl_rect);
copy_rectangle_argb32 (cvpb_surface, impl->cairo_surface, bounds_region);
cairo_surface_destroy (cvpb_surface);
cairo_region_destroy (bounds_region);
_gdk_quartz_unref_cairo_surface (gdk_window);
CVPixelBufferUnlockBaseAddress (pixels, 0);
--impl->in_paint_rect_count;