chiark / gitweb /
Rewrite trim_rect() for robustness.
authorSimon Tatham <anakin@pobox.com>
Mon, 1 Apr 2013 16:23:03 +0000 (16:23 +0000)
committerSimon Tatham <anakin@pobox.com>
Mon, 1 Apr 2013 16:23:03 +0000 (16:23 +0000)
The previous version dealt adequately with rectangles _partially_
overlapping the edge of the canvas, but doesn't correctly handle a
rectangle that's completely out of bounds in one direction. Replace
with a complete rewrite which is more easily seen to be correct. Also,
while I'm at it, add a missing condition to draw_update() so that we
don't even bother calling the Javascript half of it on any rectangle
that's been trimmed into nonexistence.

[originally from svn r9800]

emcc.c

diff --git a/emcc.c b/emcc.c
index c393c34d7b717e87467c7f7a4d2275d323ea9b67..3cb92f00d7feaad1085f64ceb20bd5c77cf912e7 100644 (file)
--- a/emcc.c
+++ b/emcc.c
@@ -416,27 +416,30 @@ static void js_blitter_free(void *handle, blitter *bl)
 
 static void trim_rect(int *x, int *y, int *w, int *h)
 {
+    int x0, x1, y0, y1;
+
     /*
      * Reduce the size of the copied rectangle to stop it going
      * outside the bounds of the canvas.
      */
-    if (*x < 0) {
-        *w += *x;
-        *x = 0;
-    }
-    if (*y < 0) {
-        *h += *y;
-        *y = 0;
-    }
-    if (*w > canvas_w - *x)
-        *w = canvas_w - *x;
-    if (*h > canvas_h - *y)
-        *h = canvas_h - *y;
 
-    if (*w < 0)
-        *w = 0;
-    if (*h < 0)
-        *h = 0;
+    /* Transform from x,y,w,h form into coordinates of all edges */
+    x0 = *x;
+    y0 = *y;
+    x1 = *x + *w;
+    y1 = *y + *h;
+
+    /* Clip each coordinate at both extremes of the canvas */
+    x0 = (x0 < 0 ? 0 : x0 > canvas_w ? canvas_w : x0);
+    x1 = (x1 < 0 ? 0 : x1 > canvas_w ? canvas_w : x1);
+    y0 = (y0 < 0 ? 0 : y0 > canvas_h ? canvas_h : y0);
+    y1 = (y1 < 0 ? 0 : y1 > canvas_h ? canvas_h : y1); 
+
+    /* Transform back into x,y,w,h to return */
+    *x = x0;
+    *y = y0;
+    *w = x1 - x0;
+    *h = y1 - y0;
 }
 
 static void js_blitter_save(void *handle, blitter *bl, int x, int y)
@@ -458,7 +461,8 @@ static void js_blitter_load(void *handle, blitter *bl, int x, int y)
 static void js_draw_update(void *handle, int x, int y, int w, int h)
 {
     trim_rect(&x, &y, &w, &h);
-    js_canvas_draw_update(x, y, w, h);
+    if (w > 0 && h > 0)
+        js_canvas_draw_update(x, y, w, h);
 }
 
 static void js_end_draw(void *handle)