GUACAMOLE-185: Clip copy/transfer operations to fit source as well as 
destination.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/2de7d017
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/2de7d017
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/2de7d017

Branch: refs/heads/master
Commit: 2de7d017f58b6fdf1e96b872d9ab7e908558ff5b
Parents: 5d5fbb4
Author: Michael Jumper <[email protected]>
Authored: Sun Sep 25 15:52:41 2016 -0700
Committer: Michael Jumper <[email protected]>
Committed: Wed Jan 25 21:05:08 2017 -0800

----------------------------------------------------------------------
 src/common/surface.c | 83 +++++++++++++++++++++++++++++++----------------
 1 file changed, 55 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/2de7d017/src/common/surface.c
----------------------------------------------------------------------
diff --git a/src/common/surface.c b/src/common/surface.c
index 99e91c0..cf5185e 100644
--- a/src/common/surface.c
+++ b/src/common/surface.c
@@ -1247,37 +1247,52 @@ void guac_common_surface_copy(guac_common_surface* src, 
int sx, int sy,
     const guac_layer* src_layer = src->layer;
     const guac_layer* dst_layer = dst->layer;
 
-    guac_common_rect rect;
-    guac_common_rect_init(&rect, dx, dy, w, h);
+    guac_common_rect srect;
+    guac_common_rect_init(&srect, sx, sy, w, h);
 
-    /* Clip operation */
-    __guac_common_clip_rect(dst, &rect, &sx, &sy);
-    if (rect.width <= 0 || rect.height <= 0)
+    /* Clip operation source rect */
+    __guac_common_clip_rect(src, &srect, &dx, &dy);
+    if (srect.width <= 0 || srect.height <= 0)
         goto complete;
 
-    /* Update backing surface first only if destination rect cannot intersect 
source rect */
+    guac_common_rect drect;
+    guac_common_rect_init(&drect, dx, dy,
+            srect.width, srect.height);
+
+    /* Clip operation destination rect */
+    __guac_common_clip_rect(dst, &drect, &srect.x, &srect.y);
+    if (drect.width <= 0 || drect.height <= 0)
+        goto complete;
+
+    /* NOTE: Being the last rectangle to be adjusted, only the width/height of
+     * drect is now correct! */
+
+    /* Update backing surface first only if drect cannot intersect srect */
     if (src != dst) {
-        __guac_common_surface_transfer(src, &sx, &sy, 
GUAC_TRANSFER_BINARY_SRC, dst, &rect);
-        if (rect.width <= 0 || rect.height <= 0)
+        __guac_common_surface_transfer(src, &srect.x, &srect.y,
+                GUAC_TRANSFER_BINARY_SRC, dst, &drect);
+        if (drect.width <= 0 || drect.height <= 0)
             goto complete;
     }
 
     /* Defer if combining */
-    if (__guac_common_should_combine(dst, &rect, 1))
-        __guac_common_mark_dirty(dst, &rect);
+    if (__guac_common_should_combine(dst, &drect, 1))
+        __guac_common_mark_dirty(dst, &drect);
 
     /* Otherwise, flush and draw immediately */
     else {
         __guac_common_surface_flush(dst);
         __guac_common_surface_flush(src);
-        guac_protocol_send_copy(socket, src_layer, sx, sy, rect.width, 
rect.height,
-                                GUAC_COMP_OVER, dst_layer, rect.x, rect.y);
+        guac_protocol_send_copy(socket, src_layer, srect.x, srect.y,
+                drect.width, drect.height, GUAC_COMP_OVER, dst_layer,
+                drect.x, drect.y);
         dst->realized = 1;
     }
 
-    /* Update backing surface last if destination rect can intersect source 
rect */
+    /* Update backing surface last if drect can intersect srect */
     if (src == dst)
-        __guac_common_surface_transfer(src, &sx, &sy, 
GUAC_TRANSFER_BINARY_SRC, dst, &rect);
+        __guac_common_surface_transfer(src, &sx, &sy,
+                GUAC_TRANSFER_BINARY_SRC, dst, &drect);
 
 complete:
 
@@ -1300,37 +1315,49 @@ void guac_common_surface_transfer(guac_common_surface* 
src, int sx, int sy, int
     const guac_layer* src_layer = src->layer;
     const guac_layer* dst_layer = dst->layer;
 
-    guac_common_rect rect;
-    guac_common_rect_init(&rect, dx, dy, w, h);
+    guac_common_rect srect;
+    guac_common_rect_init(&srect, sx, sy, w, h);
 
-    /* Clip operation */
-    __guac_common_clip_rect(dst, &rect, &sx, &sy);
-    if (rect.width <= 0 || rect.height <= 0)
+    /* Clip operation source rect */
+    __guac_common_clip_rect(src, &srect, &dx, &dy);
+    if (srect.width <= 0 || srect.height <= 0)
         goto complete;
 
-    /* Update backing surface first only if destination rect cannot intersect 
source rect */
+    guac_common_rect drect;
+    guac_common_rect_init(&drect, dx, dy,
+            srect.width, srect.height);
+
+    /* Clip operation destination rect */
+    __guac_common_clip_rect(dst, &drect, &srect.x, &srect.y);
+    if (drect.width <= 0 || drect.height <= 0)
+        goto complete;
+
+    /* NOTE: Being the last rectangle to be adjusted, only the width/height of
+     * drect is now correct! */
+
+    /* Update backing surface first only if drect cannot intersect srect */
     if (src != dst) {
-        __guac_common_surface_transfer(src, &sx, &sy, op, dst, &rect);
-        if (rect.width <= 0 || rect.height <= 0)
+        __guac_common_surface_transfer(src, &srect.x, &srect.y, op, dst, 
&drect);
+        if (drect.width <= 0 || drect.height <= 0)
             goto complete;
     }
 
     /* Defer if combining */
-    if (__guac_common_should_combine(dst, &rect, 1))
-        __guac_common_mark_dirty(dst, &rect);
+    if (__guac_common_should_combine(dst, &drect, 1))
+        __guac_common_mark_dirty(dst, &drect);
 
     /* Otherwise, flush and draw immediately */
     else {
         __guac_common_surface_flush(dst);
         __guac_common_surface_flush(src);
-        guac_protocol_send_transfer(socket, src_layer, sx, sy, rect.width,
-                rect.height, op, dst_layer, rect.x, rect.y);
+        guac_protocol_send_transfer(socket, src_layer, srect.x, srect.y,
+                drect.width, drect.height, op, dst_layer, drect.x, drect.y);
         dst->realized = 1;
     }
 
-    /* Update backing surface last if destination rect can intersect source 
rect */
+    /* Update backing surface last if drect can intersect srect */
     if (src == dst)
-        __guac_common_surface_transfer(src, &sx, &sy, op, dst, &rect);
+        __guac_common_surface_transfer(src, &srect.x, &srect.y, op, dst, 
&drect);
 
 complete:
 

Reply via email to