2011-06-26 Dirk Schulze <krit@webkit.org>
authorkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Jun 2011 06:16:05 +0000 (06:16 +0000)
committerkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Jun 2011 06:16:05 +0000 (06:16 +0000)
        Reviewed by Nikolas Zimmermann.

        SVGAnimatedType should support SVGLengthList animation
        https://bugs.webkit.org/show_bug.cgi?id=63399

        Test animations of attributes with type SVGLengthList.

        * svg/animations/script-tests/svglengthlist-animation-1.js: Added.
        (sample1):
        (sample2):
        (sample3):
        (executeTest):
        * svg/animations/script-tests/svglengthlist-animation-2.js: Added.
        (sample1):
        (sample2):
        (sample3):
        (executeTest):
        * svg/animations/script-tests/svglengthlist-animation-3.js: Added.
        (sample1):
        (sample2):
        (sample3):
        (executeTest):
        * svg/animations/script-tests/svglengthlist-animation-4.js: Added.
        (sample1):
        (sample2):
        (sample3):
        (executeTest):
        * svg/animations/svglengthlist-animation-1-expected.txt: Added.
        * svg/animations/svglengthlist-animation-1.html: Added.
        * svg/animations/svglengthlist-animation-2-expected.txt: Added.
        * svg/animations/svglengthlist-animation-2.html: Added.
        * svg/animations/svglengthlist-animation-3-expected.txt: Added.
        * svg/animations/svglengthlist-animation-3.html: Added.
        * svg/animations/svglengthlist-animation-4-expected.txt: Added.
        * svg/animations/svglengthlist-animation-4.html: Added.
2011-06-26  Dirk Schulze  <krit@webkit.org>

        Reviewed by Nikolas Zimmermann.

        SVGAnimatedType should support SVGLengthList animation
        https://bugs.webkit.org/show_bug.cgi?id=63399

        Follow up of "SVGAnimation should use direct unit animation for SVGLength": https://bugs.webkit.org/show_bug.cgi?id=61368
        This patch continues the conversion to the new concept of SVGAnimatorFactory with SVGAnimatedLengthList.

        Interpolated animations of glyph positions are possible now.

        Tests: svg/animations/svglengthlist-animation-1.html
               svg/animations/svglengthlist-animation-2.html
               svg/animations/svglengthlist-animation-3.html
               svg/animations/svglengthlist-animation-4.html

        * CMakeLists.txt: Add new file to build system.
        * GNUmakefile.list.am: Ditto.
        * WebCore.gypi: Ditto.
        * WebCore.pro: Ditto.
        * WebCore.xcodeproj/project.pbxproj: Ditto.
        * svg/SVGAllInOne.cpp: Ditto.
        * svg/SVGAnimateElement.cpp: Make use of AnimatedLengthList.
        (WebCore::SVGAnimateElement::determineAnimatedAttributeType):
        (WebCore::SVGAnimateElement::calculateAnimatedValue):
        (WebCore::SVGAnimateElement::calculateFromAndToValues):
        (WebCore::SVGAnimateElement::calculateFromAndByValues):
        (WebCore::SVGAnimateElement::resetToBaseValue):
        (WebCore::SVGAnimateElement::applyResultsToTarget):
        (WebCore::SVGAnimateElement::calculateDistance):
        * svg/SVGAnimatedLengthList.cpp: Added. New animator for SVGLengthList.
        (WebCore::SVGAnimatedLengthListAnimator::SVGAnimatedLengthListAnimator):
        (WebCore::SVGAnimatedLengthListAnimator::constructFromString):
        (WebCore::SVGAnimatedLengthListAnimator::calculateFromAndToValues):
        (WebCore::SVGAnimatedLengthListAnimator::calculateFromAndByValues):
        (WebCore::SVGAnimatedLengthListAnimator::calculateAnimatedValue):
        (WebCore::SVGAnimatedLengthListAnimator::calculateDistance):
        * svg/SVGAnimatedLengthList.h:
        (WebCore::SVGAnimatedLengthListAnimator::~SVGAnimatedLengthListAnimator):
        * svg/SVGAnimatedType.cpp: Add SVGLengthList.
        (WebCore::SVGAnimatedType::~SVGAnimatedType):
        (WebCore::SVGAnimatedType::createLengthList):
        (WebCore::SVGAnimatedType::lengthList):
        (WebCore::SVGAnimatedType::valueAsString):
        (WebCore::SVGAnimatedType::setValueAsString):
        * svg/SVGAnimatedType.h:
        * svg/SVGAnimatorFactory.h:
        (WebCore::SVGAnimatorFactory::create):
        * svg/SVGLength.cpp: Add new constructor with LengthType, LengthMode and value.
        (WebCore::SVGLength::SVGLength):
        * svg/SVGLength.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@89783 268f45cc-cd09-0410-ab3c-d52691b4dbfc

