From 3ce96e58ac697899f5856b244af4fe7dd6abdaff Mon Sep 17 00:00:00 2001
From: Christopher Chavez <chrischavez@gmx.us>
Date: Thu, 13 Aug 2020 20:51:30 -0500
Subject: [PATCH 5/6] Simplify TkMacOSXDrawCGImage()

Remove the imageBounds and srcBounds parameters); only support
drawing the entire source image. The source image must now be cropped
(e.g. with CGImageCreateWithImageInRect()) prior to calling this
function. (XPutImage() was the only caller requiring cropping logic
to be added; other callers could crop the source using
TkMacOSXCreateCGImageFromDrawableRect().)

The image is implicitly rescaled by CGContextDrawImage() if
dstBounds.size does not equal the source image's size. (Existing
arguments for imagesBounds were invalid for non-pixmap sources,
since the MacDrawable size.width and size.height were nonzero only
for pixmaps, causing TkMacOSXDrawCGImage() to complain with
"Mismatch of sub CGImage bounds.")
---
 macosx/tkMacOSXDraw.c    | 45 +++++++---------------------------------
 macosx/tkMacOSXImage.c   | 18 +++++++++-------
 macosx/tkMacOSXPrivate.h |  3 +--
 3 files changed, 20 insertions(+), 46 deletions(-)

