From d29d90b13471405544045d651341fba208b9bd1d Mon Sep 17 00:00:00 2001
From: MoyuScript <i@moyu.moe>
Date: Thu, 3 Jan 2013 18:37:27 +0200
Subject: [PATCH] refactored border radius calculation

---
 src/Parse.js                   | 170 ++++++++++++++++++---------------
 tests/cases/border/radius.html |   3 +-
 2 files changed, 96 insertions(+), 77 deletions(-)

diff --git a/src/Parse.js b/src/Parse.js
index 9850ba9..6c70e35 100644
--- a/src/Parse.js
+++ b/src/Parse.js
@@ -475,6 +475,90 @@ _html2canvas.Parse = function (images, options) {
     return borderArgs;
   }
 
+  function getBorderBounds(element) {
+    var backgroundClip = getCSS(element, 'backgroundClip');
+  }
+
+  function calculateCurvePoints(bounds, borderRadius, borders) {
+
+    var x = bounds.left,
+    y = bounds.top,
+    width = bounds.width,
+    height = bounds.height,
+
+    tlh = borderRadius[0][0],
+    tlv = borderRadius[0][1],
+    trh = borderRadius[1][0],
+    trv = borderRadius[1][1],
+    brv = borderRadius[2][0],
+    brh = borderRadius[2][1],
+    blh = borderRadius[3][0],
+    blv = borderRadius[3][1],
+
+    topWidth = width - trh,
+    rightHeight = height - brv,
+    bottomWidth = width - brh,
+    leftHeight = height - blv;
+
+    return {
+      topLeftOuter: getCurvePoints(
+        x,
+        y,
+        tlh,
+        tlv
+        ).topLeft.subdivide(0.5),
+
+      topLeftInner: getCurvePoints(
+        x + borders[3].width,
+        y + borders[0].width,
+        Math.max(0, tlh - borders[3].width),
+        Math.max(0, tlv - borders[0].width)
+        ).topLeft.subdivide(0.5),
+
+      topRightOuter: getCurvePoints(
+        x + topWidth,
+        y,
+        trh,
+        trv
+        ).topRight.subdivide(0.5),
+
+      topRightInner: getCurvePoints(
+        x + Math.min(topWidth, width + borders[3].width),
+        y + borders[0].width,
+        (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width,
+        trv - borders[0].width
+        ).topRight.subdivide(0.5),
+
+      bottomRightOuter: getCurvePoints(
+        x + bottomWidth,
+        y + rightHeight,
+        brh,
+        brv
+        ).bottomRight.subdivide(0.5),
+
+      bottomRightInner: getCurvePoints(
+        x + Math.min(bottomWidth, width + borders[3].width),
+        y + Math.min(rightHeight, height + borders[0].width),
+        Math.max(0, brh - borders[1].width),
+        Math.max(0, brv - borders[2].width)
+        ).bottomRight.subdivide(0.5),
+
+      bottomLeftOuter: getCurvePoints(
+        x,
+        y + leftHeight,
+        blh,
+        blv
+        ).bottomLeft.subdivide(0.5),
+
+      bottomLeftInner: getCurvePoints(
+        x + borders[3].width,
+        y + leftHeight,
+        Math.max(0, blh - borders[3].width),
+        Math.max(0, blv - borders[2].width)
+        ).bottomLeft.subdivide(0.5)
+    }
+  }
+
   function parseBorders(element, ctx, bounds, clip, borders){
     var x = bounds.left,
     y = bounds.top,
@@ -489,78 +573,8 @@ _html2canvas.Parse = function (images, options) {
     borderArgs,
     borderBounds,
     // http://www.w3.org/TR/css3-background/#the-border-radius
-    borderRadius = getBorderRadiusData(element);
-
-
-    var tlh = borderRadius[0][0];
-    var tlv = borderRadius[0][1];
-    var trh = borderRadius[1][0];
-    var trv = borderRadius[1][1];
-    var brv = borderRadius[2][0];
-    var brh = borderRadius[2][1];
-    var blh = borderRadius[3][0];
-    var blv = borderRadius[3][1];
-
-
-    var topWidth = width - trh;
-    var rightHeight = height - brv;
-    var bottomWidth = width - brh;
-    var leftHeight = height - blv;
-
-    var topLeftOuter = getCurvePoints(
-      x,
-      y,
-      tlh,
-      tlv
-      ).topLeft.subdivide(0.5);
-
-    var topLeftInner = getCurvePoints(
-      x + borders[3].width,
-      y + borders[0].width,
-      Math.max(0, tlh - borders[3].width),
-      Math.max(0, tlv - borders[0].width)
-      ).topLeft.subdivide(0.5);
-
-    var topRightOuter = getCurvePoints(
-      x + topWidth,
-      y,
-      trh,
-      trv
-      ).topRight.subdivide(0.5);
-
-    var topRightInner = getCurvePoints(
-      x + Math.min(topWidth, width + borders[3].width),
-      y + borders[0].width,
-      (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width,
-      trv - borders[0].width
-      ).topRight.subdivide(0.5);
-
-    var bottomRightOuter = getCurvePoints(
-      x + bottomWidth,
-      y + rightHeight,
-      brh,
-      brv
-      ).bottomRight.subdivide(0.5);
-    var bottomRightInner = getCurvePoints(
-      x + Math.min(bottomWidth, width + borders[3].width),
-      y + Math.min(rightHeight, height + borders[0].width),
-      Math.max(0, brh - borders[1].width),
-      Math.max(0, brv - borders[2].width)
-      ).bottomRight.subdivide(0.5);
-
-    var bottomLeftOuter = getCurvePoints(
-      x,
-      y + leftHeight,
-      blh,
-      blv
-      ).bottomLeft.subdivide(0.5);
-
-    var bottomLeftInner = getCurvePoints(
-      x + borders[3].width,
-      y + leftHeight,
-      Math.max(0, blh - borders[3].width),
-      Math.max(0, blv - borders[2].width)
-      ).bottomLeft.subdivide(0.5);
+    borderRadius = getBorderRadiusData(element),
+    borderPoints = calculateCurvePoints(bounds, borderRadius, borders);
 
     for (borderSide = 0; borderSide < 4; borderSide++) {
       borderData = borders[borderSide];
@@ -581,7 +595,8 @@ _html2canvas.Parse = function (images, options) {
               c2: [bx + bw, by],
               c3: [bx + bw - borders[1].width, by + bh],
               c4: [bx + borders[3].width, by + bh]
-            }, borderRadius[0], borderRadius[1], topLeftOuter, topLeftInner, topRightOuter, topRightInner);
+            }, borderRadius[0], borderRadius[1],
+            borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);
             break;
           case 1:
             // right border
@@ -593,7 +608,8 @@ _html2canvas.Parse = function (images, options) {
               c2: [bx + bw, by + bh + borders[2].width],
               c3: [bx, by + bh],
               c4: [bx, by + borders[0].width]
-            }, borderRadius[1], borderRadius[2], topRightOuter, topRightInner, bottomRightOuter, bottomRightInner);
+            }, borderRadius[1], borderRadius[2],
+            borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);
             break;
           case 2:
             // bottom border
