Title: [146510] trunk
Revision
146510
Author
p...@google.com
Date
2013-03-21 13:35:36 -0700 (Thu, 21 Mar 2013)

Log Message

Correct bisector angle calculation for markers
https://bugs.webkit.org/show_bug.cgi?id=112054

Reviewed by Stephen Chenney.

Source/WebCore:

The SVG marker spec states that mid markers with orient=auto should be aligned with their
x-axis along the bisector of the incoming (in) and outgoing (out) angles. Previously we
calculated this bisector angle as:
    bisector = (in + out) / 2;
Angles cannot be averaged this way! Consider in=90deg and out=-180deg: the bisector should
be 135deg but a naive average gives -45deg. This patch corrects for the discontinuity in
angle values with:
    bisector = (in + out + 360) / 2   // if |in - out| > 180
    bisector = (in + out) / 2         // otherwise
This patch includes an exhaustive test of angle values.

Test: svg/custom/marker-orient-auto.html

* rendering/svg/SVGMarkerData.h:
(WebCore::SVGMarkerData::currentAngle):

LayoutTests:

* platform/chromium-linux/svg/custom/marker-orient-auto-expected.png: Added.
* platform/chromium-linux/svg/custom/marker-orient-auto-expected.txt: Added.
* platform/chromium/TestExpectations:
* svg/custom/marker-orient-auto.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (146509 => 146510)


--- trunk/LayoutTests/ChangeLog	2013-03-21 20:28:46 UTC (rev 146509)
+++ trunk/LayoutTests/ChangeLog	2013-03-21 20:35:36 UTC (rev 146510)
@@ -1,3 +1,15 @@
+2013-03-21  Philip Rogers  <p...@google.com>
+
+        Correct bisector angle calculation for markers
+        https://bugs.webkit.org/show_bug.cgi?id=112054
+
+        Reviewed by Stephen Chenney.
+
+        * platform/chromium-linux/svg/custom/marker-orient-auto-expected.png: Added.
+        * platform/chromium-linux/svg/custom/marker-orient-auto-expected.txt: Added.
+        * platform/chromium/TestExpectations:
+        * svg/custom/marker-orient-auto.html: Added.
+
 2013-03-21  Harald Alvestrand  <h...@google.com>
 
         Expose the Type field of an RTCStatsReport

Modified: trunk/LayoutTests/platform/chromium/TestExpectations (146509 => 146510)


--- trunk/LayoutTests/platform/chromium/TestExpectations	2013-03-21 20:28:46 UTC (rev 146509)
+++ trunk/LayoutTests/platform/chromium/TestExpectations	2013-03-21 20:35:36 UTC (rev 146510)
@@ -1379,6 +1379,9 @@
 
 webkit.org/b/93589 svg/dom/SVGScriptElement/script-change-externalResourcesRequired-while-loading.svg [ Failure Pass Timeout ]
 
+# This test needs a rebaseline after https://bugs.webkit.org/show_bug.cgi?id=112054
+webkit.org/b/112054 svg/custom/marker-orient-auto.html
+
 webkit.org/b/111626 [ Mac Debug ] svg/css/font-face-crash.html [ Pass Crash ]
 
 # -----------------------------------------------------------------

Added: trunk/LayoutTests/platform/chromium-linux/svg/custom/marker-orient-auto-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/chromium-linux/svg/custom/marker-orient-auto-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/chromium-linux/svg/custom/marker-orient-auto-expected.txt (0 => 146510)