28 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/animations/script-tests/svglengthlist-animation-1.js [new file with mode: 0644]
LayoutTests/svg/animations/script-tests/svglengthlist-animation-2.js [new file with mode: 0644]
LayoutTests/svg/animations/script-tests/svglengthlist-animation-3.js [new file with mode: 0644]
LayoutTests/svg/animations/script-tests/svglengthlist-animation-4.js [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-1-expected.txt [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-1.html [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-2-expected.txt [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-2.html [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-3-expected.txt [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-3.html [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-4-expected.txt [new file with mode: 0644]
LayoutTests/svg/animations/svglengthlist-animation-4.html [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/svg/SVGAllInOne.cpp
Source/WebCore/svg/SVGAnimateElement.cpp
Source/WebCore/svg/SVGAnimatedLengthList.cpp [new file with mode: 0644]
Source/WebCore/svg/SVGAnimatedLengthList.h
Source/WebCore/svg/SVGAnimatedType.cpp
Source/WebCore/svg/SVGAnimatedType.h
Source/WebCore/svg/SVGAnimatorFactory.h
Source/WebCore/svg/SVGLength.cpp
Source/WebCore/svg/SVGLength.h

index fdf1d25..fc84334 100644 (file)
@@ -1,3 +1,41 @@
+2011-06-26  Dirk Schulze  <krit@webkit.org>
+
+        Reviewed by Nikolas Zimmermann.
+
+        SVGAnimatedType should support SVGLengthList animation
+        https://bugs.webkit.org/show_bug.cgi?id=63399
+        
+        Test animations of attributes with type SVGLengthList.
+
+        * svg/animations/script-tests/svglengthlist-animation-1.js: Added.
+        (sample1):
+        (sample2):
+        (sample3):
+        (executeTest):
+        * svg/animations/script-tests/svglengthlist-animation-2.js: Added.
+        (sample1):
+        (sample2):
+        (sample3):
+        (executeTest):
+        * svg/animations/script-tests/svglengthlist-animation-3.js: Added.
+        (sample1):
+        (sample2):
+        (sample3):
+        (executeTest):
+        * svg/animations/script-tests/svglengthlist-animation-4.js: Added.
+        (sample1):
+        (sample2):
+        (sample3):
+        (executeTest):
+        * svg/animations/svglengthlist-animation-1-expected.txt: Added.
+        * svg/animations/svglengthlist-animation-1.html: Added.
+        * svg/animations/svglengthlist-animation-2-expected.txt: Added.
+        * svg/animations/svglengthlist-animation-2.html: Added.
+        * svg/animations/svglengthlist-animation-3-expected.txt: Added.
+        * svg/animations/svglengthlist-animation-3.html: Added.
+        * svg/animations/svglengthlist-animation-4-expected.txt: Added.
+        * svg/animations/svglengthlist-animation-4.html: Added.
+
 2011-06-26  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Eric Seidel.
diff --git a/LayoutTests/svg/animations/script-tests/svglengthlist-animation-1.js b/LayoutTests/svg/animations/script-tests/svglengthlist-animation-1.js
new file mode 100644 (file)
index 0000000..86efafd
--- /dev/null
@@ -0,0 +1,58 @@
+description("Test 'to' animation of SVGLengthList with LengthType number.");
+createSVGTestCase();
+
+// Setup test document
+var text = createSVGElement("text");
+text.setAttribute("id", "text");
+text.textContent = "ABCD";
+text.setAttribute("x", "50 70 90 110");
+text.setAttribute("y", "50");
+text.setAttribute("onclick", "executeTest()");
+rootSVGElement.appendChild(text);
+
+var animate = createSVGElement("animate");
+animate.setAttribute("id", "animation");
+animate.setAttribute("attributeName", "x");
+animate.setAttribute("begin", "click");
+animate.setAttribute("dur", "4s");
+animate.setAttribute("from", "50 70 90 110");
+animate.setAttribute("to", "60 90 120 150");
+text.appendChild(animate);
+
+// Setup animation test
+function sample1() {
+       shouldBe("text.x.animVal.getItem(0).value", "50");
+       shouldBe("text.x.animVal.getItem(1).value", "70");
+       shouldBe("text.x.animVal.getItem(2).value", "90");
+       shouldBe("text.x.animVal.getItem(3).value", "110");
+}
+
+function sample2() {
+       shouldBe("text.x.animVal.getItem(0).value", "55");
+       shouldBe("text.x.animVal.getItem(1).value", "80");
+       shouldBe("text.x.animVal.getItem(2).value", "105");
+       shouldBe("text.x.animVal.getItem(3).value", "130");
+}
+
+function sample3() {
+       shouldBeCloseEnough("text.x.animVal.getItem(0).value", "60", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(1).value", "90", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(2).value", "120", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(3).value", "150", 0.01);
+}
+
+function executeTest() {
+    const expectedValues = [
+        // [animationId, time, elementId, sampleCallback]
+        ["animation", 0.0,    "text", sample1],
+        ["animation", 2.0,    "text", sample2],
+        ["animation", 3.9999, "text", sample3],
+        ["animation", 4.0 ,   "text", sample1]
+    ];
+
+    runAnimationTest(expectedValues);
+}
+
+// Begin test async
+window.setTimeout("triggerUpdate(51, 49)", 0);
+var successfullyParsed = true;
diff --git a/LayoutTests/svg/animations/script-tests/svglengthlist-animation-2.js b/LayoutTests/svg/animations/script-tests/svglengthlist-animation-2.js
new file mode 100644 (file)
index 0000000..527a1f0
--- /dev/null
@@ -0,0 +1,58 @@
+description("Test 'to' animation of SVGLengthList with different LengthTypes.");
+createSVGTestCase();
+
+// Setup test document
+var text = createSVGElement("text");
+text.setAttribute("id", "text");
+text.textContent = "ABCD";
+text.setAttribute("x", "50 70 90 110");
+text.setAttribute("y", "50");
+text.setAttribute("onclick", "executeTest()");
+rootSVGElement.appendChild(text);
+
+var animate = createSVGElement("animate");
+animate.setAttribute("id", "animation");
+animate.setAttribute("attributeName", "x");
+animate.setAttribute("begin", "click");
+animate.setAttribute("dur", "4s");
+animate.setAttribute("from", "50 70px 5cm 8pt");
+animate.setAttribute("to", "3cm 80 100px 4in");
+text.appendChild(animate);
+
+// Setup animation test
+function sample1() {
+       shouldBe("text.x.animVal.getItem(0).value", "50");
+       shouldBe("text.x.animVal.getItem(1).value", "70");
+       shouldBe("text.x.animVal.getItem(2).value", "90");
+       shouldBe("text.x.animVal.getItem(3).value", "110");
+}
+
+function sample2() {
+       shouldBeCloseEnough("text.x.animVal.getItem(0).value", "81.7", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(1).value", "75", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(2).value", "144.49", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(3).value", "197.33", 0.01);
+}
+
+function sample3() {
+       shouldBeCloseEnough("text.x.animVal.getItem(0).value", "113.39", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(1).value", "80", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(2).value", "100", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(3).value", "383.99", 0.01);
+}
+
+function executeTest() {
+    const expectedValues = [
+        // [animationId, time, elementId, sampleCallback]
+        ["animation", 0.0,    "text", sample1],
+        ["animation", 2.0,    "text", sample2],
+        ["animation", 3.9999, "text", sample3],
+        ["animation", 4.0 ,   "text", sample1]
+    ];
+
+    runAnimationTest(expectedValues);
+}
+
+// Begin test async
+window.setTimeout("triggerUpdate(51, 49)", 0);
+var successfullyParsed = true;
diff --git a/LayoutTests/svg/animations/script-tests/svglengthlist-animation-3.js b/LayoutTests/svg/animations/script-tests/svglengthlist-animation-3.js
new file mode 100644 (file)
index 0000000..56ce4de
--- /dev/null
@@ -0,0 +1,58 @@
+description("Test 'to' animation of SVGLengthList with different count of items.");
+createSVGTestCase();
+
+// Setup test document
+var text = createSVGElement("text");
+text.setAttribute("id", "text");
+text.textContent = "ABCD";
+text.setAttribute("x", "50");
+text.setAttribute("y", "50");
+text.setAttribute("onclick", "executeTest()");
+rootSVGElement.appendChild(text);
+
+var animate = createSVGElement("animate");
+animate.setAttribute("id", "animation");
+animate.setAttribute("attributeName", "x");
+animate.setAttribute("begin", "click");
+animate.setAttribute("dur", "4s");
+animate.setAttribute("from", "50");
+animate.setAttribute("to", "70 80 90 110");
+text.appendChild(animate);
+
+// Setup animation test
+function sample1() {
+       shouldBe("text.x.animVal.numberOfItems", "1");
+       shouldBe("text.x.animVal.getItem(0).value", "50");
+}
+
+function sample2() {
+       shouldBe("text.x.animVal.numberOfItems", "4");
+       shouldBeCloseEnough("text.x.animVal.getItem(0).value", "70", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(1).value", "80", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(2).value", "90", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(3).value", "110", 0.01);
+}
+
+function sample3() {
+       shouldBe("text.x.animVal.numberOfItems", "4");
+       shouldBeCloseEnough("text.x.animVal.getItem(0).value", "70", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(1).value", "80", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(2).value", "90", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(3).value", "110", 0.01);
+}
+
+function executeTest() {
+    const expectedValues = [
+        // [animationId, time, elementId, sampleCallback]
+        ["animation", 0.0,    "text", sample1],
+        ["animation", 2.0,    "text", sample2],
+        ["animation", 3.9999, "text", sample3],
+        ["animation", 4.0 ,   "text", sample1]
+    ];
+
+    runAnimationTest(expectedValues);
+}
+
+// Begin test async
+window.setTimeout("triggerUpdate(51, 49)", 0);
+var successfullyParsed = true;
diff --git a/LayoutTests/svg/animations/script-tests/svglengthlist-animation-4.js b/LayoutTests/svg/animations/script-tests/svglengthlist-animation-4.js
new file mode 100644 (file)
index 0000000..5c49492
--- /dev/null
@@ -0,0 +1,59 @@
+description("Test 'by' animation of SVGLengthList.");
+createSVGTestCase();
+
+// Setup test document
+var text = createSVGElement("text");
+text.setAttribute("id", "text");
+text.textContent = "ABCD";
+text.setAttribute("x", "50 60 70 80");
+text.setAttribute("y", "50");
+text.setAttribute("onclick", "executeTest()");
+rootSVGElement.appendChild(text);
+
+var animate = createSVGElement("animate");
+animate.setAttribute("id", "animation");
+animate.setAttribute("attributeName", "x");
+animate.setAttribute("begin", "click");
+animate.setAttribute("dur", "4s");
+animate.setAttribute("from", "50 60 70 80");
+animate.setAttribute("by", "20 20 20 20");
+text.appendChild(animate);
+
+// Setup animation test
+function sample1() {
+       shouldBe("text.x.animVal.getItem(0).value", "50");
+       shouldBe("text.x.animVal.getItem(1).value", "60");
+       shouldBe("text.x.animVal.getItem(2).value", "70");
+       shouldBe("text.x.animVal.getItem(3).value", "80");
+}
+
+function sample2() {
+       shouldBe("text.x.animVal.getItem(0).value", "60");
+       shouldBe("text.x.animVal.getItem(1).value", "70");
+       shouldBe("text.x.animVal.getItem(2).value", "80");
+       shouldBe("text.x.animVal.getItem(3).value", "90");
+}
+
+function sample3() {
+       shouldBe("text.x.animVal.numberOfItems", "4");
+       shouldBeCloseEnough("text.x.animVal.getItem(0).value", "70", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(1).value", "80", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(2).value", "90", 0.01);
+       shouldBeCloseEnough("text.x.animVal.getItem(3).value", "100", 0.01);
+}
+
+function executeTest() {
+    const expectedValues = [
+        // [animationId, time, elementId, sampleCallback]
+        ["animation", 0.0,    "text", sample1],
+        ["animation", 2.0,    "text", sample2],
+        ["animation", 3.9999, "text", sample3],
+        ["animation", 4.0 ,   "text", sample1]
+    ];
+
+    runAnimationTest(expectedValues);
+}
+
+// Begin test async
+window.setTimeout("triggerUpdate(51, 49)", 0);
+var successfullyParsed = true;
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-1-expected.txt b/LayoutTests/svg/animations/svglengthlist-animation-1-expected.txt
new file mode 100644 (file)
index 0000000..1b2a13e
--- /dev/null
@@ -0,0 +1,28 @@
+SVG 1.1 dynamic animation tests
+
+ABCD
+Test 'to' animation of SVGLengthList with LengthType number.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS text.x.animVal.getItem(0).value is 50
+PASS text.x.animVal.getItem(1).value is 70
+PASS text.x.animVal.getItem(2).value is 90
+PASS text.x.animVal.getItem(3).value is 110
+PASS text.x.animVal.getItem(0).value is 55
+PASS text.x.animVal.getItem(1).value is 80
+PASS text.x.animVal.getItem(2).value is 105
+PASS text.x.animVal.getItem(3).value is 130
+PASS text.x.animVal.getItem(0).value is 60
+PASS text.x.animVal.getItem(1).value is 90
+PASS text.x.animVal.getItem(2).value is 120
+PASS text.x.animVal.getItem(3).value is 150
+PASS text.x.animVal.getItem(0).value is 50
+PASS text.x.animVal.getItem(1).value is 70
+PASS text.x.animVal.getItem(2).value is 90
+PASS text.x.animVal.getItem(3).value is 110
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-1.html b/LayoutTests/svg/animations/svglengthlist-animation-1.html
new file mode 100644 (file)
index 0000000..477413b
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="../dynamic-updates/resources/SVGTestCase.js"></script>
+<script src="resources/SVGAnimationTestCase.js"></script>
+</head>
+<body>
+<h1>SVG 1.1 dynamic animation tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/svglengthlist-animation-1.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-2-expected.txt b/LayoutTests/svg/animations/svglengthlist-animation-2-expected.txt
new file mode 100644 (file)
index 0000000..2a3b0c5
--- /dev/null
@@ -0,0 +1,28 @@
+SVG 1.1 dynamic animation tests
+
+ABCD
+Test 'to' animation of SVGLengthList with different LengthTypes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS text.x.animVal.getItem(0).value is 50
+PASS text.x.animVal.getItem(1).value is 70
+PASS text.x.animVal.getItem(2).value is 90
+PASS text.x.animVal.getItem(3).value is 110
+PASS text.x.animVal.getItem(0).value is 81.7
+PASS text.x.animVal.getItem(1).value is 75
+PASS text.x.animVal.getItem(2).value is 144.49
+PASS text.x.animVal.getItem(3).value is 197.33
+PASS text.x.animVal.getItem(0).value is 113.39
+PASS text.x.animVal.getItem(1).value is 80
+PASS text.x.animVal.getItem(2).value is 100
+PASS text.x.animVal.getItem(3).value is 383.99
+PASS text.x.animVal.getItem(0).value is 50
+PASS text.x.animVal.getItem(1).value is 70
+PASS text.x.animVal.getItem(2).value is 90
+PASS text.x.animVal.getItem(3).value is 110
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-2.html b/LayoutTests/svg/animations/svglengthlist-animation-2.html
new file mode 100644 (file)
index 0000000..44bbb46
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="../dynamic-updates/resources/SVGTestCase.js"></script>
+<script src="resources/SVGAnimationTestCase.js"></script>
+</head>
+<body>
+<h1>SVG 1.1 dynamic animation tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/svglengthlist-animation-2.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-3-expected.txt b/LayoutTests/svg/animations/svglengthlist-animation-3-expected.txt
new file mode 100644 (file)
index 0000000..93162b4
--- /dev/null
@@ -0,0 +1,26 @@
+SVG 1.1 dynamic animation tests
+
+ABCD
+Test 'to' animation of SVGLengthList with different count of items.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS text.x.animVal.numberOfItems is 1
+PASS text.x.animVal.getItem(0).value is 50
+PASS text.x.animVal.numberOfItems is 4
+PASS text.x.animVal.getItem(0).value is 70
+PASS text.x.animVal.getItem(1).value is 80
+PASS text.x.animVal.getItem(2).value is 90
+PASS text.x.animVal.getItem(3).value is 110
+PASS text.x.animVal.numberOfItems is 4
+PASS text.x.animVal.getItem(0).value is 70
+PASS text.x.animVal.getItem(1).value is 80
+PASS text.x.animVal.getItem(2).value is 90
+PASS text.x.animVal.getItem(3).value is 110
+PASS text.x.animVal.numberOfItems is 1
+PASS text.x.animVal.getItem(0).value is 50
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-3.html b/LayoutTests/svg/animations/svglengthlist-animation-3.html
new file mode 100644 (file)
index 0000000..d403de5
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="../dynamic-updates/resources/SVGTestCase.js"></script>
+<script src="resources/SVGAnimationTestCase.js"></script>
+</head>
+<body>
+<h1>SVG 1.1 dynamic animation tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/svglengthlist-animation-3.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-4-expected.txt b/LayoutTests/svg/animations/svglengthlist-animation-4-expected.txt
new file mode 100644 (file)
index 0000000..3e39eef
--- /dev/null
@@ -0,0 +1,29 @@
+SVG 1.1 dynamic animation tests
+
+ABCD
+Test 'by' animation of SVGLengthList.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS text.x.animVal.getItem(0).value is 50
+PASS text.x.animVal.getItem(1).value is 60
+PASS text.x.animVal.getItem(2).value is 70
+PASS text.x.animVal.getItem(3).value is 80
+PASS text.x.animVal.getItem(0).value is 60
+PASS text.x.animVal.getItem(1).value is 70
+PASS text.x.animVal.getItem(2).value is 80
+PASS text.x.animVal.getItem(3).value is 90
+PASS text.x.animVal.numberOfItems is 4
+PASS text.x.animVal.getItem(0).value is 70
+PASS text.x.animVal.getItem(1).value is 80
+PASS text.x.animVal.getItem(2).value is 90
+PASS text.x.animVal.getItem(3).value is 100
+PASS text.x.animVal.getItem(0).value is 50
+PASS text.x.animVal.getItem(1).value is 60
+PASS text.x.animVal.getItem(2).value is 70
+PASS text.x.animVal.getItem(3).value is 80
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/animations/svglengthlist-animation-4.html b/LayoutTests/svg/animations/svglengthlist-animation-4.html
new file mode 100644 (file)
index 0000000..8c14217
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="../dynamic-updates/resources/SVGTestCase.js"></script>
+<script src="resources/SVGAnimationTestCase.js"></script>
+</head>
+<body>
+<h1>SVG 1.1 dynamic animation tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/svglengthlist-animation-4.js"></script>
+</body>
+</html>
index fa97271..2d3e94a 100644 (file)
@@ -1659,6 +1659,7 @@ IF (ENABLE_SVG)
         svg/SVGAnimatedAngle.cpp
         svg/SVGAnimatedColor.cpp
         svg/SVGAnimatedLength.cpp
+        svg/SVGAnimatedLengthList.cpp
         svg/SVGAnimatedNumber.cpp
         svg/SVGAnimatedNumberList.cpp
         svg/SVGAnimatedNumberOptionalNumber.cpp
index da38775..fbf0f2a 100644 (file)
@@ -1,3 +1,56 @@
+2011-06-26  Dirk Schulze  <krit@webkit.org>
+
+        Reviewed by Nikolas Zimmermann.
+
+        SVGAnimatedType should support SVGLengthList animation
+        https://bugs.webkit.org/show_bug.cgi?id=63399
+
+        Follow up of "SVGAnimation should use direct unit animation for SVGLength": https://bugs.webkit.org/show_bug.cgi?id=61368
+        This patch continues the conversion to the new concept of SVGAnimatorFactory with SVGAnimatedLengthList.
+        
+        Interpolated animations of glyph positions are possible now.
+
+        Tests: svg/animations/svglengthlist-animation-1.html
+               svg/animations/svglengthlist-animation-2.html
+               svg/animations/svglengthlist-animation-3.html
+               svg/animations/svglengthlist-animation-4.html
+
+        * CMakeLists.txt: Add new file to build system.
+        * GNUmakefile.list.am: Ditto.
+        * WebCore.gypi: Ditto.
+        * WebCore.pro: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * svg/SVGAllInOne.cpp: Ditto.
+        * svg/SVGAnimateElement.cpp: Make use of AnimatedLengthList.
+        (WebCore::SVGAnimateElement::determineAnimatedAttributeType):
+        (WebCore::SVGAnimateElement::calculateAnimatedValue):
+        (WebCore::SVGAnimateElement::calculateFromAndToValues):
+        (WebCore::SVGAnimateElement::calculateFromAndByValues):
+        (WebCore::SVGAnimateElement::resetToBaseValue):
+        (WebCore::SVGAnimateElement::applyResultsToTarget):
+        (WebCore::SVGAnimateElement::calculateDistance):
+        * svg/SVGAnimatedLengthList.cpp: Added. New animator for SVGLengthList.
+        (WebCore::SVGAnimatedLengthListAnimator::SVGAnimatedLengthListAnimator):
+        (WebCore::SVGAnimatedLengthListAnimator::constructFromString):
+        (WebCore::SVGAnimatedLengthListAnimator::calculateFromAndToValues):
+        (WebCore::SVGAnimatedLengthListAnimator::calculateFromAndByValues):
+        (WebCore::SVGAnimatedLengthListAnimator::calculateAnimatedValue):
+        (WebCore::SVGAnimatedLengthListAnimator::calculateDistance):
+        * svg/SVGAnimatedLengthList.h:
+        (WebCore::SVGAnimatedLengthListAnimator::~SVGAnimatedLengthListAnimator):
+        * svg/SVGAnimatedType.cpp: Add SVGLengthList.
+        (WebCore::SVGAnimatedType::~SVGAnimatedType):
+        (WebCore::SVGAnimatedType::createLengthList):
+        (WebCore::SVGAnimatedType::lengthList):
+        (WebCore::SVGAnimatedType::valueAsString):
+        (WebCore::SVGAnimatedType::setValueAsString):
+        * svg/SVGAnimatedType.h:
+        * svg/SVGAnimatorFactory.h:
+        (WebCore::SVGAnimatorFactory::create):
+        * svg/SVGLength.cpp: Add new constructor with LengthType, LengthMode and value.
+        (WebCore::SVGLength::SVGLength):
+        * svg/SVGLength.h:
+
 2011-06-26  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Eric Seidel.
index 23c01a3..6467b04 100644 (file)
@@ -3430,6 +3430,7 @@ webcore_sources += \
        Source/WebCore/svg/SVGAnimatedInteger.h \
        Source/WebCore/svg/SVGAnimatedLength.cpp \
        Source/WebCore/svg/SVGAnimatedLength.h \
+       Source/WebCore/svg/SVGAnimatedLengthList.cpp \
        Source/WebCore/svg/SVGAnimatedLengthList.h \
        Source/WebCore/svg/SVGAnimatedNumber.cpp \
        Source/WebCore/svg/SVGAnimatedNumber.h \
index 16a99c8..2214672 100644 (file)
             'svg/SVGAnimatedAngle.cpp',
             'svg/SVGAnimatedColor.cpp',
             'svg/SVGAnimatedLength.cpp',
+            'svg/SVGAnimatedLengthList.cpp',
             'svg/SVGAnimatedNumber.cpp',
             'svg/SVGAnimatedNumberList.cpp',
             'svg/SVGAnimatedNumberOptionalNumber.cpp',
index ac52de1..18224e4 100644 (file)
@@ -3339,6 +3339,7 @@ contains(DEFINES, ENABLE_SVG=1) {
               svg/SVGAnimatedAngle.cpp \
               svg/SVGAnimatedColor.cpp \
               svg/SVGAnimatedLength.cpp \
+              svg/SVGAnimatedLengthList.cpp \
               svg/SVGAnimatedNumber.cpp \
               svg/SVGAnimatedNumberList.cpp \
               svg/SVGAnimatedNumberOptionalNumber.cpp \
index 669edd1..3462954 100644 (file)
                43142E7A13B1E97700F1C871 /* SVGAnimatedRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43142E7913B1E97700F1C871 /* SVGAnimatedRect.cpp */; };
                431A2F9C13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 431A2F9A13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h */; };
                431A2F9D13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 431A2F9B13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.cpp */; };
+               431A2FD713B7707A007791E4 /* SVGAnimatedLengthList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 431A2FD613B7707A007791E4 /* SVGAnimatedLengthList.cpp */; };
                4331AC7813B6870000A9E5AE /* SVGAnimatedNumberList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4331AC7713B6870000A9E5AE /* SVGAnimatedNumberList.cpp */; };
                4358E86A1360A21600E4748C /* DOMSVGFEDropShadowElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4358E8671360A21600E4748C /* DOMSVGFEDropShadowElement.h */; };
                4358E86B1360A21600E4748C /* DOMSVGFEDropShadowElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4358E8681360A21600E4748C /* DOMSVGFEDropShadowElement.mm */; };
                43142E7913B1E97700F1C871 /* SVGAnimatedRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedRect.cpp; sourceTree = "<group>"; };
                431A2F9A13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedNumberOptionalNumber.h; sourceTree = "<group>"; };
                431A2F9B13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedNumberOptionalNumber.cpp; sourceTree = "<group>"; };
+               431A2FD613B7707A007791E4 /* SVGAnimatedLengthList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedLengthList.cpp; sourceTree = "<group>"; };
                4331AC7713B6870000A9E5AE /* SVGAnimatedNumberList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedNumberList.cpp; sourceTree = "<group>"; };
                4358E8671360A21600E4748C /* DOMSVGFEDropShadowElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMSVGFEDropShadowElement.h; sourceTree = "<group>"; };
                4358E8681360A21600E4748C /* DOMSVGFEDropShadowElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMSVGFEDropShadowElement.mm; sourceTree = "<group>"; };
                                4381763A13A697D4007D1187 /* SVGAnimatedLength.cpp */,
                                089021A8126EF5DE0092D5EA /* SVGAnimatedLength.h */,
                                B22277EA0D00BF1F0071B782 /* SVGAnimatedLength.idl */,
+                               431A2FD613B7707A007791E4 /* SVGAnimatedLengthList.cpp */,
                                089021AC126EF5E90092D5EA /* SVGAnimatedLengthList.h */,
                                B22277EB0D00BF1F0071B782 /* SVGAnimatedLengthList.idl */,
                                43A0F0B013AC7D6D00A5F0A7 /* SVGAnimatedNumber.cpp */,
                                376DCCE113B4F966002EBEFC /* TextRun.cpp in Sources */,
                                4331AC7813B6870000A9E5AE /* SVGAnimatedNumberList.cpp in Sources */,
                                431A2F9D13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.cpp in Sources */,
+                               431A2FD713B7707A007791E4 /* SVGAnimatedLengthList.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 8377eef..076f775 100644 (file)
@@ -33,6 +33,7 @@
 #include "SVGAnimatedAngle.cpp"
 #include "SVGAnimatedColor.cpp"
 #include "SVGAnimatedLength.cpp"
+#include "SVGAnimatedLengthList.cpp"
 #include "SVGAnimatedNumber.cpp"
 #include "SVGAnimatedNumberList.cpp"
 #include "SVGAnimatedNumberOptionalNumber.cpp"
index d338a69..179ff00 100644 (file)
@@ -111,7 +111,6 @@ AnimatedAttributeType SVGAnimateElement::determineAnimatedAttributeType(SVGEleme
         return AnimatedAngle;
     case AnimatedBoolean:
     case AnimatedEnumeration:
-    case AnimatedLengthList:
     case AnimatedPreserveAspectRatio:
     case AnimatedString:
         return AnimatedString;
@@ -119,6 +118,8 @@ AnimatedAttributeType SVGAnimateElement::determineAnimatedAttributeType(SVGEleme
         return AnimatedColor;
     case AnimatedLength:
         return AnimatedLength;
+    case AnimatedLengthList:
+        return AnimatedLengthList;
     case AnimatedInteger:
     case AnimatedNumber:
         return AnimatedNumber;
@@ -164,6 +165,7 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
     case AnimatedAngle:
     case AnimatedColor:
     case AnimatedLength:
+    case AnimatedLengthList:
     case AnimatedNumber:
     case AnimatedNumberList:
     case AnimatedNumberOptionalNumber:
@@ -231,6 +233,7 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const
     case AnimatedAngle:
     case AnimatedColor:
     case AnimatedLength:
+    case AnimatedLengthList:
     case AnimatedNumber:
     case AnimatedNumberList:
     case AnimatedNumberOptionalNumber:
@@ -259,6 +262,7 @@ bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const
     case AnimatedAngle:
     case AnimatedColor:
     case AnimatedLength:
+    case AnimatedLengthList:
     case AnimatedNumber:
     case AnimatedNumberList:
     case AnimatedNumberOptionalNumber:
@@ -286,6 +290,7 @@ void SVGAnimateElement::resetToBaseValue(const String& baseString)
     case AnimatedAngle:
     case AnimatedColor:
     case AnimatedLength:
+    case AnimatedLengthList:
     case AnimatedNumber:
     case AnimatedNumberList:
     case AnimatedNumberOptionalNumber:
@@ -312,6 +317,7 @@ void SVGAnimateElement::applyResultsToTarget()
     case AnimatedAngle:
     case AnimatedColor:
     case AnimatedLength:
+    case AnimatedLengthList:
     case AnimatedNumber:
     case AnimatedNumberList:
     case AnimatedNumberOptionalNumber:
@@ -338,6 +344,7 @@ float SVGAnimateElement::calculateDistance(const String& fromString, const Strin
     case AnimatedAngle:
     case AnimatedColor:
     case AnimatedLength:
+    case AnimatedLengthList:
     case AnimatedNumber:
     case AnimatedNumberList:
     case AnimatedNumberOptionalNumber:
diff --git a/Source/WebCore/svg/SVGAnimatedLengthList.cpp b/Source/WebCore/svg/SVGAnimatedLengthList.cpp
new file mode 100644 (file)
index 0000000..7c1de89
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
+#include "SVGAnimatedLengthList.h"
+
+#include "SVGAnimateElement.h"
+#include "SVGAnimatedNumber.h"
+
+namespace WebCore {
+
+SVGAnimatedLengthListAnimator::SVGAnimatedLengthListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
+    : SVGAnimatedTypeAnimator(AnimatedLengthList, animationElement, contextElement)
+    , m_lengthMode(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()))
+{
+}
+
+PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthListAnimator::constructFromString(const String& string)
+{
+    OwnPtr<SVGAnimatedType> animateType = SVGAnimatedType::createLengthList(new SVGLengthList);
+    animateType->lengthList().parse(string, m_lengthMode);
+    return animateType.release();
+}
+
+void SVGAnimatedLengthListAnimator::calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString)
+{
+    ASSERT(m_contextElement);
+    ASSERT(m_animationElement);
+    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
+    animationElement->determinePropertyValueTypes(fromString, toString);
+    
+    from = constructFromString(fromString);
+    to = constructFromString(toString);
+}
+
+void SVGAnimatedLengthListAnimator::calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString)
+{
+    ASSERT(m_contextElement);
+    ASSERT(m_animationElement);
+    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
+    animationElement->determinePropertyValueTypes(fromString, byString);
+    
+    from = constructFromString(fromString);
+    to = constructFromString(byString);
+    
+    SVGLengthList& fromLengthList = from->lengthList();
+    SVGLengthList& toLengthList = to->lengthList();
+    unsigned itemsCount = fromLengthList.size();
+    if (itemsCount != toLengthList.size())
+        return;
+    ExceptionCode ec = 0;
+    for (unsigned i = 0; i < itemsCount; ++i) {
+        toLengthList[i].setValue(toLengthList[i].value(m_contextElement) + fromLengthList[i].value(m_contextElement), m_contextElement, ec);
+        ASSERT(!ec);
+    }
+}
+
+void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
+                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+{
+    ASSERT(m_animationElement);
+    ASSERT(m_contextElement);
+
+    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
+    AnimationMode animationMode = animationElement->animationMode();
+
+    // To animation uses contributions from the lower priority animations as the base value.
+    SVGLengthList& fromLengthList = from->lengthList();
+    SVGLengthList& animatedLengthList = animated->lengthList();
+    if (animationMode == ToAnimation)
+        fromLengthList = animatedLengthList;
+    
+    // Replace 'inherit' by their computed property values.    
+    SVGLengthList& toLengthList = to->lengthList();
+    if (animationElement->fromPropertyValueType() == InheritValue) {
+        String fromLengthString;
+        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromLengthString);
+        fromLengthList.parse(fromLengthString, m_lengthMode);
+    }
+    if (animationElement->toPropertyValueType() == InheritValue) {
+        String toLengthString;
+        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toLengthString);
+        toLengthList.parse(toLengthString, m_lengthMode);
+    }
+
+    unsigned itemsCount = fromLengthList.size();
+    if (itemsCount != toLengthList.size()) {
+        if (percentage < 0.5) {
+            if (animationMode != ToAnimation)
+                animatedLengthList = fromLengthList;
+        } else
+            animatedLengthList = toLengthList;
+        return;
+    }
+    
+    animatedLengthList.clear();
+    for (unsigned i = 0; i < itemsCount; ++i) {
+        float result = 0;
+        SVGLengthType unitType = percentage < 0.5 ? fromLengthList[i].unitType() : toLengthList[i].unitType();
+        SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, result, fromLengthList[i].value(m_contextElement), toLengthList[i].value(m_contextElement));
+        animatedLengthList.append(SVGLength(m_contextElement, result, m_lengthMode, unitType));
+    }
+}
+
+float SVGAnimatedLengthListAnimator::calculateDistance(const String&, const String&)
+{
+    // FIXME: Distance calculation is not possible for SVGLengthList right now. We need the distance for every single value.
+    return -1;
+}
+
+}
+
+#endif // ENABLE(SVG) && ENABLE(SVG_ANIMATION)
index a0217fa..01cec8c 100644 (file)
@@ -22,6 +22,7 @@
 
 #if ENABLE(SVG)
 #include "SVGAnimatedListPropertyTearOff.h"
+#include "SVGAnimatedTypeAnimator.h"
 #include "SVGLengthList.h"
 
 namespace WebCore {
@@ -34,6 +35,28 @@ DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedLengthList, SVGLengthList, UpperProper
 
 #define DEFINE_ANIMATED_LENGTH_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
 DEFINE_ANIMATED_LIST_PROPERTY(OwnerType, DOMAttribute, DOMAttribute.localName(), SVGAnimatedLengthList, SVGLengthList, UpperProperty, LowerProperty)
+    
+#if ENABLE(SVG_ANIMATION)
+class SVGAnimationElement;
+
+class SVGAnimatedLengthListAnimator : public SVGAnimatedTypeAnimator {
+    
+public:
+    SVGAnimatedLengthListAnimator(SVGAnimationElement*, SVGElement*);
+    virtual ~SVGAnimatedLengthListAnimator() { }
+    
+    virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
+    
+    virtual void calculateFromAndToValues(OwnPtr<SVGAnimatedType>& fromValue, OwnPtr<SVGAnimatedType>& toValue, const String& fromString, const String& toString);
+    virtual void calculateFromAndByValues(OwnPtr<SVGAnimatedType>& fromValue, OwnPtr<SVGAnimatedType>& toValue, const String& fromString, const String& byString);
+    virtual void calculateAnimatedValue(float percentage, unsigned repeatCount,
+                                        OwnPtr<SVGAnimatedType>& fromValue, OwnPtr<SVGAnimatedType>& toValue, OwnPtr<SVGAnimatedType>& animatedValue);
+    virtual float calculateDistance(const String& fromString, const String& toString);
+    
+private:
+    SVGLengthMode m_lengthMode;
+};
+#endif // ENABLE(SVG_ANIMATION)
 
 } // namespace WebCore
 
index 2b4ab60..a4a4f19 100644 (file)
@@ -26,6 +26,7 @@
 #include "SVGAngle.h"
 #include "SVGColor.h"
 #include "SVGLength.h"
+#include "SVGLengthList.h"
 #include "SVGNumberList.h"
 #include "SVGParserUtilities.h"
 #include "SVGPathParserFactory.h"
@@ -52,6 +53,9 @@ SVGAnimatedType::~SVGAnimatedType()
     case AnimatedLength:
         delete m_data.length;
         break;
+    case AnimatedLengthList:
+        delete m_data.lengthList;
+        break;
     case AnimatedNumber:
         delete m_data.number;
         break;
@@ -103,6 +107,14 @@ PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLength(SVGLength* length)
     return animatedType.release();
 }
 
+PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLengthList(SVGLengthList* lengthList)
+{
+    ASSERT(lengthList);
+    OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedLengthList));
+    animatedType->m_data.lengthList = lengthList;
+    return animatedType.release();
+}
+
 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumber(float* number)
 {
     ASSERT(number);
@@ -177,6 +189,12 @@ SVGLength& SVGAnimatedType::length()
     return *m_data.length;
 }
 
+SVGLengthList& SVGAnimatedType::lengthList()
+{
+    ASSERT(m_type == AnimatedLengthList);
+    return *m_data.lengthList;
+}
+
 float& SVGAnimatedType::number()
 {
     ASSERT(m_type == AnimatedNumber);
@@ -231,6 +249,9 @@ String SVGAnimatedType::valueAsString()
     case AnimatedLength:
         ASSERT(m_data.length);
         return m_data.length->valueAsString();
+    case AnimatedLengthList:
+        ASSERT(m_data.lengthList);
+        return m_data.lengthList->valueAsString();
     case AnimatedNumber:
         ASSERT(m_data.number);
         return String::number(*m_data.number);
@@ -279,6 +300,10 @@ bool SVGAnimatedType::setValueAsString(const QualifiedName& attrName, const Stri
         ASSERT(m_data.length);
         m_data.length->setValueAsString(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName), ec);
         break;
+    case AnimatedLengthList:
+        ASSERT(m_data.lengthList);
+        m_data.lengthList->parse(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName));
+        break;
     case AnimatedNumber:
         ASSERT(m_data.number);
         parseNumberFromString(value, *m_data.number);
index b1bb667..9bda35d 100644 (file)
@@ -31,6 +31,7 @@ class Color;
 class FloatRect;
 class SVGAngle;
 class SVGLength;
+class SVGLengthList;
 class SVGNumberList;
 class SVGPathByteStream;
 class SVGPointList;
@@ -43,6 +44,7 @@ public:
     static PassOwnPtr<SVGAnimatedType> createAngle(SVGAngle*);
     static PassOwnPtr<SVGAnimatedType> createColor(Color*);
     static PassOwnPtr<SVGAnimatedType> createLength(SVGLength*);
+    static PassOwnPtr<SVGAnimatedType> createLengthList(SVGLengthList*);
     static PassOwnPtr<SVGAnimatedType> createNumber(float*);
     static PassOwnPtr<SVGAnimatedType> createNumberList(SVGNumberList*);
     static PassOwnPtr<SVGAnimatedType> createNumberOptionalNumber(pair<float, float>*);
@@ -56,6 +58,7 @@ public:
     SVGAngle& angle();
     Color& color();
     SVGLength& length();
+    SVGLengthList& lengthList();
     float& number();
     SVGNumberList& numberList();
     pair<float, float>& numberOptionalNumber();
@@ -82,6 +85,7 @@ private:
         SVGAngle* angle;
         Color* color;
         SVGLength* length;
+        SVGLengthList* lengthList;
         float* number;
         SVGNumberList* numberList;
         pair<float, float>* numberOptionalNumber;
index d557be4..ffedad9 100644 (file)
@@ -24,6 +24,7 @@
 #include "SVGAnimatedAngle.h"
 #include "SVGAnimatedColor.h"
 #include "SVGAnimatedLength.h"
+#include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedNumber.h"
 #include "SVGAnimatedNumberList.h"
 #include "SVGAnimatedNumberOptionalNumber.h"
@@ -51,6 +52,8 @@ public:
             return adoptPtr(new SVGAnimatedColorAnimator(animationElement, contextElement));
         case AnimatedLength:
             return adoptPtr(new SVGAnimatedLengthAnimator(animationElement, contextElement));
+        case AnimatedLengthList:
+            return adoptPtr(new SVGAnimatedLengthListAnimator(animationElement, contextElement));
         case AnimatedNumber:
             return adoptPtr(new SVGAnimatedNumberAnimator(animationElement, contextElement));
         case AnimatedNumberList:
index d3fa279..1baa386 100644 (file)
@@ -131,7 +131,16 @@ SVGLength::SVGLength(SVGLengthMode mode, const String& valueAsString)
     ExceptionCode ec = 0;
     setValueAsString(valueAsString, ec);
 }
-    
+
+SVGLength::SVGLength(const SVGElement* context, float value, SVGLengthMode mode, SVGLengthType unitType)
+    : m_valueInSpecifiedUnits(0)
+    , m_unit(storeUnit(mode, unitType))
+{
+    ExceptionCode ec = 0;
+    setValue(value, context, ec);
+    ASSERT(!ec);
+}
+
 void SVGLength::setValueAsString(const String& valueAsString, SVGLengthMode mode, ExceptionCode& ec)
 {
     m_valueInSpecifiedUnits = 0;
index 94f47db..8838254 100644 (file)
@@ -70,6 +70,7 @@ public:
     };
 
     SVGLength(SVGLengthMode mode = LengthModeOther, const String& valueAsString = String());
+    SVGLength(const SVGElement*, float, SVGLengthMode mode = LengthModeOther, SVGLengthType type = LengthTypeNumber);
     SVGLength(const SVGLength&);
 
     SVGLengthType unitType() const;