Title: [197738] trunk
Revision
197738
Author
[email protected]
Date
2016-03-08 00:20:22 -0800 (Tue, 08 Mar 2016)

Log Message

[SVG2] Implement marker orient='auto-start-reverse'
https://bugs.webkit.org/show_bug.cgi?id=138456

Patch by Nikos Andronikos <[email protected]> on 2016-03-08
Reviewed by Darin Adler.

Source/WebCore:

https://www.w3.org/TR/SVG2/painting.html#OrientAttribute
marker-start markers must be oriented at 180 degrees to the direction of the path when
the orient attribute of the marker is set to 'auto-start-reverse'.

To acheive this the SVGMarkerData class which calculates the angles for each marker on
a path must know whether the orient type is set to reverse the start marker.

Tests: svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html
       svg/animations/animate-marker-orienttype-4.html
       svg/custom/marker-auto-start-reverse.html

* rendering/svg/RenderSVGShape.cpp:
(WebCore::RenderSVGShape::processMarkerPositions):
  Create marker data, using animated value of orient to determine
  if first marker should be reversed.
* rendering/svg/SVGMarkerData.h:
(WebCore::SVGMarkerData::SVGMarkerData):
  Constructor now requires boolean indicating if start marker is
  reversed.
(WebCore::SVGMarkerData::currentAngle):
  Take into account whether start marker should be reversed.
* rendering/svg/SVGResources.cpp:
(WebCore::SVGResources::markerReverseStart):
  New function to query whether start marker should be reversed.
* rendering/svg/SVGResources.h:
  Add declaration for new function.
* svg/SVGAnimatedAngle.cpp:
(WebCore::SVGAnimatedAngleAnimator::calculateAnimatedValue):
  Support animation including the value auto-start-reverse.
* svg/SVGMarkerElement.cpp:
(WebCore::SVGMarkerElement::setOrient):
  Combine duplicated functionality into one private method
(WebCore::SVGMarkerElement::setOrientToAuto):
  Set orient type and angle correctly for orient=auto. Uses setOrient.
(WebCore::SVGMarkerElement::setOrientToAngle):
  Set orient type and angle correctly for orient=<angle>. Uses setOrient.
(WebCore::SVGMarkerElement::synchronizeOrientType):
  Support auto-start-reverse as a possible case.
* svg/SVGMarkerElement.h:
(WebCore::SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue):
  Limit the orient DOM property so that the new enum value
  required for auto-start-reverse is not exposed.
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::highestEnumValue):
  Support auto-start-reverse.
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::fromString):
  Support auto-start-reverse.

LayoutTests:

* svg/animations/animate-marker-orient-from-angle-to-autostartreverse-expected.txt: Added.
* svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html: Added.
* svg/animations/animate-marker-orienttype-4-expected.html: Added.
* svg/animations/animate-marker-orienttype-4.html: Added.
  Verify output after animation has run - ensure animation reflected in visual result.
* svg/animations/script-tests/animate-marker-orient-from-angle-to-autostartreverse.js: Added.
  Test DOM values at various snap-shot times throughout the animation.
(sample1):
(sample2):
(sample3):
(executeTest):
* svg/custom/marker-auto-start-reverse-expected.html: Added.
* svg/custom/marker-auto-start-reverse.html: Added.
  Verify static result - start marker is oriented at 180 degrees to direction of path.
* svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:
* svg/dom/script-tests/SVGAnimatedEnumeration-SVGMarkerElement.js:
  Check attributes are treated as case sensitive.
  Check UNKNOWN is returned for enum value when auto-start-reverse set.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (197737 => 197738)