@@ -605,7 +621,8 @@ _html2canvas.Parse = function (images, options) {
               c2: [bx, by + bh],
               c3: [bx + borders[3].width, by],
               c4: [bx + bw - borders[2].width, by]
-            }, borderRadius[2], borderRadius[3], bottomRightOuter, bottomRightInner, bottomLeftOuter, bottomLeftInner);
+            }, borderRadius[2], borderRadius[3],
+            borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);
             break;
           case 3:
             // left border
@@ -616,7 +633,8 @@ _html2canvas.Parse = function (images, options) {
               c2: [bx, by],
               c3: [bx + bw, by + borders[0].width],
               c4: [bx + bw, by + bh]
-            }, borderRadius[3], borderRadius[0], bottomLeftOuter, bottomLeftInner, topLeftOuter, topLeftInner);
+            }, borderRadius[3], borderRadius[0],
+            borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);
             break;
         }
 
diff --git a/tests/cases/border/radius.html b/tests/cases/border/radius.html
index 84b0095..6b883fe 100644
--- a/tests/cases/border/radius.html
+++ b/tests/cases/border/radius.html
@@ -38,11 +38,12 @@
 
       .box4 {
         border-width: 50px;
-        border-left-color: #00b5e2;
+        border-left-color: transparent;
         border-top-color: red;
         border-top-width: 10px;
         border-right-color: green;
         border-bottom-right-radius: 190px;
+        background-clip: padding-box;
       }
 
       html {