diff --git macosx/tkMacOSXDraw.c macosx/tkMacOSXDraw.c
index 2f0d3d458..339a527cf 100644
--- macosx/tkMacOSXDraw.c
+++ macosx/tkMacOSXDraw.c
@@ -270,9 +270,8 @@ XCopyArea(
     int dest_y)
 {
     TkMacOSXDrawingContext dc;
-    MacDrawable *srcDraw = (MacDrawable *) src;
     CGImageRef img = NULL;
-    CGRect bounds, srcRect, dstRect;
+    CGRect dstRect;
 
     display->request++;
     if (!width || !height) {
@@ -289,21 +288,13 @@ XCopyArea(
 	return BadDrawable;
     }
 
-    if (srcDraw->flags & TK_IS_PIXMAP) {
-	img = TkMacOSXCreateCGImageWithDrawable(src);
-    } else if (TkMacOSXDrawableWindow(src)) {
-	img = TkMacOSXCreateCGImageFromDrawableRect(src,
-		src_x, src_y, width, height);
-    } else {
-	TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
-    }
+    img = TkMacOSXCreateCGImageFromDrawableRect(src,
+	    src_x, src_y, width, height);
 
     if (img) {
-	bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
-	srcRect = CGRectMake(src_x, src_y, width, height);
 	dstRect = CGRectMake(dest_x, dest_y, width, height);
 	TkMacOSXDrawCGImage(dst, gc, dc.context, img,
-		gc->foreground, gc->background, bounds, srcRect, dstRect);
+		gc->foreground, gc->background, dstRect);
 	CFRelease(img);
     } else {
 	TkMacOSXDbgMsg("Failed to construct CGImage.");
@@ -348,7 +339,7 @@ XCopyPlane(
     TkMacOSXDrawingContext dc;
     MacDrawable *srcDraw = (MacDrawable *) src;
     MacDrawable *dstDraw = (MacDrawable *) dst;
-    CGRect bounds, srcRect, dstRect;
+    CGRect srcRect, dstRect;
     display->request++;
     if (!width || !height) {
 	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
@@ -414,13 +405,9 @@ XCopyPlane(
 		    CGImageRelease(submask);
 		    CGImageRelease(subimage);
 		} else {
-		    bounds = CGRectMake(0, 0,
-			    srcDraw->size.width, srcDraw->size.height);
-		    srcRect = CGRectMake(src_x, src_y, width, height);
 		    dstRect = CGRectMake(dest_x, dest_y, width, height);
 		    TkMacOSXDrawCGImage(dst, gc, dc.context, img,
-			    gc->foreground, imageBackground, bounds,
-			    srcRect, dstRect);
+			    gc->foreground, imageBackground, dstRect);
 		    CGImageRelease(img);
 		}
 	    } else {
@@ -651,7 +638,8 @@ TkMacOSXGetCGContextForDrawable(
  *
  * TkMacOSXDrawCGImage --
  *
- *	Draw CG image into drawable.
+ *	Draw CG image into drawable. The entire image is used, and will
+ *	be rescaled if its dimensions do not equal dstBounds.size.
  *
  * Results:
  *	None.
@@ -670,25 +658,11 @@ TkMacOSXDrawCGImage(
     CGImageRef image,
     unsigned long imageForeground,
     unsigned long imageBackground,
-    CGRect imageBounds,
-    CGRect srcBounds,
     CGRect dstBounds)
 {
     MacDrawable *macDraw = (MacDrawable *) d;
 
     if (macDraw && context && image) {
-	CGImageRef subImage = NULL;
-
-	if (!CGRectEqualToRect(imageBounds, srcBounds)) {
-	    if (!CGRectContainsRect(imageBounds, srcBounds)) {
-		TkMacOSXDbgMsg("Mismatch of sub CGImage bounds");
-	    }
-	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
-		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
-	    if (subImage) {
-		image = subImage;
-	    }
-	}
 	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);
 	if (CGImageIsMask(image)) {
 	    if (macDraw->flags & TK_IS_BW_PIXMAP) {
@@ -737,9 +711,6 @@ TkMacOSXDrawCGImage(
 	CGContextDrawImage(context, dstBounds, image);
 	CGContextRestoreGState(context);
 #endif /* TK_MAC_DEBUG_IMAGE_DRAWING */
-	if (subImage) {
-	    CFRelease(subImage);
-	}
     } else {
 	TkMacOSXDbgMsg("Drawing of empty CGImage requested");
     }
diff --git macosx/tkMacOSXImage.c macosx/tkMacOSXImage.c
index 3c8530505..0654825a5 100644
--- macosx/tkMacOSXImage.c
+++ macosx/tkMacOSXImage.c
@@ -527,8 +527,16 @@ XPutImage(
 	return BadDrawable;
     }
     if (dc.context) {
-	CGRect bounds, srcRect, dstRect;
+	CGRect dstRect, srcRect = CGRectMake(src_x, src_y, width, height);
+	/*
+	 * Whole image is copied before cropping. For performance,
+	 * consider revising TkMacOSXCreateCGImageWithXImage() to accept
+	 * source x/y/w/h and copy only the needed portion instead.
+	 */
 	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);
+	CGImageRef cropped = CGImageCreateWithImageInRect(img, srcRect);
+	CGImageRelease(img);
+	img = cropped;
 
 	/*
 	 * The CGContext for a pixmap is RGB only, with A = 0.
@@ -538,13 +546,9 @@ XPutImage(
 	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
 	}
 	if (img) {
-
-	    bounds = CGRectMake(0, 0, image->width, image->height);
-	    srcRect = CGRectMake(src_x, src_y, width, height);
 	    dstRect = CGRectMake(dest_x, dest_y, width, height);
-	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
-				img, gc->foreground, gc->background,
-				bounds, srcRect, dstRect);
+	    TkMacOSXDrawCGImage(drawable, gc, dc.context, img,
+				gc->foreground, gc->background, dstRect);
 	    CFRelease(img);
 	} else {
 	    TkMacOSXDbgMsg("Invalid source drawable");
diff --git macosx/tkMacOSXPrivate.h macosx/tkMacOSXPrivate.h
index f3900ee33..2b71434d1 100644
--- macosx/tkMacOSXPrivate.h
+++ macosx/tkMacOSXPrivate.h
@@ -272,8 +272,7 @@ MODULE_SCOPE CGImageRef	TkMacOSXCreateCGImageFromDrawableRect(Drawable drawable,
 MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image);
 MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
 			    CGImageRef image, unsigned long imageForeground,
-			    unsigned long imageBackground, CGRect imageBounds,
-			    CGRect srcBounds, CGRect dstBounds);
+			    unsigned long imageBackground, CGRect dstBounds);
 MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
 			    int useCG, TkMacOSXDrawingContext *dcPtr);
 MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
-- 
2.28.0