--- trunk/LayoutTests/ChangeLog	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/LayoutTests/ChangeLog	2016-03-08 08:20:22 UTC (rev 197738)
@@ -1,3 +1,29 @@
+2016-03-08  Nikos Andronikos  <[email protected]>
+
+        [SVG2] Implement marker orient='auto-start-reverse'
+        https://bugs.webkit.org/show_bug.cgi?id=138456
+
+        Reviewed by Darin Adler.
+
+        * svg/animations/animate-marker-orient-from-angle-to-autostartreverse-expected.txt: Added.
+        * svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html: Added.
+        * svg/animations/animate-marker-orienttype-4-expected.html: Added.
+        * svg/animations/animate-marker-orienttype-4.html: Added.
+          Verify output after animation has run - ensure animation reflected in visual result.
+        * svg/animations/script-tests/animate-marker-orient-from-angle-to-autostartreverse.js: Added.
+          Test DOM values at various snap-shot times throughout the animation.
+        (sample1):
+        (sample2):
+        (sample3):
+        (executeTest):
+        * svg/custom/marker-auto-start-reverse-expected.html: Added.
+        * svg/custom/marker-auto-start-reverse.html: Added.
+          Verify static result - start marker is oriented at 180 degrees to direction of path.
+        * svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:
+        * svg/dom/script-tests/SVGAnimatedEnumeration-SVGMarkerElement.js:
+          Check attributes are treated as case sensitive.
+          Check UNKNOWN is returned for enum value when auto-start-reverse set.
+
 2016-03-07  Chris Dumez  <[email protected]>
 
         Stop clamping HTMLElement.tabIndex to the range of a short

Added: trunk/LayoutTests/svg/animations/animate-marker-orient-from-angle-to-autostartreverse-expected.txt (0 => 197738)


--- trunk/LayoutTests/svg/animations/animate-marker-orient-from-angle-to-autostartreverse-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-marker-orient-from-angle-to-autostartreverse-expected.txt	2016-03-08 08:20:22 UTC (rev 197738)
@@ -0,0 +1,37 @@
+SVG 2 dynamic animation tests
+
+Animate SVGMarkerElement orientAttr from an angle to auto-start-reverse.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS SVGMarkerElement.SVG_MARKER_ORIENT_AUTOSTARTREVERSE is undefined
+PASS marker.orientType.baseVal = 3 threw exception Error: SVG_INVALID_VALUE_ERR: DOM SVG Exception 1.
+PASS marker.orientAngle.animVal.value is 0
+PASS marker.orientAngle.baseVal.value is 0
+PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientAngle.animVal.value is 90
+PASS marker.orientAngle.baseVal.value is 0
+PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientAngle.animVal.value is 90
+PASS marker.orientAngle.baseVal.value is 0
+PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientAngle.animVal.value is 0
+PASS marker.orientAngle.baseVal.value is 0
+PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN
+PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientAngle.animVal.value is 0
+PASS marker.orientAngle.baseVal.value is 0
+PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN
+PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS marker.orientAngle.animVal.value is 0
+PASS marker.orientAngle.baseVal.value is 0
+PASS marker.orientType.animVal is SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN
+PASS marker.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html (0 => 197738)


--- trunk/LayoutTests/svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html	2016-03-08 08:20:22 UTC (rev 197738)
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body _onload_="runSMILTest()">
+<h1>SVG 2 dynamic animation tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/svg/animations/animate-marker-orienttype-4-expected.html (0 => 197738)


--- trunk/LayoutTests/svg/animations/animate-marker-orienttype-4-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-marker-orienttype-4-expected.html	2016-03-08 08:20:22 UTC (rev 197738)
@@ -0,0 +1,22 @@
+<!doctype html>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" width="500" height="500">
+    <defs>
+        <marker id="arrow1" orient="auto" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue" />
+        </marker>
+         <marker id="arrow2" orient="auto-start-reverse" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue" />
+        </marker>
+         <marker id="arrow3" orient="77" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue" />
+        </marker>
+         <marker id="arrow4" orient="auto-start-reverse" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue" />
+        </marker>
+    </defs>
+    <path d="M 200,200 h 600" marker-start="url(#arrow1)" marker-end="url(#arrow1)" stroke="black"/>
+    <path d="M 200,400 h 600" marker-start="url(#arrow2)" marker-end="url(#arrow2)" stroke="black"/>
+    <path d="M 200,600 h 600" marker-start="url(#arrow3)" marker-end="url(#arrow3)" stroke="black"/>
+    <path d="M 200,800 h 600" marker-start="url(#arrow4)" marker-end="url(#arrow4)" stroke="black"/>
+</svg>
+

Added: trunk/LayoutTests/svg/animations/animate-marker-orienttype-4.html (0 => 197738)


