GNUstep compatibility: avoid attempting blitter_save with a partially
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 6 May 2012 14:01:36 +0000 (14:01 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 6 May 2012 14:01:36 +0000 (14:01 +0000)
out-of-bounds rectangle. Instead, take the intersection of the
rectangle with the window boundary and do a smaller operation on
what's left.

git-svn-id: svn://svn.tartarus.org/sgt/puzzles@9503 cda61777-01e9-0310-a592-d414129be87e

osx.m

diff --git a/osx.m b/osx.m
index 1794cf9..fdcef1e 100644 (file)
--- a/osx.m
+++ b/osx.m
@@ -1421,11 +1421,42 @@ static void osx_blitter_free(void *handle, blitter *bl)
 static void osx_blitter_save(void *handle, blitter *bl, int x, int y)
 {
     frontend *fe = (frontend *)handle;
+    int sx, sy, sX, sY, dx, dy, dX, dY;
     [fe->image unlockFocus];
     [bl->img lockFocus];
-    [fe->image drawInRect:NSMakeRect(0, 0, bl->w, bl->h)
-       fromRect:NSMakeRect(x, fe->h - y - bl->h, bl->w, bl->h)
-       operation:NSCompositeCopy fraction:1.0];
+
+    /*
+     * Find the intersection of the source and destination rectangles,
+     * so as to avoid trying to copy from outside the source image,
+     * which GNUstep dislikes.
+     *
+     * Lower-case x,y coordinates are bottom left box corners;
+     * upper-case X,Y are the top right.
+     */
+    sx = x; sy = fe->h - y - bl->h;
+    sX = sx + bl->w; sY = sy + bl->h;
+    dx = dy = 0;
+    dX = bl->w; dY = bl->h;
+    if (sx < 0) {
+        dx += -sx;
+        sx = 0;
+    }
+    if (sy < 0) {
+        dy += -sy;
+        sy = 0;
+    }
+    if (sX > fe->w) {
+        dX -= (sX - fe->w);
+        sX = fe->w;
+    }
+    if (sY > fe->h) {
+        dY -= (sY - fe->h);
+        sY = fe->h;
+    }
+
+    [fe->image drawInRect:NSMakeRect(dx, dy, dX-dx, dY-dy)
+                 fromRect:NSMakeRect(sx, sy, sX-sx, sY-sy)
+                operation:NSCompositeCopy fraction:1.0];
     [bl->img unlockFocus];
     [fe->image lockFocus];
     bl->x = x;