--- trunk/LayoutTests/platform/chromium-linux/svg/custom/marker-orient-auto-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/chromium-linux/svg/custom/marker-orient-auto-expected.txt	2013-03-21 20:35:36 UTC (rev 146510)
@@ -0,0 +1,15 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x561
+  RenderBlock {HTML} at (0,0) size 800x561
+    RenderBody {BODY} at (8,8) size 784x545
+      RenderText {#text} at (0,0) size 748x39
+        text run at (0,0) width 748: "Test for wkbug.com/112054. This test passes if the green star has orange markers pointing outside only and the blue star has"
+        text run at (0,20) width 216: "orange markers pointing inside only."
+      RenderBR {BR} at (216,20) size 0x19
+      RenderSVGRoot {svg} at (15,55) size 394x206
+        RenderSVGResourceMarker {marker} [id="marker"] [markerUnits=strokeWidth] [ref at (0,0)] [angle=auto]
+          RenderSVGPath {path} at (8,48) size 5x6 [stroke={[type=SOLID] [color=#000000] [stroke width=0.50]}] [fill={[type=SOLID] [color=#FFA500]}] [data="" 0 0 L 4 0 L 2 5 L 0 0 Z"]
+        RenderSVGPath {path} at (15,55) size 206x206 [stroke={[type=SOLID] [color=#008000] [stroke width=2.00]}] [middle marker=marker] [data="" 156 189.674 L 158.215 180.153 L 152.243 162.166 L 140.89 142.551 L 129.972 127.983 L 125.867 122.175 L 132.54 124.637 L 149.437 131.413 L 171.321 137.302 L 190.242 138.415 L 198.865 133.811 L 193.699 125.513 L 176.757 117.016 L 154.86 111.175 L 136.839 108.593 L 129.829 107.389 L 136.288 104.412 L 153.027 97.2547 L 172.666 85.9447 L 186.832 73.3529 L 189.674 64 L 180.153 61.7849 L 162.166 67.7571 L 142.551 79.1098 L 127.983 90.0277 L 122.175 94.1329 L 124.637 87.4604 L 131.413 70.5627 L 137.302 48.6786 L 138.415 29.758 L 133.811 21.1348 L 125.513 26.3008 L 117.016 43.2431 L 111.175 65.14 L 108.593 83.1614 L 107.389 90.1711 L 104.412 83.7119 L 97.2547 66.9726 L 85.9447 47.3338 L 73.3529 33.1678 L 64 30.3257 L 61.7849 39.8466 L 67.7571 57.8344 L 79.1098 77.4485 L 90.0277 92.0169 L 94.1329 97.8248 L 87.4604 95.3626 L 70.5627 88.5873 L 48.6786 82.698 L 29.758 81.5848 L 21.1348 86.1886 L 26.3008 94.4873 L 43.2431 102.984 L 65.14 108.825 L 83.1614 111.407 L 90.1711 112.611 L 83.7119 115.588 L 66.9726 122.745 L 47.3338 134.055 L 33.1678 146.647 L 30.3257 156 L 39.8466 158.215 L 57.8344 152.243 L 77.4485 140.89 L 92.0169 129.972 L 97.8248 125.867 L 95.3626 132.54 L 88.5873 149.437 L 82.698 171.321 L 81.5848 190.242 L 86.1886 198.865 L 94.4873 193.699 L 102.984 176.757 L 108.825 154.86 L 111.407 136.839 L 112.611 129.829 L 115.588 136.288 L 122.745 153.027 L 134.055 172.666 L 146.647 186.832"]
+        RenderSVGPath {path} at (227,67) size 182x182 [stroke={[type=SOLID] [color=#0000FF] [stroke width=2.00]}] [middle marker=marker] [data="" 356 189.674 L 346.647 186.832 L 334.055 172.666 L 322.745 153.027 L 315.588 136.288 L 312.611 129.829 L 311.407 136.839 L 308.825 154.86 L 302.984 176.757 L 294.487 193.699 L 286.189 198.865 L 281.585 190.242 L 282.698 171.321 L 288.587 149.437 L 295.363 132.54 L 297.825 125.867 L 292.017 129.972 L 277.449 140.89 L 257.834 152.243 L 239.847 158.215 L 230.326 156 L 233.168 146.647 L 247.334 134.055 L 266.973 122.745 L 283.712 115.588 L 290.171 112.611 L 283.161 111.407 L 265.14 108.825 L 243.243 102.984 L 226.301 94.4873 L 221.135 86.1886 L 229.758 81.5848 L 248.679 82.698 L 270.563 88.5873 L 287.46 95.3626 L 294.133 97.8248 L 290.028 92.0169 L 279.11 77.4485 L 267.757 57.8344 L 261.785 39.8466 L 264 30.3257 L 273.353 33.1678 L 285.945 47.3338 L 297.255 66.9726 L 304.412 83.7119 L 307.389 90.1711 L 308.593 83.1614 L 311.175 65.14 L 317.016 43.2431 L 325.513 26.3008 L 333.811 21.1348 L 338.415 29.758 L 337.302 48.6786 L 331.413 70.5627 L 324.637 87.4604 L 322.175 94.1329 L 327.983 90.0277 L 342.551 79.1098 L 362.166 67.7571 L 380.153 61.7849 L 389.674 64 L 386.832 73.3529 L 372.666 85.9447 L 353.027 97.2547 L 336.288 104.412 L 329.829 107.389 L 336.839 108.593 L 354.86 111.175 L 376.757 117.016 L 393.699 125.513 L 398.865 133.811 L 390.242 138.415 L 371.321 137.302 L 349.437 131.413 L 332.54 124.637 L 325.867 122.175 L 329.972 127.983 L 340.89 142.551 L 352.243 162.166 L 358.215 180.153"]
+      RenderText {#text} at (0,0) size 0x0

Added: trunk/LayoutTests/svg/custom/marker-orient-auto.html (0 => 146510)


--- trunk/LayoutTests/svg/custom/marker-orient-auto.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/marker-orient-auto.html	2013-03-21 20:35:36 UTC (rev 146510)
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+  function startTest() {
+    starPath(document.getElementById("marker-path-cw"), true, 110, 110, 56, 8, 36, 80, Math.PI/6);
+    starPath(document.getElementById("marker-path-ccw"), false, 310, 110, 56, 8, 36, 80, Math.PI/6);
+  }
+
+  // Generate a star path
+  //   cw - true for clockwise, false for counter-clockwise
+  //   centered at (cx,cy)
+  //   radius r
+  //   s 'spikes' of length l
+  //   n total vertices
+  //   t rotation
+  function starPath(el, cw, cx, cy, r, s, l, n, t) {
+    var d = "";
+    for (var i=0; i<=2*Math.PI; i+=2*Math.PI/n) {
+      var a = cw ? i : -i;
+      var px = cx + (r+l*Math.cos(a*s))*Math.sin(a+t);
+      var py = cy + (r+l*Math.cos(a*s))*Math.cos(a+t);
+      d += (d.length ? "L" : "M") + px + " " + py;
+    }
+    el.setAttribute("d", d);
+  }
+</script>
+<style>
+#marker-path-cw {
+  stroke: green;
+}
+#marker-path-ccw {
+  stroke: blue;
+}
+.marker-path {
+  fill: none;
+  stroke-width: 2px;
+  marker-mid: url(#marker);
+}
+</style>
+</head>
+<body _onload_="startTest()">
+Test for wkbug.com/112054.
+This test passes if the green star has orange markers pointing outside only and the blue star has orange markers pointing inside only.<br/>
+<svg width="500" height="500">
+  <marker id="marker" markerWidth="15" markerHeight="15" orient="auto">
+    <!-- This marker points in the direction of the bisector angle. -->
+    <path d="M0 0L4 0L2 5L0 0Z" fill="orange" stroke-width='0.5px' stroke='black'/> 
+  </marker>
+  <path id="marker-path-cw" class="marker-path"/>
+  <path id="marker-path-ccw" class="marker-path"/>
+</svg>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (146509 => 146510)


--- trunk/Source/WebCore/ChangeLog	2013-03-21 20:28:46 UTC (rev 146509)
+++ trunk/Source/WebCore/ChangeLog	2013-03-21 20:35:36 UTC (rev 146510)
@@ -1,3 +1,26 @@
+2013-03-21  Philip Rogers  <p...@google.com>
+
+        Correct bisector angle calculation for markers
+        https://bugs.webkit.org/show_bug.cgi?id=112054
+
+        Reviewed by Stephen Chenney.
+
+        The SVG marker spec states that mid markers with orient=auto should be aligned with their
+        x-axis along the bisector of the incoming (in) and outgoing (out) angles. Previously we
+        calculated this bisector angle as:
+            bisector = (in + out) / 2;
+        Angles cannot be averaged this way! Consider in=90deg and out=-180deg: the bisector should
+        be 135deg but a naive average gives -45deg. This patch corrects for the discontinuity in
+        angle values with:
+            bisector = (in + out + 360) / 2   // if |in - out| > 180
+            bisector = (in + out) / 2         // otherwise
+        This patch includes an exhaustive test of angle values.
+
+        Test: svg/custom/marker-orient-auto.html
+
+        * rendering/svg/SVGMarkerData.h:
+        (WebCore::SVGMarkerData::currentAngle):
+
 2013-03-21  Harald Alvestrand  <h...@google.com>
 
         Expose the Type field of an RTCStatsReport

Modified: trunk/Source/WebCore/rendering/svg/SVGMarkerData.h (146509 => 146510)


--- trunk/Source/WebCore/rendering/svg/SVGMarkerData.h	2013-03-21 20:28:46 UTC (rev 146509)
+++ trunk/Source/WebCore/rendering/svg/SVGMarkerData.h	2013-03-21 20:35:36 UTC (rev 146510)
@@ -82,19 +82,23 @@
 private:
     float currentAngle(SVGMarkerType type) const
     {
-        FloatPoint inslopeChange(m_inslopePoints[1] - m_inslopePoints[0]);
-        FloatPoint outslopeChange(m_outslopePoints[1] - m_outslopePoints[0]);
+        // For details of this calculation, see: http://www.w3.org/TR/SVG/single-page.html#painting-MarkerElement
+        FloatPoint inSlope(m_inslopePoints[1] - m_inslopePoints[0]);
+        FloatPoint outSlope(m_outslopePoints[1] - m_outslopePoints[0]);
 
-        double inslope = rad2deg(inslopeChange.slopeAngleRadians());
-        double outslope = rad2deg(outslopeChange.slopeAngleRadians());
+        double inAngle = rad2deg(inSlope.slopeAngleRadians());
+        double outAngle = rad2deg(outSlope.slopeAngleRadians());
 
         switch (type) {
         case StartMarker:
-            return narrowPrecisionToFloat(outslope);
+            return narrowPrecisionToFloat(outAngle);
         case MidMarker:
-            return narrowPrecisionToFloat((inslope + outslope) / 2);
+            // WK193015: Prevent bugs due to angles being non-continuous.
+            if (fabs(inAngle - outAngle) > 180)
+                inAngle += 360;
+            return narrowPrecisionToFloat((inAngle + outAngle) / 2);
         case EndMarker:
-            return narrowPrecisionToFloat(inslope);
+            return narrowPrecisionToFloat(inAngle);
         }
 
         ASSERT_NOT_REACHED();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to