--- trunk/LayoutTests/svg/animations/animate-marker-orienttype-4.html	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-marker-orienttype-4.html	2016-03-08 08:20:22 UTC (rev 197738)
@@ -0,0 +1,48 @@
+<!doctype html>
+<!--
+  Test that the renderer uses the animated value of orientType.
+  To test this, the final animated value must be of a different type than the initial value.
+ -->
+<script>
+function doTest() {
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+    var svg = document.querySelector("#svg");
+    svg.setCurrentTime(5);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+</script>
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" width="500" height="500" _onload_="doTest()">
+    <defs>
+        <marker id="arrow1" orient="auto-start-reverse" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue"/>
+            <animate attributeName="orient" from="auto-start-reverse" to="auto" begin="0s" dur="1s" fill="freeze"/>
+        </marker>
+         <marker id="arrow2" orient="90" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue"/>
+            <animate attributeName="orient" from="auto" to="auto-start-reverse" begin="0s" dur="1s" fill="freeze"/>
+        </marker>
+         <marker id="arrow3" orient="auto" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue"/>
+            <animate attributeName="orient" from="auto-start-reverse" to="77" begin="0s" dur="1s" fill="freeze"/>
+        </marker>
+         <marker id="arrow4" orient="123" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M50,0 L 0,-50 L0,50 z" fill="skyblue"/>
+            <animate attributeName="orient" from="123" to="auto-start-reverse" begin="0s" dur="1s" fill="freeze"/>
+        </marker>
+        <path d="M50,0 L 0,-50 L0,50 z" transform="scale(0.8) translate(5)" id="pointer" fill="red"/>
+    </defs>
+    <use xlink:href="" transform="translate(200,200) rotate(0)"/>
+    <use xlink:href="" transform="translate(800,200) rotate(0)"/>
+    <path d="M 200,200 h 600" marker-start="url(#arrow1)" marker-end="url(#arrow1)" stroke="black"/>
+    <use xlink:href="" transform="translate(200,400) rotate(180)"/>
+    <use xlink:href="" transform="translate(800,400) rotate(0)"/>
+    <path d="M 200,400 h 600" marker-start="url(#arrow2)" marker-end="url(#arrow2)" stroke="black"/>
+    <use xlink:href="" transform="translate(200,600) rotate(77)"/>
+    <use xlink:href="" transform="translate(800,600) rotate(77)"/>
+    <path d="M 200,600 h 600" marker-start="url(#arrow3)" marker-end="url(#arrow3)" stroke="black"/>
+    <use xlink:href="" transform="translate(200,800) rotate(180)"/>
+    <use xlink:href="" transform="translate(800,800) rotate(0)"/>
+    <path d="M 200,800 h 600" marker-start="url(#arrow4)" marker-end="url(#arrow4)" stroke="black"/>
+</svg>

Added: trunk/LayoutTests/svg/animations/script-tests/animate-marker-orient-from-angle-to-autostartreverse.js (0 => 197738)


--- trunk/LayoutTests/svg/animations/script-tests/animate-marker-orient-from-angle-to-autostartreverse.js	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/script-tests/animate-marker-orient-from-angle-to-autostartreverse.js	2016-03-08 08:20:22 UTC (rev 197738)
@@ -0,0 +1,91 @@
+description("Animate SVGMarkerElement orientAttr from an angle to auto-start-reverse.");
+createSVGTestCase();
+
+// Setup test document.
+
+var marker = createSVGElement("marker");
+marker.setAttribute("id", "marker");
+marker.setAttribute("viewBox", "0 0 10 10");
+marker.setAttribute("markerWidth", "2");
+marker.setAttribute("markerHeight", "2");
+marker.setAttribute("refX", "5");
+marker.setAttribute("refY", "5");
+marker.setAttribute("markerUnits", "strokeWidth");
+
+var markerPath = createSVGElement("path");
+markerPath.setAttribute("fill", "blue");
+markerPath.setAttribute("d", "M 5 0 L 10 10 L 0 10 Z");
+marker.appendChild(markerPath);
+
+var defsElement = createSVGElement("defs");
+defsElement.appendChild(marker);
+rootSVGElement.appendChild(defsElement);
+
+var path = createSVGElement("path");
+path.setAttribute("id", "path");
+path.setAttribute("onclick", "executeTest()");
+path.setAttribute("fill", "none");
+path.setAttribute("stroke", "green");
+path.setAttribute("stroke-width", "10");
+path.setAttribute("marker-start", "url(#marker)");
+path.setAttribute("marker-end", "url(#marker)");
+path.setAttribute("d", "M 130 135 L 180 135 L 180 185");
+path.setAttribute("transform", "translate(-130, -120)");
+rootSVGElement.appendChild(path);
+
+var animate1 = createSVGElement("animate");
+animate1.setAttribute("id", "animation");
+animate1.setAttribute("attributeName", "orient");
+animate1.setAttribute("begin", "path.click");
+animate1.setAttribute("dur", "4s");
+animate1.setAttribute("from", "90deg");
+animate1.setAttribute("to", "auto-start-reverse");
+animate1.setAttribute("fill", "freeze");
+marker.appendChild(animate1);
+
+// Setup animation test.
+function sample1() {
+    shouldBeCloseEnough("marker.orientAngle.animVal.value", "0");
+    shouldBe("marker.orientAngle.baseVal.value", "0");
+
+    shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+    shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+}
+
+function sample2() {
+    shouldBeCloseEnough("marker.orientAngle.animVal.value", "90");
+    shouldBe("marker.orientAngle.baseVal.value", "0");
+
+    shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+    shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+}
+
+function sample3() {
+    shouldBeCloseEnough("marker.orientAngle.animVal.value", "0");
+    shouldBe("marker.orientAngle.baseVal.value", "0");
+
+    shouldBe("marker.orientType.animVal", "SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN");
+    shouldBe("marker.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+}
+
+function executeTest() {
+    const expectedValues = [
+        // [animationId, time, sampleCallback]
+        ["animation", 0.0,   sample1],
+        ["animation", 0.001, sample2],
+        ["animation", 1.999, sample2],
+        ["animation", 2.001, sample3],
+        ["animation", 3.999, sample3],
+        ["animation", 4.001, sample3]
+    ];
+
+    // Ensure new enum value is not exposed through the IDL
+    shouldBe("SVGMarkerElement.SVG_MARKER_ORIENT_AUTOSTARTREVERSE", "undefined");
+
+    // Ensure we cannot set autostartreverse through the orient property.
+    shouldThrow("marker.orientType.baseVal = 3");
+
+    runAnimationTest(expectedValues);
+}
+
+var successfullyParsed = true;

Added: trunk/LayoutTests/svg/custom/marker-auto-start-reverse-expected.html (0 => 197738)


--- trunk/LayoutTests/svg/custom/marker-auto-start-reverse-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/marker-auto-start-reverse-expected.html	2016-03-08 08:20:22 UTC (rev 197738)
@@ -0,0 +1,12 @@
+<!doctype html>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="300" height="300">
+    <defs>
+        <marker id="arrow" orient="225" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M5,0 L 0,-5 L0,5 z" fill="green"/>
+        </marker>
+        <marker id="arrow2" orient="auto" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M5,0 L 0,-5 L0,5 z" fill="green"/>
+        </marker>
+     </defs>
+    <path d="M 20,20 L50,50 L 80,80" marker-start="url(#arrow)" marker-mid="url(#arrow2)" marker-end="url(#arrow2)" stroke="black"/>
+</svg>

Added: trunk/LayoutTests/svg/custom/marker-auto-start-reverse.html (0 => 197738)


--- trunk/LayoutTests/svg/custom/marker-auto-start-reverse.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/marker-auto-start-reverse.html	2016-03-08 08:20:22 UTC (rev 197738)
@@ -0,0 +1,14 @@
+<!doctype html>
+<!-- 
+Reftest for auto-start-reverse value for orient property of marker element.
+Markers at each end of the path should point outwards. Middle marker should point along the direction of the path.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="300" height="300">
+    <defs>
+        <!-- Correct definition - uses lower case -->
+        <marker id="arrow" orient="auto-start-reverse" markerWidth="10" markerHeight="10" style="overflow:visible">
+            <path d="M5,0 L 0,-5 L0,5 z" fill="green"/>
+        </marker>
+     </defs>
+    <path d="M 20,20 l30,30 30,30" marker-start="url(#arrow)" marker-mid="url(#arrow)" marker-end="url(#arrow)" stroke="black"/>
+</svg>

Modified: trunk/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt (197737 => 197738)


--- trunk/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt	2016-03-08 08:20:22 UTC (rev 197738)
@@ -37,6 +37,13 @@
 PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
 PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
 
+Switch to 'auto-start-reverse' value - by modifying the orient attribute.
+PASS markerElement.setAttribute('orient', 'auto-start-reverse') did not throw exception.
+PASS markerElement.orientAngle.baseVal.value is 0
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN
+PASS markerElement.getAttribute('orient') is "auto-start-reverse"
+
 Switch to 'Pi/2 rad' value - via setOrientToAngle()
 PASS anglePiHalfRad = svgElement.createSVGAngle(); anglePiHalfRad.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, (Math.PI / 2).toFixed(2)) is undefined.
 PASS markerElement.setOrientToAngle(anglePiHalfRad) is undefined.
@@ -92,6 +99,14 @@
 PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
 PASS markerElement.getAttribute('orient') is "10deg"
 
+Test case sensitivity of attributes - try setting invalid values
+PASS markerElement.setAttribute('orient', 'AUTO-START-REVERSE') did not throw exception.
+FAIL markerElement.getAttribute('orient') should be AUTO-START-REVERSE. Was 10deg.
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.setAttribute('orient', 'AUTO') did not throw exception.
+FAIL markerElement.getAttribute('orient') should be AUTO. Was 10deg.
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+
 Switch back to 'auto' value
 PASS markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
 PASS markerElement.orientAngle.baseVal.value is 10

Modified: trunk/LayoutTests/svg/dom/script-tests/SVGAnimatedEnumeration-SVGMarkerElement.js (197737 => 197738)


--- trunk/LayoutTests/svg/dom/script-tests/SVGAnimatedEnumeration-SVGMarkerElement.js	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/LayoutTests/svg/dom/script-tests/SVGAnimatedEnumeration-SVGMarkerElement.js	2016-03-08 08:20:22 UTC (rev 197738)
@@ -49,6 +49,14 @@
 shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
 
 debug("");
+debug("Switch to 'auto-start-reverse' value - by modifying the orient attribute.");
+shouldNotThrow("markerElement.setAttribute('orient', 'auto-start-reverse')");
+shouldBe("markerElement.orientAngle.baseVal.value", "0");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "auto-start-reverse");
+
+debug("");
 debug("Switch to 'Pi/2 rad' value - via setOrientToAngle()");
 shouldBeUndefined("anglePiHalfRad = svgElement.createSVGAngle(); anglePiHalfRad.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, (Math.PI / 2).toFixed(2))");
 shouldBeUndefined("markerElement.setOrientToAngle(anglePiHalfRad)");
@@ -113,6 +121,22 @@
 shouldBeEqualToString("markerElement.getAttribute('orient')", "10deg");
 
 debug("");
+debug("Test case sensitivity of attributes - try setting invalid values");
+shouldNotThrow("markerElement.setAttribute('orient', 'AUTO-START-REVERSE')");
+// The line below fails as a result of https://bugs.webkit.org/show_bug.cgi?id=154141
+// The attribute value is not updated to the invalid value.
+// The expected result recognises this and should be updated when the above bug
+// is resolved.
+// What's important here though is that the DOM values are unchanged, and this
+// is demonstrated correctly.
+shouldBeEqualToString("markerElement.getAttribute('orient')", "AUTO-START-REVERSE");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+
+shouldNotThrow("markerElement.setAttribute('orient', 'AUTO')");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "AUTO");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); 
+
+debug("");
 debug("Switch back to 'auto' value");
 shouldBe("markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
 shouldBe("markerElement.orientAngle.baseVal.value", "10");

Modified: trunk/Source/WebCore/ChangeLog (197737 => 197738)


--- trunk/Source/WebCore/ChangeLog	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/ChangeLog	2016-03-08 08:20:22 UTC (rev 197738)
@@ -1,3 +1,57 @@
+2016-03-08  Nikos Andronikos  <[email protected]>
+
+        [SVG2] Implement marker orient='auto-start-reverse'
+        https://bugs.webkit.org/show_bug.cgi?id=138456
+
+        Reviewed by Darin Adler.
+
+        https://www.w3.org/TR/SVG2/painting.html#OrientAttribute
+        marker-start markers must be oriented at 180 degrees to the direction of the path when
+        the orient attribute of the marker is set to 'auto-start-reverse'.
+
+        To acheive this the SVGMarkerData class which calculates the angles for each marker on
+        a path must know whether the orient type is set to reverse the start marker. 
+
+        Tests: svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html
+               svg/animations/animate-marker-orienttype-4.html
+               svg/custom/marker-auto-start-reverse.html
+
+        * rendering/svg/RenderSVGShape.cpp:
+        (WebCore::RenderSVGShape::processMarkerPositions):
+          Create marker data, using animated value of orient to determine
+          if first marker should be reversed.
+        * rendering/svg/SVGMarkerData.h:
+        (WebCore::SVGMarkerData::SVGMarkerData):
+          Constructor now requires boolean indicating if start marker is 
+          reversed.
+        (WebCore::SVGMarkerData::currentAngle):
+          Take into account whether start marker should be reversed.
+        * rendering/svg/SVGResources.cpp:
+        (WebCore::SVGResources::markerReverseStart):
+          New function to query whether start marker should be reversed.
+        * rendering/svg/SVGResources.h:
+          Add declaration for new function.
+        * svg/SVGAnimatedAngle.cpp:
+        (WebCore::SVGAnimatedAngleAnimator::calculateAnimatedValue):
+          Support animation including the value auto-start-reverse.
+        * svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::setOrient):
+          Combine duplicated functionality into one private method
+        (WebCore::SVGMarkerElement::setOrientToAuto):
+          Set orient type and angle correctly for orient=auto. Uses setOrient.
+        (WebCore::SVGMarkerElement::setOrientToAngle):
+          Set orient type and angle correctly for orient=<angle>. Uses setOrient.
+        (WebCore::SVGMarkerElement::synchronizeOrientType):
+          Support auto-start-reverse as a possible case.
+        * svg/SVGMarkerElement.h:
+        (WebCore::SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue):
+          Limit the orient DOM property so that the new enum value
+          required for auto-start-reverse is not exposed.
+        (WebCore::SVGPropertyTraits<SVGMarkerOrientType>::highestEnumValue):
+          Support auto-start-reverse.
+        (WebCore::SVGPropertyTraits<SVGMarkerOrientType>::fromString):
+          Support auto-start-reverse.
+
 2016-03-07  Keith Rollin  <[email protected]>
 
         Enhance logging: Use "always on" macros

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp (197737 => 197738)


