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
- trunk/LayoutTests/ChangeLog
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/svg/SVGSVGElement.cpp
- trunk/Source/WebCore/svg/animation/SMILTimeContainer.cpp
- trunk/Source/WebCore/svg/animation/SMILTimeContainer.h
- trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp
- trunk/Source/WebCore/svg/animation/SVGSMILElement.h
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
