Title: [104719] trunk
Revision
104719
Author
[email protected]
Date
2012-01-11 09:54:43 -0800 (Wed, 11 Jan 2012)

Log Message

Implement setCurrentTime() and pauseAnimations() on SVGSVGElement
https://bugs.webkit.org/show_bug.cgi?id=12073

Patch by Joel Webber <[email protected]> on 2012-01-11
Reviewed by Nikolas Zimmermann.

Source/WebCore:

Adds the ability to reset an SVGSMILElement internally. SVGSMILElements are no longer removed
from their containers when they become inactive, because they sometimes have to be reactivated
when the container's current time is changed.

Test: svg/animations/animate-setcurrenttime.html

* svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::setCurrentTime):
* svg/animation/SMILTimeContainer.cpp:
(WebCore::SMILTimeContainer::SMILTimeContainer):
(WebCore::SMILTimeContainer::begin):
(WebCore::SMILTimeContainer::pause):
(WebCore::SMILTimeContainer::setElapsed):
(WebCore::SMILTimeContainer::updateAnimations):
* svg/animation/SMILTimeContainer.h:
* svg/animation/SVGSMILElement.cpp:
(WebCore::SVGSMILElement::reset):
* svg/animation/SVGSMILElement.h:

LayoutTests:

* platform/chromium-linux/svg/animations/animate-setcurrenttime-expected.png: Added.
* platform/chromium-linux/svg/animations/animate-setcurrenttime-expected.txt: Added.
* svg/animations/animate-setcurrenttime.svg: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (104718 => 104719)


--- trunk/LayoutTests/ChangeLog	2012-01-11 17:49:43 UTC (rev 104718)
+++ trunk/LayoutTests/ChangeLog	2012-01-11 17:54:43 UTC (rev 104719)
@@ -1,3 +1,14 @@
+2012-01-11  Joel Webber  <[email protected]>
+
+        Implement setCurrentTime() and pauseAnimations() on SVGSVGElement
+        https://bugs.webkit.org/show_bug.cgi?id=12073
+
+        Reviewed by Nikolas Zimmermann.
+
+        * platform/chromium-linux/svg/animations/animate-setcurrenttime-expected.png: Added.
+        * platform/chromium-linux/svg/animations/animate-setcurrenttime-expected.txt: Added.
+        * svg/animations/animate-setcurrenttime.svg: Added.
+
 2012-01-11  Stephen Chenney  <[email protected]>
 
         REGRESSION(r103130) - svg/W3C-SVG-1.1/animate-elem-*-t.svg asserting

Added: trunk/LayoutTests/svg/animations/animate-setcurrenttime-expected.txt (0 => 104719)


--- trunk/LayoutTests/svg/animations/animate-setcurrenttime-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-setcurrenttime-expected.txt	2012-01-11 17:54:43 UTC (rev 104719)
@@ -0,0 +1,93 @@
+SVG 1.1 dynamic animation tests
+
+ PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 128
+PASS sequential.x.animVal.value is 128
+PASS accumulating.x.animVal.value is 128
+PASS repeating.x.animVal.value is 128
+PASS nested.x.animVal.value is 128
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 32
+PASS sequential.x.animVal.value is 32
+PASS accumulating.x.animVal.value is 128
+PASS repeating.x.animVal.value is 128
+PASS nested.x.animVal.value is 32
+PASS plain.x.animVal.value is 64
+PASS sequential.x.animVal.value is 32
+PASS accumulating.x.animVal.value is 256
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 64
+PASS plain.x.animVal.value is 96
+PASS sequential.x.animVal.value is 64
+PASS accumulating.x.animVal.value is 192
+PASS repeating.x.animVal.value is 128
+PASS nested.x.animVal.value is 96
+PASS plain.x.animVal.value is 128
+PASS sequential.x.animVal.value is 128
+PASS accumulating.x.animVal.value is 128
+PASS repeating.x.animVal.value is 128
+PASS nested.x.animVal.value is 128
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 32
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 64
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 96
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 128
+PASS plain.x.animVal.value is 0
+PASS sequential.x.animVal.value is 0
+PASS accumulating.x.animVal.value is 0
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 32
+PASS sequential.x.animVal.value is 32
+PASS accumulating.x.animVal.value is 128
+PASS repeating.x.animVal.value is 128
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 64
+PASS sequential.x.animVal.value is 32
+PASS accumulating.x.animVal.value is 256
+PASS repeating.x.animVal.value is 0
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 96
+PASS sequential.x.animVal.value is 64
+PASS accumulating.x.animVal.value is 192
+PASS repeating.x.animVal.value is 128
+PASS nested.x.animVal.value is 0
+PASS plain.x.animVal.value is 128
+PASS sequential.x.animVal.value is 128
+PASS accumulating.x.animVal.value is 128
+PASS repeating.x.animVal.value is 128
+PASS nested.x.animVal.value is 0
+