--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2016-03-08 08:20:22 UTC (rev 197738)
@@ -482,7 +482,7 @@
 
     ASSERT(m_path);
 
-    SVGMarkerData markerData(m_markerPositions);
+    SVGMarkerData markerData(m_markerPositions, SVGResourcesCache::cachedResourcesForRenderer(*this)->markerReverseStart());
     m_path->apply([&markerData](const PathElement& pathElement) {
         SVGMarkerData::updateFromPathElement(markerData, pathElement);
     });

Modified: trunk/Source/WebCore/rendering/svg/SVGMarkerData.h (197737 => 197738)


--- trunk/Source/WebCore/rendering/svg/SVGMarkerData.h	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/rendering/svg/SVGMarkerData.h	2016-03-08 08:20:22 UTC (rev 197738)
@@ -48,9 +48,10 @@
 
 class SVGMarkerData {
 public:
-    SVGMarkerData(Vector<MarkerPosition>& positions)
+    SVGMarkerData(Vector<MarkerPosition>& positions, bool reverseStart)
         : m_positions(positions)
         , m_elementIndex(0)
+        , m_reverseStart(reverseStart)
     {
     }
 
@@ -87,6 +88,8 @@
 
         switch (type) {
         case StartMarker:
+            if (m_reverseStart)
+                return narrowPrecisionToFloat(outAngle - 180);
             return narrowPrecisionToFloat(outAngle);
         case MidMarker:
             // WK193015: Prevent bugs due to angles being non-continuous.
@@ -147,6 +150,7 @@
     FloatPoint m_subpathStart;
     FloatPoint m_inslopePoints[2];
     FloatPoint m_outslopePoints[2];
+    bool m_reverseStart;
 };
 
 }

Modified: trunk/Source/WebCore/rendering/svg/SVGResources.cpp (197737 => 197738)


--- trunk/Source/WebCore/rendering/svg/SVGResources.cpp	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/rendering/svg/SVGResources.cpp	2016-03-08 08:20:22 UTC (rev 197738)
@@ -305,6 +305,13 @@
         markerEnd()->layoutIfNeeded();
 }
 
+bool SVGResources::markerReverseStart() const
+{
+    return m_markerData
+        && m_markerData->markerStart
+        && m_markerData->markerStart->markerElement().orientType() == SVGMarkerOrientAutoStartReverse;
+}
+
 void SVGResources::removeClientFromCache(RenderElement& renderer, bool markForInvalidation) const
 {
     if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData && !m_linkedResource)

Modified: trunk/Source/WebCore/rendering/svg/SVGResources.h (197737 => 197738)


--- trunk/Source/WebCore/rendering/svg/SVGResources.h	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/rendering/svg/SVGResources.h	2016-03-08 08:20:22 UTC (rev 197738)
@@ -20,6 +20,8 @@
 #ifndef SVGResources_h
 #define SVGResources_h
 
+#include "RenderSVGResourceMarker.h"
+
 #include <memory>
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
@@ -52,6 +54,7 @@
     RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : nullptr; }
     RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : nullptr; }
     RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : nullptr; }