Added: trunk/LayoutTests/svg/animations/animate-setcurrenttime.html (0 => 104719)


--- trunk/LayoutTests/svg/animations/animate-setcurrenttime.html	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-setcurrenttime.html	2012-01-11 17:54:43 UTC (rev 104719)
@@ -0,0 +1,120 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+  <script src=""
+</head>
+
+<body>
+  <h1>SVG 1.1 dynamic animation tests</h1>
+
+  <svg id='outer-svg' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve'>
+    <!-- sequential animations -->
+    <rect id='plain' x='0' y='0' width='32' height='32' fill='green'>
+      <animate id='plain-anim' attributeName='x' from='0' to='128' begin='0s' dur='4s' fill='freeze'/>
+    </rect>
+
+    <!-- sequential animations -->
+    <rect id='sequential' x='0' y='32' width='32' height='32' fill='green'>
+      <animate attributeName='x'  from='0'  to='32' begin='0s' dur='1s' fill='freeze'/>
+      <animate attributeName='x' from='64' to='128' begin='3s' dur='1s' fill='freeze'/>
+    </rect>
+
+    <!-- accumulating values -->
+    <rect id='accumulating' x='0' y='64' width='32' height='32' fill='green'>
+      <animate attributeName='x' values='0; 256; 128' additive='sum' accumulate='sum' begin='0s' dur='4s' fill='freeze'/>
+    </rect>
+
+    <!-- repeating -->
+    <rect id='repeating' x='0' y='96' width='32' height='32' fill='green'>
+      <animate attributeName='x' values='0; 256; 128; 0; 128' begin='0s' dur='2s' fill='freeze' repeatCount='2'/>
+    </rect>
+
+    <!-- nested -->
+    <svg id='nested-svg' x='0' y='128'>
+      <rect id='nested' x='0' y='0' width='32' height='32' fill='green'>
+        <animate attributeName='x' from='0' to='128' begin='0s' dur='4s' fill='freeze'/>
+      </rect>
+    </svg>
+
+    <script>
+    var svg = document.getElementById('outer-svg'),
+        nestedsvg = document.getElementById('nested-svg');
+    var tests, curIdx = 0;
+
+    var plain = document.getElementById('plain');
+    var sequential = document.getElementById('sequential');
+    var accumulating = document.getElementById('accumulating');
+    var repeating = document.getElementById('repeating');
+    var nested = document.getElementById('nested');
+
+    function runTest() {
+      var test = tests[curIdx++];
+
+      svg.setCurrentTime(test.time[0]);
+      nestedsvg.setCurrentTime(test.time[1]);
+
+      setTimeout(function() {
+        for (var attr in test.values) {
+          shouldBe(attr + '.animVal.value', String(test.values[attr]));
+        }
+
+        if (curIdx == tests.length) {
+          if (window.layoutTestController)
+            layoutTestController.notifyDone();
+        }
+        else
+          runTest();
+      }, 0);
+    }
+
+    function executeTests() {
+      nestedsvg.pauseAnimations();
+      svg.pauseAnimations();
+
+      tests = [
+        // Test invalid values.
+        { time: ['tintin', NaN], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':   0 } },
+
+        // Test out-of-range values.
+        { time: [-1, -1], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':   0 } },
+        { time: [ 5,  5], values: { 'plain.x': 128, 'sequential.x': 128, 'accumulating.x': 128, 'repeating.x': 128, 'nested.x': 128 } },
+
+        // Test changing time only for all elements.
+        { time: [0, 0], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':   0 } },
+        { time: [1, 1], values: { 'plain.x':  32, 'sequential.x':  32, 'accumulating.x': 128, 'repeating.x': 128, 'nested.x':  32 } },
+        { time: [2, 2], values: { 'plain.x':  64, 'sequential.x':  32, 'accumulating.x': 256, 'repeating.x':   0, 'nested.x':  64 } },
+        { time: [3, 3], values: { 'plain.x':  96, 'sequential.x':  64, 'accumulating.x': 192, 'repeating.x': 128, 'nested.x':  96 } },
+        { time: [4, 4], values: { 'plain.x': 128, 'sequential.x': 128, 'accumulating.x': 128, 'repeating.x': 128, 'nested.x': 128 } },
+
+        // Test changing time only for the nested svg element.
+        { time: [0, 0], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':   0 } },
+        { time: [0, 1], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':  32 } },
+        { time: [0, 2], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':  64 } },
+        { time: [0, 3], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':  96 } },
+        { time: [0, 4], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x': 128 } },
+
+        // Test changing time only for the outer svg element.
+        { time: [0, 0], values: { 'plain.x':   0, 'sequential.x':   0, 'accumulating.x':   0, 'repeating.x':   0, 'nested.x':   0 } },
+        { time: [1, 0], values: { 'plain.x':  32, 'sequential.x':  32, 'accumulating.x': 128, 'repeating.x': 128, 'nested.x':   0 } },
+        { time: [2, 0], values: { 'plain.x':  64, 'sequential.x':  32, 'accumulating.x': 256, 'repeating.x':   0, 'nested.x':   0 } },
+        { time: [3, 0], values: { 'plain.x':  96, 'sequential.x':  64, 'accumulating.x': 192, 'repeating.x': 128, 'nested.x':   0 } },
+        { time: [4, 0], values: { 'plain.x': 128, 'sequential.x': 128, 'accumulating.x': 128, 'repeating.x': 128, 'nested.x':   0 } },
+      ];
+
+      runTest();
+    }
+
+    // Begin test async
+    if (window.layoutTestController) {
+      layoutTestController.dumpAsText()
+      layoutTestController.waitUntilDone()
+    }
+    executeTests();
+    </script>
+  </svg>
+
+  <p id="description"></p>
+  <div id="console"></div>
+</body>
+</html>
+

Modified: trunk/Source/WebCore/ChangeLog (104718 => 104719)


--- trunk/Source/WebCore/ChangeLog	2012-01-11 17:49:43 UTC (rev 104718)
+++ trunk/Source/WebCore/ChangeLog	2012-01-11 17:54:43 UTC (rev 104719)
@@ -1,3 +1,29 @@
+2012-01-11  Joel Webber  <[email protected]>
+
+        Implement setCurrentTime() and pauseAnimations() on SVGSVGElement
+        https://bugs.webkit.org/show_bug.cgi?id=12073
+
+        Reviewed by Nikolas Zimmermann.
+
+        Adds the ability to reset an SVGSMILElement internally. SVGSMILElements are no longer removed
+        from their containers when they become inactive, because they sometimes have to be reactivated
+        when the container's current time is changed.
+
+        Test: svg/animations/animate-setcurrenttime.html
+
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::setCurrentTime):
+        * svg/animation/SMILTimeContainer.cpp:
+        (WebCore::SMILTimeContainer::SMILTimeContainer):
+        (WebCore::SMILTimeContainer::begin):
+        (WebCore::SMILTimeContainer::pause):
+        (WebCore::SMILTimeContainer::setElapsed):
+        (WebCore::SMILTimeContainer::updateAnimations):
+        * svg/animation/SMILTimeContainer.h:
+        * svg/animation/SVGSMILElement.cpp:
+        (WebCore::SVGSMILElement::reset):
+        * svg/animation/SVGSMILElement.h:
+
 2012-01-11  Peter Rybin  <[email protected]>
 
         Web Inspector: CodeGeneratorInspector.py: fix codestyle of generated enums

Modified: trunk/Source/WebCore/svg/SVGSVGElement.cpp (104718 => 104719)


--- trunk/Source/WebCore/svg/SVGSVGElement.cpp	2012-01-11 17:49:43 UTC (rev 104718)
+++ trunk/Source/WebCore/svg/SVGSVGElement.cpp	2012-01-11 17:54:43 UTC (rev 104719)
@@ -524,9 +524,12 @@
     return narrowPrecisionToFloat(m_timeContainer->elapsed().value());
 }
 
-void SVGSVGElement::setCurrentTime(float /* seconds */)
+void SVGSVGElement::setCurrentTime(float seconds)
 {
-    // FIXME: Implement me, bug 12073
+    if (isnan(seconds))
+        return;
+    seconds = max(seconds, 0.0f);
+    m_timeContainer->setElapsed(seconds);
 }
 
 bool SVGSVGElement::selfHasRelativeLengths() const

Modified: trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp (104718 => 104719)


--- trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp	2012-01-11 17:49:43 UTC (rev 104718)
+++ trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp	2012-01-11 17:54:43 UTC (rev 104719)
@@ -46,6 +46,7 @@
     : m_beginTime(0)
     , m_pauseTime(0)
     , m_accumulatedPauseTime(0)
+    , m_presetStartTime(0)
     , m_documentOrderIndexesDirty(false)
     , m_timer(this, &SMILTimeContainer::timerFired)
     , m_ownerSVGElement(owner)
@@ -89,17 +90,25 @@
 void SMILTimeContainer::begin()
 {
     ASSERT(!m_beginTime);
-    m_beginTime = currentTime();
-    updateAnimations(0);
+    double now = currentTime();
+
+    m_beginTime = now - m_presetStartTime;
+    updateAnimations(SMILTime(m_presetStartTime));
+    m_presetStartTime = 0;
+
+    if (m_pauseTime) {
+        m_pauseTime = now;
+        m_timer.stop();
+    }
 }
 
 void SMILTimeContainer::pause()
 {
-    if (!m_beginTime)
-        return;
     ASSERT(!isPaused());
     m_pauseTime = currentTime();
-    m_timer.stop();
+
+    if (m_beginTime)
+        m_timer.stop();
 }
 
 void SMILTimeContainer::resume()
@@ -112,6 +121,26 @@
     startTimer(0);
 }
 
+void SMILTimeContainer::setElapsed(SMILTime time)
+{
+    if (!m_beginTime) {
+        m_presetStartTime = time.value();
+        return;
+    }
+
+    double now = currentTime();
+    m_beginTime = now - time.value();
+    m_accumulatedPauseTime = 0;
+
+    Vector<SVGSMILElement*> toReset;
+    copyToVector(m_scheduledAnimations, toReset);
+    for (unsigned n = 0; n < toReset.size(); ++n)
+        toReset[n]->reset();
+
+    if (isPaused())
+        updateAnimations(now - m_beginTime - m_accumulatedPauseTime);
+}
+
 void SMILTimeContainer::startTimer(SMILTime fireTime, SMILTime minimumDelay)
 {
     if (!m_beginTime || isPaused())
@@ -123,7 +152,7 @@
     SMILTime delay = max(fireTime - elapsed(), minimumDelay);
     m_timer.startOneShot(delay.value());
 }
-    
+
 void SMILTimeContainer::timerFired(Timer<SMILTimeContainer>*)
 {
     ASSERT(m_beginTime);
@@ -131,7 +160,7 @@
     SMILTime elapsed = this->elapsed();
     updateAnimations(elapsed);
 }
- 
+
 void SMILTimeContainer::updateDocumentOrderIndexes()
 {
     unsigned timingElementCount = 0;
@@ -277,11 +306,6 @@
         SMILTime nextFireTime = animation->nextProgressTime();
         if (nextFireTime.isFinite())
             earliersFireTime = min(nextFireTime, earliersFireTime);
-        else if (!animation->isContributing(elapsed)) {
-            m_scheduledAnimations.remove(animation);
-            if (m_scheduledAnimations.isEmpty())
-                m_savedBaseValues.clear();
-        }
     }
     
     Vector<SVGSMILElement*> animationsToApply;

Modified: trunk/Source/WebCore/svg/animation/SMILTimeContainer.h (104718 => 104719)


--- trunk/Source/WebCore/svg/animation/SMILTimeContainer.h	2012-01-11 17:49:43 UTC (rev 104718)
+++ trunk/Source/WebCore/svg/animation/SMILTimeContainer.h	2012-01-11 17:54:43 UTC (rev 104719)
@@ -59,7 +59,8 @@
     void begin();
     void pause();
     void resume();
-    
+    void setElapsed(SMILTime);
+
     void setDocumentOrderIndexesDirty() { m_documentOrderIndexesDirty = true; }
 
     // Move to a specific time. Only used for DRT testing purposes.
@@ -81,6 +82,7 @@
     double m_beginTime;
     double m_pauseTime;
     double m_accumulatedPauseTime;
+    double m_presetStartTime;
 
     bool m_documentOrderIndexesDirty;
     

Modified: trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp (104718 => 104719)


--- trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp	2012-01-11 17:49:43 UTC (rev 104718)
+++ trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp	2012-01-11 17:54:43 UTC (rev 104719)
@@ -134,6 +134,7 @@
     , m_cachedMin(invalidCachedTime)
     , m_cachedMax(invalidCachedTime)
 {
+    reset();
 }
 
 SVGSMILElement::~SVGSMILElement()
@@ -166,7 +167,21 @@
     
     return QualifiedName(nullAtom, localName, namespaceURI);
 }
-    
+
+void SVGSMILElement::reset()
+{
+    m_activeState = Inactive;
+    m_isWaitingForFirstInterval = true;
+    m_intervalBegin = SMILTime::unresolved();
+    m_intervalEnd = SMILTime::unresolved();
+    m_previousIntervalBegin = SMILTime::unresolved();
+    m_lastPercent = 0;
+    m_lastRepeat = 0;
+    m_nextProgressTime = 0;
+
+    resolveFirstInterval();
+}
+
 void SVGSMILElement::insertedIntoDocument()
 {
     SVGElement::insertedIntoDocument();

Modified: trunk/Source/WebCore/svg/animation/SVGSMILElement.h (104718 => 104719)


--- trunk/Source/WebCore/svg/animation/SVGSMILElement.h	2012-01-11 17:49:43 UTC (rev 104718)
+++ trunk/Source/WebCore/svg/animation/SVGSMILElement.h	2012-01-11 17:54:43 UTC (rev 104719)
@@ -92,6 +92,8 @@
     void progress(SMILTime elapsed, SVGSMILElement* resultsElement);
     SMILTime nextProgressTime() const;
 
+    void reset();
+
     static SMILTime parseClockValue(const String&);
     static SMILTime parseOffsetValue(const String&);
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to