+    bool markerReverseStart() const;
     RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : nullptr; }
     RenderSVGResourceFilter* filter() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->filter : nullptr; }
 

Modified: trunk/Source/WebCore/svg/SVGAnimatedAngle.cpp (197737 => 197738)


--- trunk/Source/WebCore/svg/SVGAnimatedAngle.cpp	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/svg/SVGAnimatedAngle.cpp	2016-03-08 08:20:22 UTC (rev 197738)
@@ -36,7 +36,7 @@
     std::pair<SVGAngle, unsigned>& animatedPair = animatedType->angleAndEnumeration();
 
     SVGAngle angle;
-    SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string,  angle);
+    SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string, angle);
     if (orientType > 0)
         animatedPair.second = orientType;
     if (orientType == SVGMarkerOrientAngle)
@@ -113,28 +113,25 @@
         return;
     }
 
-    // From 'auto' to 'auto'.
-    if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto) {
-        animatedAngleAndEnumeration.first.setValue(0);
-        animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
-        return;
-    }
+    if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) {
+        // Regular from angle to angle animation, with support for smooth interpolation, and additive and accumulated animation.
+        animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
 
-    // If the enumeration value is not angle or auto, its unknown.
-    if (fromAngleAndEnumeration.second != SVGMarkerOrientAngle) {
-        animatedAngleAndEnumeration.first.setValue(0);
-        animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
+        SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first;
+        const SVGAngle& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first;
+        float animatedAngle = animatedSVGAngle.value();
+        m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle);
+        animatedSVGAngle.setValue(animatedAngle);
         return;
     }
 
-    // Regular from angle to angle animation, with all features like additive etc.
-    animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
+    // auto, auto-start-reverse, or unknown.
+    animatedAngleAndEnumeration.first.setValue(0);
 
-    SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first;
-    const SVGAngle& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first;
-    float animatedAngle = animatedSVGAngle.value();
-    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle);
-    animatedSVGAngle.setValue(animatedAngle);
+    if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto || fromAngleAndEnumeration.second == SVGMarkerOrientAutoStartReverse)
+        animatedAngleAndEnumeration.second = fromAngleAndEnumeration.second;
+    else
+        animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
 }
 
 float SVGAnimatedAngleAnimator::calculateDistance(const String& fromString, const String& toString)

Modified: trunk/Source/WebCore/svg/SVGMarkerElement.cpp (197737 => 197738)


--- trunk/Source/WebCore/svg/SVGMarkerElement.cpp	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/svg/SVGMarkerElement.cpp	2016-03-08 08:20:22 UTC (rev 197738)
@@ -189,11 +189,11 @@
         object->setNeedsLayout();
 }
 
-void SVGMarkerElement::setOrientToAuto()
+void SVGMarkerElement::setOrient(SVGMarkerOrientType orientType, const SVGAngle& angle)
 {
-    setOrientTypeBaseValue(SVGMarkerOrientAuto);
-    setOrientAngleBaseValue(SVGAngle());
- 
+    setOrientTypeBaseValue(orientType);
+    setOrientAngleBaseValue(angle);
+
     // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization.
     m_orientAngle.shouldSynchronize = true;
     m_orientType.shouldSynchronize = true;
@@ -201,16 +201,14 @@
     svgAttributeChanged(orientAnglePropertyInfo()->attributeName);
 }
 
+void SVGMarkerElement::setOrientToAuto()
+{
+    setOrient(SVGMarkerOrientAuto, { });
+}
+
 void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
 {
-    setOrientTypeBaseValue(SVGMarkerOrientAngle);
-    setOrientAngleBaseValue(angle);
-
-    // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization.
-    m_orientAngle.shouldSynchronize = true;
-    m_orientType.shouldSynchronize = true;
-    invalidateSVGAttributes();
-    svgAttributeChanged(orientAnglePropertyInfo()->attributeName);
+    setOrient(SVGMarkerOrientAngle, angle);
 }
 
 RenderPtr<RenderElement> SVGMarkerElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
@@ -233,12 +231,17 @@
     if (!ownerType.m_orientType.shouldSynchronize)
         return;
 
-    // If orient is not auto, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle.
-    if (ownerType.m_orientType.value != SVGMarkerOrientAuto)
+    static NeverDestroyed<AtomicString> autoString("auto", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<AtomicString> autoStartReverseString("auto-start-reverse", AtomicString::ConstructFromLiteral);
+
+    // If orient is not auto or auto-start-reverse, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle.
+    if (ownerType.m_orientType.value == SVGMarkerOrientAuto) {
+        ownerType.m_orientType.synchronize(&ownerType, orientTypePropertyInfo()->attributeName, autoString);
         return;
+    }
 
-    static NeverDestroyed<AtomicString> autoString("auto", AtomicString::ConstructFromLiteral);
-    ownerType.m_orientType.synchronize(&ownerType, orientTypePropertyInfo()->attributeName, autoString);
+    if (ownerType.m_orientType.value == SVGMarkerOrientAutoStartReverse)
+        ownerType.m_orientType.synchronize(&ownerType, orientTypePropertyInfo()->attributeName, autoStartReverseString);
 }
 
 Ref<SVGAnimatedProperty> SVGMarkerElement::lookupOrCreateOrientTypeWrapper(SVGElement* contextElement)

Modified: trunk/Source/WebCore/svg/SVGMarkerElement.h (197737 => 197738)


--- trunk/Source/WebCore/svg/SVGMarkerElement.h	2016-03-08 08:16:29 UTC (rev 197737)
+++ trunk/Source/WebCore/svg/SVGMarkerElement.h	2016-03-08 08:20:22 UTC (rev 197738)
@@ -43,6 +43,7 @@
     SVGMarkerOrientUnknown = 0,
     SVGMarkerOrientAuto,
     SVGMarkerOrientAngle,
+    SVGMarkerOrientAutoStartReverse,
 
     // Add new elements before here.
     SVGMarkerOrientMax
@@ -78,8 +79,11 @@
 };
 
 template<>
+inline unsigned SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue() { return SVGMarkerOrientAngle; }
+
+template<>
 struct SVGPropertyTraits<SVGMarkerOrientType> {
-    static unsigned highestEnumValue() { return SVGMarkerOrientAngle; }
+    static unsigned highestEnumValue() { return SVGMarkerOrientAutoStartReverse; }
 
     // toString is not needed, synchronizeOrientType() handles this on its own.
 
@@ -87,6 +91,8 @@
     {
         if (value == "auto")
             return SVGMarkerOrientAuto;
+        if (value == "auto-start-reverse")
+            return SVGMarkerOrientAutoStartReverse;
 
         ExceptionCode ec = 0;
         angle.setValueAsString(value, ec);
@@ -110,7 +116,8 @@
     enum {
         SVG_MARKER_ORIENT_UNKNOWN = SVGMarkerOrientUnknown,
         SVG_MARKER_ORIENT_AUTO = SVGMarkerOrientAuto,
-        SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle
+        SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle,
+        SVG_MARKER_ORIENT_AUTOSTARTREVERSE = SVGMarkerOrientAutoStartReverse
     };
 
     static Ref<SVGMarkerElement> create(const QualifiedName&, Document&);
@@ -137,6 +144,8 @@
 
     bool selfHasRelativeLengths() const override;
 
+    void setOrient(SVGMarkerOrientType, const SVGAngle&);
+
     void synchronizeOrientType();
 
     static const AtomicString& orientTypeIdentifier();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to