Enable animVal support for SVGTransformList
https://bugs.webkit.org/show_bug.cgi?id=80758
Reviewed by Antti Koivisto.
Source/WebCore:
Enable animVal support for SVGTransformList. SVGTransformLists are only animatable
via <animateTransform>, not via <animate> directly. Still we can handle it in the
same framework as all other types used for <animate>, as we also need proper animVal
support for <animateTransform>.
This patch removes the special <animateTransform> implementation, and lets
SVGAnimateTransformElement inherit from SVGAnimateElement, just like its done
for SVGAnimateColorElement & SVGSetElement.
All existing code (calculateFromAndToValues/FromAndByValues/etc..) are moved from
SVGAnimateTransform right into the SVGAnimatedTransformListAnimator.
This doesn't change <animateTransform> behavior, it just simplies the code
and enables animVal support for SVGTransformLists - all covered by existing tests.
* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
* svg/SVGAllInOne.cpp:
* svg/SVGAnimateElement.cpp:
(WebCore::SVGAnimateElement::SVGAnimateElement):
(WebCore::SVGAnimateElement::determineAnimatedPropertyType):
(WebCore::SVGAnimateElement::calculateAnimatedValue):
(WebCore::SVGAnimateElement::applyResultsToTarget):
* svg/SVGAnimateTransformElement.cpp:
(WebCore::SVGAnimateTransformElement::SVGAnimateTransformElement):
(WebCore::SVGAnimateTransformElement::hasValidAttributeType):
(WebCore::SVGAnimateTransformElement::parseAttribute):
* svg/SVGAnimateTransformElement.h:
(WebCore::SVGAnimateTransformElement::transformType):
(SVGAnimateTransformElement):
* svg/SVGAnimatedTransformList.cpp: Added.
(WebCore):
(WebCore::SVGAnimatedTransformListAnimator::SVGAnimatedTransformListAnimator):
(WebCore::SVGAnimatedTransformListAnimator::constructFromString):
(WebCore::SVGAnimatedTransformListAnimator::constructFromCopy):
(WebCore::SVGAnimatedTransformListAnimator::calculateFromAndToValues):
(WebCore::SVGAnimatedTransformListAnimator::calculateFromAndByValues):
(WebCore::SVGAnimatedTransformListAnimator::calculateAnimatedValue):
(WebCore::SVGAnimatedTransformListAnimator::calculateDistance):
* svg/SVGAnimatedTransformList.h:
(WebCore):
(SVGAnimatedTransformListAnimator):
(WebCore::SVGAnimatedTransformListAnimator::~SVGAnimatedTransformListAnimator):
* svg/SVGAnimatedType.cpp:
(WebCore::SVGAnimatedType::~SVGAnimatedType):
(WebCore::SVGAnimatedType::createTransformList):
(WebCore):
(WebCore::SVGAnimatedType::transformList):
(WebCore::SVGAnimatedType::valueAsString):
(WebCore::SVGAnimatedType::setValueAsString):
(WebCore::SVGAnimatedType::supportsAnimVal):
(WebCore::SVGAnimatedType::setVariantValue):
* svg/SVGAnimatedType.h:
(WebCore):
(SVGAnimatedType):
* svg/SVGAnimatorFactory.h:
(WebCore::SVGAnimatorFactory::create):
* svg/SVGGradientElement.cpp:
(WebCore::SVGGradientElement::parseAttribute):
* svg/SVGPatternElement.cpp:
(WebCore::SVGPatternElement::parseAttribute):
* svg/SVGStyledTransformableElement.cpp:
(WebCore::SVGStyledTransformableElement::parseAttribute):
* svg/SVGTextElement.cpp:
(WebCore::SVGTextElement::parseAttribute):
* svg/SVGTransform.cpp:
(WebCore::SVGTransform::transformTypePrefixForParsing):
(WebCore):
(WebCore::SVGTransform::valueAsString):
* svg/SVGTransform.h:
(SVGTransform):
* svg/SVGTransformList.cpp:
(WebCore::SVGTransformList::parse):
(WebCore):
* svg/SVGTransformList.h:
(SVGTransformList):
* svg/SVGTransformable.cpp:
(WebCore::SVGTransformable::parseTransformType):
* svg/SVGTransformable.h:
(WebCore):
* svg/SVGViewSpec.cpp:
(WebCore::SVGViewSpec::setTransform):
LayoutTests:
Rebaseline tests after enabling animVal support SVGAnimateTransformElement/SVGTransformList.
* svg/animations/animate-gradient-transform-expected.txt:
* svg/animations/animateTransform-pattern-transform-expected.txt:
* svg/animations/script-tests/animate-gradient-transform.js:
(sample1):
(sample2):
(sample3):
(executeTest):
* svg/animations/script-tests/animateTransform-pattern-transform.js:
(sample1):
(sample2):
(sample3):
(sample4):
(executeTest):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@110838 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index ddad5db..ce29142 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,26 @@
+2012-03-15 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Enable animVal support for SVGTransformList
+ https://bugs.webkit.org/show_bug.cgi?id=80758
+
+ Reviewed by Antti Koivisto.
+
+ Rebaseline tests after enabling animVal support SVGAnimateTransformElement/SVGTransformList.
+
+ * svg/animations/animate-gradient-transform-expected.txt:
+ * svg/animations/animateTransform-pattern-transform-expected.txt:
+ * svg/animations/script-tests/animate-gradient-transform.js:
+ (sample1):
+ (sample2):
+ (sample3):
+ (executeTest):
+ * svg/animations/script-tests/animateTransform-pattern-transform.js:
+ (sample1):
+ (sample2):
+ (sample3):
+ (sample4):
+ (executeTest):
+
2012-03-13 Nikolas Zimmermann <nzimmermann@rim.com>
Enable animVal support for SVGLengthList
diff --git a/LayoutTests/svg/animations/animate-gradient-transform-expected.txt b/LayoutTests/svg/animations/animate-gradient-transform-expected.txt
index eb62209..cd72814 100644
--- a/LayoutTests/svg/animations/animate-gradient-transform-expected.txt
+++ b/LayoutTests/svg/animations/animate-gradient-transform-expected.txt
@@ -5,12 +5,31 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS gradient.gradientTransform.baseVal.consolidate().matrix.e is 0
-PASS gradient.gradientTransform.animVal.consolidate().matrix.e threw exception Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7.
-PASS gradient.gradientTransform.baseVal.consolidate().matrix.e is 100
-PASS gradient.gradientTransform.animVal.consolidate().matrix.e threw exception Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7.
-PASS gradient.gradientTransform.baseVal.consolidate().matrix.e is 200
-PASS gradient.gradientTransform.animVal.consolidate().matrix.e threw exception Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7.
+PASS gradient.gradientTransform.animVal.consolidate() threw exception Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7.
+PASS gradient.gradientTransform.animVal.numberOfItems is 1
+PASS gradient.gradientTransform.animVal.getItem(0).matrix.e is 0
+PASS gradient.gradientTransform.animVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.baseVal.numberOfItems is 1
+PASS gradient.gradientTransform.baseVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.baseVal.getItem(0).matrix.e is 0
+PASS gradient.gradientTransform.animVal.numberOfItems is 1
+PASS gradient.gradientTransform.animVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.animVal.getItem(0).matrix.e is 100
+PASS gradient.gradientTransform.baseVal.numberOfItems is 1
+PASS gradient.gradientTransform.baseVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.baseVal.getItem(0).matrix.e is 0
+PASS gradient.gradientTransform.animVal.numberOfItems is 1
+PASS gradient.gradientTransform.animVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.animVal.getItem(0).matrix.e is 200
+PASS gradient.gradientTransform.baseVal.numberOfItems is 1
+PASS gradient.gradientTransform.baseVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.baseVal.getItem(0).matrix.e is 0
+PASS gradient.gradientTransform.animVal.numberOfItems is 1
+PASS gradient.gradientTransform.animVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.animVal.getItem(0).matrix.e is 200
+PASS gradient.gradientTransform.baseVal.numberOfItems is 1
+PASS gradient.gradientTransform.baseVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_TRANSLATE
+PASS gradient.gradientTransform.baseVal.getItem(0).matrix.e is 0
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/svg/animations/animateTransform-pattern-transform-expected.txt b/LayoutTests/svg/animations/animateTransform-pattern-transform-expected.txt
index fec4f0b..8094fac 100644
--- a/LayoutTests/svg/animations/animateTransform-pattern-transform-expected.txt
+++ b/LayoutTests/svg/animations/animateTransform-pattern-transform-expected.txt
@@ -5,14 +5,22 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+PASS pattern.patternTransform.animVal.numberOfItems is 0
+PASS pattern.patternTransform.baseVal.numberOfItems is 0
+PASS pattern.patternTransform.animVal.numberOfItems is 1
+PASS pattern.patternTransform.animVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_SCALE
PASS pattern.patternTransform.animVal.getItem(0).matrix.a is 1
-PASS pattern.patternTransform.baseVal.getItem(0).matrix.a is 1
+PASS pattern.patternTransform.baseVal.numberOfItems is 0
+PASS pattern.patternTransform.animVal.numberOfItems is 1
+PASS pattern.patternTransform.animVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_SCALE
PASS pattern.patternTransform.animVal.getItem(0).matrix.a is 1.5
-PASS pattern.patternTransform.baseVal.getItem(0).matrix.a is 1.5
+PASS pattern.patternTransform.baseVal.numberOfItems is 0
+PASS pattern.patternTransform.animVal.numberOfItems is 1
+PASS pattern.patternTransform.animVal.getItem(0).type is SVGTransform.SVG_TRANSFORM_SCALE
PASS pattern.patternTransform.animVal.getItem(0).matrix.a is 2
-PASS pattern.patternTransform.baseVal.getItem(0).matrix.a is 2
-PASS pattern.patternTransform.animVal.getItem(0).matrix.a is 1
-PASS pattern.patternTransform.baseVal.getItem(0).matrix.a is 1
+PASS pattern.patternTransform.baseVal.numberOfItems is 0
+PASS pattern.patternTransform.animVal.numberOfItems is 0
+PASS pattern.patternTransform.baseVal.numberOfItems is 0
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/svg/animations/script-tests/animate-gradient-transform.js b/LayoutTests/svg/animations/script-tests/animate-gradient-transform.js
index 8f93abf..b62146b 100644
--- a/LayoutTests/svg/animations/script-tests/animate-gradient-transform.js
+++ b/LayoutTests/svg/animations/script-tests/animate-gradient-transform.js
@@ -44,20 +44,36 @@
// Setup animation test
function sample1() {
// Check initial conditions
- shouldBeCloseEnough("gradient.gradientTransform.baseVal.consolidate().matrix.e", "0");
- shouldThrow("gradient.gradientTransform.animVal.consolidate().matrix.e");
+ shouldThrow("gradient.gradientTransform.animVal.consolidate()");
+ shouldBe("gradient.gradientTransform.animVal.numberOfItems", "1");
+ shouldBeCloseEnough("gradient.gradientTransform.animVal.getItem(0).matrix.e", "0");
+ shouldBe("gradient.gradientTransform.animVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_TRANSLATE");
+
+ shouldBe("gradient.gradientTransform.baseVal.numberOfItems", "1");
+ shouldBe("gradient.gradientTransform.baseVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_TRANSLATE");
+ shouldBe("gradient.gradientTransform.baseVal.getItem(0).matrix.e", "0");
}
function sample2() {
// Check half-time conditions
- shouldBeCloseEnough("gradient.gradientTransform.baseVal.consolidate().matrix.e", "100");
- shouldThrow("gradient.gradientTransform.animVal.consolidate().matrix.e");
+ shouldBe("gradient.gradientTransform.animVal.numberOfItems", "1");
+ shouldBe("gradient.gradientTransform.animVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_TRANSLATE");
+ shouldBeCloseEnough("gradient.gradientTransform.animVal.getItem(0).matrix.e", "100");
+
+ shouldBe("gradient.gradientTransform.baseVal.numberOfItems", "1");
+ shouldBe("gradient.gradientTransform.baseVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_TRANSLATE");
+ shouldBe("gradient.gradientTransform.baseVal.getItem(0).matrix.e", "0");
}
function sample3() {
// Check end conditions
- shouldBeCloseEnough("gradient.gradientTransform.baseVal.consolidate().matrix.e", "200");
- shouldThrow("gradient.gradientTransform.animVal.consolidate().matrix.e");
+ shouldBe("gradient.gradientTransform.animVal.numberOfItems", "1");
+ shouldBe("gradient.gradientTransform.animVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_TRANSLATE");
+ shouldBeCloseEnough("gradient.gradientTransform.animVal.getItem(0).matrix.e", "200");
+
+ shouldBe("gradient.gradientTransform.baseVal.numberOfItems", "1");
+ shouldBe("gradient.gradientTransform.baseVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_TRANSLATE");
+ shouldBe("gradient.gradientTransform.baseVal.getItem(0).matrix.e", "0");
}
function executeTest() {
@@ -65,7 +81,8 @@
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 2.0, sample2],
- ["animation", 4.0, sample3]
+ ["animation", 3.999, sample3],
+ ["animation", 4.001, sample3]
];
runAnimationTest(expectedValues);
diff --git a/LayoutTests/svg/animations/script-tests/animateTransform-pattern-transform.js b/LayoutTests/svg/animations/script-tests/animateTransform-pattern-transform.js
index cf71f7a..3c2ce4d 100644
--- a/LayoutTests/svg/animations/script-tests/animateTransform-pattern-transform.js
+++ b/LayoutTests/svg/animations/script-tests/animateTransform-pattern-transform.js
@@ -41,28 +41,44 @@
// Setup animation test
function sample1() {
// Check initial/end conditions
- shouldBeCloseEnough("pattern.patternTransform.animVal.getItem(0).matrix.a", "1");
- shouldBeCloseEnough("pattern.patternTransform.baseVal.getItem(0).matrix.a", "1");
+ shouldBe("pattern.patternTransform.animVal.numberOfItems", "0");
+ shouldBe("pattern.patternTransform.baseVal.numberOfItems", "0");
}
function sample2() {
- // Check half-time conditions
- shouldBeCloseEnough("pattern.patternTransform.animVal.getItem(0).matrix.a", "1.5");
- shouldBeCloseEnough("pattern.patternTransform.baseVal.getItem(0).matrix.a", "1.5");
+ shouldBe("pattern.patternTransform.animVal.numberOfItems", "1");
+ shouldBe("pattern.patternTransform.animVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_SCALE");
+ shouldBeCloseEnough("pattern.patternTransform.animVal.getItem(0).matrix.a", "1");
+
+ shouldBe("pattern.patternTransform.baseVal.numberOfItems", "0");
}
function sample3() {
+ // Check half-time conditions
+ shouldBe("pattern.patternTransform.animVal.numberOfItems", "1");
+ shouldBe("pattern.patternTransform.animVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_SCALE");
+ shouldBeCloseEnough("pattern.patternTransform.animVal.getItem(0).matrix.a", "1.5");
+
+ shouldBe("pattern.patternTransform.baseVal.numberOfItems", "0");
+}
+
+function sample4() {
+ // Check half-time conditions
+ shouldBe("pattern.patternTransform.animVal.numberOfItems", "1");
+ shouldBe("pattern.patternTransform.animVal.getItem(0).type", "SVGTransform.SVG_TRANSFORM_SCALE");
shouldBeCloseEnough("pattern.patternTransform.animVal.getItem(0).matrix.a", "2");
- shouldBeCloseEnough("pattern.patternTransform.baseVal.getItem(0).matrix.a", "2");
+
+ shouldBe("pattern.patternTransform.baseVal.numberOfItems", "0");
}
function executeTest() {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
- ["animation", 2.0, sample2],
- ["animation", 3.999, sample3],
- ["animation", 4.001, sample1]
+ ["animation", 0.001, sample2],
+ ["animation", 2.0, sample3],
+ ["animation", 3.999, sample4],
+ ["animation", 4.0, sample1]
];
runAnimationTest(expectedValues);
diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt
index da4c9c9..42fa002 100644
--- a/Source/WebCore/CMakeLists.txt
+++ b/Source/WebCore/CMakeLists.txt
@@ -1770,6 +1770,7 @@
svg/SVGAnimatedPreserveAspectRatio.cpp
svg/SVGAnimatedRect.cpp
svg/SVGAnimatedString.cpp
+ svg/SVGAnimatedTransformList.cpp
svg/SVGAnimatedType.cpp
svg/SVGAnimateElement.cpp
svg/SVGAnimateMotionElement.cpp
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 37e9852..d2f9307 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,96 @@
+2012-03-15 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Enable animVal support for SVGTransformList
+ https://bugs.webkit.org/show_bug.cgi?id=80758
+
+ Reviewed by Antti Koivisto.
+
+ Enable animVal support for SVGTransformList. SVGTransformLists are only animatable
+ via <animateTransform>, not via <animate> directly. Still we can handle it in the
+ same framework as all other types used for <animate>, as we also need proper animVal
+ support for <animateTransform>.
+
+ This patch removes the special <animateTransform> implementation, and lets
+ SVGAnimateTransformElement inherit from SVGAnimateElement, just like its done
+ for SVGAnimateColorElement & SVGSetElement.
+
+ All existing code (calculateFromAndToValues/FromAndByValues/etc..) are moved from
+ SVGAnimateTransform right into the SVGAnimatedTransformListAnimator.
+
+ This doesn't change <animateTransform> behavior, it just simplies the code
+ and enables animVal support for SVGTransformLists - all covered by existing tests.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * Target.pri:
+ * WebCore.gypi:
+ * WebCore.xcodeproj/project.pbxproj:
+ * svg/SVGAllInOne.cpp:
+ * svg/SVGAnimateElement.cpp:
+ (WebCore::SVGAnimateElement::SVGAnimateElement):
+ (WebCore::SVGAnimateElement::determineAnimatedPropertyType):
+ (WebCore::SVGAnimateElement::calculateAnimatedValue):
+ (WebCore::SVGAnimateElement::applyResultsToTarget):
+ * svg/SVGAnimateTransformElement.cpp:
+ (WebCore::SVGAnimateTransformElement::SVGAnimateTransformElement):
+ (WebCore::SVGAnimateTransformElement::hasValidAttributeType):
+ (WebCore::SVGAnimateTransformElement::parseAttribute):
+ * svg/SVGAnimateTransformElement.h:
+ (WebCore::SVGAnimateTransformElement::transformType):
+ (SVGAnimateTransformElement):
+ * svg/SVGAnimatedTransformList.cpp: Added.
+ (WebCore):
+ (WebCore::SVGAnimatedTransformListAnimator::SVGAnimatedTransformListAnimator):
+ (WebCore::SVGAnimatedTransformListAnimator::constructFromString):
+ (WebCore::SVGAnimatedTransformListAnimator::constructFromCopy):
+ (WebCore::SVGAnimatedTransformListAnimator::calculateFromAndToValues):
+ (WebCore::SVGAnimatedTransformListAnimator::calculateFromAndByValues):
+ (WebCore::SVGAnimatedTransformListAnimator::calculateAnimatedValue):
+ (WebCore::SVGAnimatedTransformListAnimator::calculateDistance):
+ * svg/SVGAnimatedTransformList.h:
+ (WebCore):
+ (SVGAnimatedTransformListAnimator):
+ (WebCore::SVGAnimatedTransformListAnimator::~SVGAnimatedTransformListAnimator):
+ * svg/SVGAnimatedType.cpp:
+ (WebCore::SVGAnimatedType::~SVGAnimatedType):
+ (WebCore::SVGAnimatedType::createTransformList):
+ (WebCore):
+ (WebCore::SVGAnimatedType::transformList):
+ (WebCore::SVGAnimatedType::valueAsString):
+ (WebCore::SVGAnimatedType::setValueAsString):
+ (WebCore::SVGAnimatedType::supportsAnimVal):
+ (WebCore::SVGAnimatedType::setVariantValue):
+ * svg/SVGAnimatedType.h:
+ (WebCore):
+ (SVGAnimatedType):
+ * svg/SVGAnimatorFactory.h:
+ (WebCore::SVGAnimatorFactory::create):
+ * svg/SVGGradientElement.cpp:
+ (WebCore::SVGGradientElement::parseAttribute):
+ * svg/SVGPatternElement.cpp:
+ (WebCore::SVGPatternElement::parseAttribute):
+ * svg/SVGStyledTransformableElement.cpp:
+ (WebCore::SVGStyledTransformableElement::parseAttribute):
+ * svg/SVGTextElement.cpp:
+ (WebCore::SVGTextElement::parseAttribute):
+ * svg/SVGTransform.cpp:
+ (WebCore::SVGTransform::transformTypePrefixForParsing):
+ (WebCore):
+ (WebCore::SVGTransform::valueAsString):
+ * svg/SVGTransform.h:
+ (SVGTransform):
+ * svg/SVGTransformList.cpp:
+ (WebCore::SVGTransformList::parse):
+ (WebCore):
+ * svg/SVGTransformList.h:
+ (SVGTransformList):
+ * svg/SVGTransformable.cpp:
+ (WebCore::SVGTransformable::parseTransformType):
+ * svg/SVGTransformable.h:
+ (WebCore):
+ * svg/SVGViewSpec.cpp:
+ (WebCore::SVGViewSpec::setTransform):
+
2012-03-13 Nikolas Zimmermann <nzimmermann@rim.com>
Enable animVal support for SVGLengthList
diff --git a/Source/WebCore/GNUmakefile.list.am b/Source/WebCore/GNUmakefile.list.am
index 9b58c95..a87ae1c 100644
--- a/Source/WebCore/GNUmakefile.list.am
+++ b/Source/WebCore/GNUmakefile.list.am
@@ -4100,6 +4100,7 @@
Source/WebCore/svg/SVGAnimatedRect.h \
Source/WebCore/svg/SVGAnimatedString.cpp \
Source/WebCore/svg/SVGAnimatedString.h \
+ Source/WebCore/svg/SVGAnimatedTransformList.cpp \
Source/WebCore/svg/SVGAnimatedTransformList.h \
Source/WebCore/svg/SVGAnimatedType.cpp \
Source/WebCore/svg/SVGAnimatedType.h \
diff --git a/Source/WebCore/Target.pri b/Source/WebCore/Target.pri
index ecfd647..063aa40 100644
--- a/Source/WebCore/Target.pri
+++ b/Source/WebCore/Target.pri
@@ -3501,6 +3501,7 @@
svg/SVGAnimatedPreserveAspectRatio.cpp \
svg/SVGAnimatedRect.cpp \
svg/SVGAnimatedString.cpp \
+ svg/SVGAnimatedTransformList.cpp \
svg/SVGAnimatedType.cpp \
svg/SVGAnimateElement.cpp \
svg/SVGAnimateMotionElement.cpp \
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index 75f0c8f..851b8b5 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -5813,6 +5813,7 @@
'svg/SVGAnimatedPreserveAspectRatio.cpp',
'svg/SVGAnimatedRect.cpp',
'svg/SVGAnimatedString.cpp',
+ 'svg/SVGAnimatedTransformList.cpp',
'svg/SVGAnimatedType.cpp',
'svg/SVGAnimateElement.cpp',
'svg/SVGAnimateElement.h',
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index d8e57db..51fbf42 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -1788,6 +1788,7 @@
7134496D146941B300720312 /* SVGLengthContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7134496B146941B300720312 /* SVGLengthContext.cpp */; };
7134496E146941B300720312 /* SVGLengthContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 7134496C146941B300720312 /* SVGLengthContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
71537A01146BD9D7008BD615 /* SVGPathData.h in Headers */ = {isa = PBXBuildFile; fileRef = 715379FF146BD9D6008BD615 /* SVGPathData.h */; };
+ 7157F062150B6564006EAABD /* SVGAnimatedTransformList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7157F061150B6564006EAABD /* SVGAnimatedTransformList.cpp */; };
71FB967B1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 71FB967A1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h */; settings = {ATTRIBUTES = (Private, ); }; };
72626E020EF022FE00A07E20 /* FontFastPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72626E010EF022FE00A07E20 /* FontFastPath.cpp */; };
750D029311D0E7F300BD1B27 /* RenderInputSpeech.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 750D029111D0E7F300BD1B27 /* RenderInputSpeech.cpp */; };
@@ -8739,6 +8740,7 @@
7134496C146941B300720312 /* SVGLengthContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGLengthContext.h; sourceTree = "<group>"; };
715379FE146BD9D6008BD615 /* SVGPathData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGPathData.cpp; sourceTree = "<group>"; };
715379FF146BD9D6008BD615 /* SVGPathData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathData.h; sourceTree = "<group>"; };
+ 7157F061150B6564006EAABD /* SVGAnimatedTransformList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedTransformList.cpp; sourceTree = "<group>"; };
71FB967A1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedEnumerationPropertyTearOff.h; sourceTree = "<group>"; };
72626E010EF022FE00A07E20 /* FontFastPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFastPath.cpp; sourceTree = "<group>"; };
750D029111D0E7F300BD1B27 /* RenderInputSpeech.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderInputSpeech.cpp; sourceTree = "<group>"; };
@@ -18589,6 +18591,7 @@
43A6266613B3D11000AC94B8 /* SVGAnimatedString.cpp */,
084DB59A128008CC002A6D64 /* SVGAnimatedString.h */,
B22277F60D00BF1F0071B782 /* SVGAnimatedString.idl */,
+ 7157F061150B6564006EAABD /* SVGAnimatedTransformList.cpp */,
08250938128BD4D800E2ED8E /* SVGAnimatedTransformList.h */,
B22277F80D00BF1F0071B782 /* SVGAnimatedTransformList.idl */,
43A0F0B513ACCCFF00A5F0A7 /* SVGAnimatedType.cpp */,
@@ -27556,6 +27559,7 @@
450CEBF015073BBE002BB149 /* LabelableElement.cpp in Sources */,
C5B4C24E1509236C00A6EF37 /* WebCoreNSURLExtras.mm in Sources */,
9B2B7AC11509850A008932CC /* MicroDataItemValue.cpp in Sources */,
+ 7157F062150B6564006EAABD /* SVGAnimatedTransformList.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/WebCore/svg/SVGAllInOne.cpp b/Source/WebCore/svg/SVGAllInOne.cpp
index e1a7417..4f09d5c 100644
--- a/Source/WebCore/svg/SVGAllInOne.cpp
+++ b/Source/WebCore/svg/SVGAllInOne.cpp
@@ -46,6 +46,7 @@
#include "SVGAnimatedPreserveAspectRatio.cpp"
#include "SVGAnimatedRect.cpp"
#include "SVGAnimatedString.cpp"
+#include "SVGAnimatedTransformList.cpp"
#include "SVGAnimatedType.cpp"
#include "SVGAnimateElement.cpp"
#include "SVGAnimateMotionElement.cpp"
diff --git a/Source/WebCore/svg/SVGAnimateElement.cpp b/Source/WebCore/svg/SVGAnimateElement.cpp
index 06e4c81..059ebc6 100644
--- a/Source/WebCore/svg/SVGAnimateElement.cpp
+++ b/Source/WebCore/svg/SVGAnimateElement.cpp
@@ -43,7 +43,7 @@
, m_toPropertyValueType(RegularPropertyValue)
, m_animatedProperty(0)
{
- ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateColorTag));
+ ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateColorTag) || hasTagName(SVGNames::animateTransformTag));
}
PassRefPtr<SVGAnimateElement> SVGAnimateElement::create(const QualifiedName& tagName, Document* document)
@@ -130,7 +130,7 @@
// Animations of transform lists are not allowed for <animate> or <set>
// http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
- if (type == AnimatedTransformList)
+ if (type == AnimatedTransformList && !hasTagName(SVGNames::animateTransformTag))
return AnimatedUnknown;
return type;
@@ -166,7 +166,7 @@
ASSERT(percentage >= 0 && percentage <= 1);
ASSERT(m_animatedPropertyType != AnimatedEnumeration);
- ASSERT(m_animatedPropertyType != AnimatedTransformList);
+ ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag));
ASSERT(m_animatedPropertyType != AnimatedUnknown);
ASSERT(m_animator);
ASSERT(m_animator->type() == m_animatedPropertyType);
@@ -176,6 +176,7 @@
ASSERT(resultElement->hasTagName(SVGNames::animateTag)
|| resultElement->hasTagName(SVGNames::animateColorTag)
+ || resultElement->hasTagName(SVGNames::animateTransformTag)
|| resultElement->hasTagName(SVGNames::setTag));
SVGAnimateElement* resultAnimationElement = static_cast<SVGAnimateElement*>(resultElement);
@@ -250,7 +251,7 @@
void SVGAnimateElement::applyResultsToTarget()
{
ASSERT(m_animatedPropertyType != AnimatedEnumeration);
- ASSERT(m_animatedPropertyType != AnimatedTransformList);
+ ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag));
ASSERT(m_animatedPropertyType != AnimatedUnknown);
ASSERT(m_animatedType);
setTargetAttributeAnimatedValue(m_animatedType.get());
diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.cpp b/Source/WebCore/svg/SVGAnimateTransformElement.cpp
index c1bb199..faacd4e 100644
--- a/Source/WebCore/svg/SVGAnimateTransformElement.cpp
+++ b/Source/WebCore/svg/SVGAnimateTransformElement.cpp
@@ -25,32 +25,15 @@
#if ENABLE(SVG)
#include "SVGAnimateTransformElement.h"
-#include "AffineTransform.h"
#include "Attribute.h"
-#include "RenderObject.h"
-#include "RenderSVGResource.h"
-#include "SVGAngle.h"
-#include "SVGElementInstance.h"
-#include "SVGGradientElement.h"
#include "SVGNames.h"
-#include "SVGParserUtilities.h"
-#include "SVGPatternElement.h"
-#include "SVGSVGElement.h"
-#include "SVGStyledTransformableElement.h"
-#include "SVGTextElement.h"
-#include "SVGTransform.h"
-#include "SVGTransformList.h"
-#include "SVGUseElement.h"
-#include <wtf/MathExtras.h>
-
-using namespace std;
+#include "SVGTransformable.h"
namespace WebCore {
inline SVGAnimateTransformElement::SVGAnimateTransformElement(const QualifiedName& tagName, Document* document)
- : SVGAnimationElement(tagName, document)
+ : SVGAnimateElement(tagName, document)
, m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
- , m_baseIndexInTransformList(0)
{
ASSERT(hasTagName(SVGNames::animateTransformTag));
}
@@ -62,26 +45,9 @@
bool SVGAnimateTransformElement::hasValidAttributeType()
{
- SVGElement* targetElement = this->targetElement();
- if (!targetElement)
- return false;
-
- return determineAnimatedPropertyType(targetElement) == AnimatedTransformList;
-}
-
-AnimatedPropertyType SVGAnimateTransformElement::determineAnimatedPropertyType(SVGElement* targetElement) const
-{
- ASSERT(targetElement);
-
- // Just transform lists can be animated with <animateTransform>
- // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
- Vector<AnimatedPropertyType> propertyTypes;
- targetElement->animatedPropertyTypeForAttribute(attributeName(), propertyTypes);
- if (propertyTypes.isEmpty() || propertyTypes[0] != AnimatedTransformList)
- return AnimatedUnknown;
-
- ASSERT(propertyTypes.size() == 1);
- return AnimatedTransformList;
+ if (SVGElement* targetElement = this->targetElement())
+ return determineAnimatedPropertyType(targetElement) == AnimatedTransformList;
+ return false;
}
bool SVGAnimateTransformElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -95,194 +61,18 @@
void SVGAnimateTransformElement::parseAttribute(Attribute* attr)
{
if (!isSupportedAttribute(attr->name())) {
- SVGAnimationElement::parseAttribute(attr);
+ SVGAnimateElement::parseAttribute(attr);
return;
}
if (attr->name() == SVGNames::typeAttr) {
- const AtomicString& value = attr->value();
- if (value == "translate")
- m_type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
- else if (value == "scale")
- m_type = SVGTransform::SVG_TRANSFORM_SCALE;
- else if (value == "rotate")
- m_type = SVGTransform::SVG_TRANSFORM_ROTATE;
- else if (value == "skewX")
- m_type = SVGTransform::SVG_TRANSFORM_SKEWX;
- else if (value == "skewY")
- m_type = SVGTransform::SVG_TRANSFORM_SKEWY;
+ m_type = SVGTransformable::parseTransformType(attr->value());
return;
}
ASSERT_NOT_REACHED();
}
-static PassRefPtr<SVGAnimatedTransformList> animatedTransformListFor(SVGElement* element)
-{
- ASSERT(element);
- if (element->isStyledTransformable())
- return static_cast<SVGStyledTransformableElement*>(element)->transformAnimated();
- if (element->hasTagName(SVGNames::textTag))
- return static_cast<SVGTextElement*>(element)->transformAnimated();
- if (element->hasTagName(SVGNames::linearGradientTag) || element->hasTagName(SVGNames::radialGradientTag))
- return static_cast<SVGGradientElement*>(element)->gradientTransformAnimated();
- if (element->hasTagName(SVGNames::patternTag))
- return static_cast<SVGPatternElement*>(element)->patternTransformAnimated();
- return 0;
-}
-
-void SVGAnimateTransformElement::resetToBaseValue(const String& baseValue)
-{
- // FIXME: Once we added SVGAnimatedTransformListAnimator, this whole class is unncessary.
- // See bug https://bugs.webkit.org/show_bug.cgi?id=80758. Once this is fixed animVal support
- // for <animateTransform> is finished, and this class is almost empty.
- SVGElement* targetElement = this->targetElement();
- if (!targetElement || determineAnimatedPropertyType(targetElement) == AnimatedUnknown)
- return;
-
- // FIXME: This might not be correct for accumulated sum. Needs checking.
- if (targetElement->hasTagName(SVGNames::linearGradientTag) || targetElement->hasTagName(SVGNames::radialGradientTag)) {
- targetElement->setAttribute(SVGNames::gradientTransformAttr, baseValue.isEmpty() ? "matrix(1 0 0 1 0 0)" : baseValue);
- return;
- }
- if (targetElement->hasTagName(SVGNames::patternTag)) {
- targetElement->setAttribute(SVGNames::patternTransformAttr, baseValue.isEmpty() ? "matrix(1 0 0 1 0 0)" : baseValue);
- return;
- }
-
- if (baseValue.isEmpty()) {
- if (RefPtr<SVGAnimatedTransformList> list = animatedTransformListFor(targetElement)) {
- SVGListProperty<SVGTransformList>* baseVal = static_cast<SVGListProperty<SVGTransformList>*>(list->baseVal());
- baseVal->detachListWrappers(0);
- baseVal->values().clear();
- }
- } else
- targetElement->setAttribute(SVGNames::transformAttr, baseValue);
}
-void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement*)
-{
- // FIXME: Once we added SVGAnimatedTransformListAnimator, this whole class is unncessary.
- // See bug https://bugs.webkit.org/show_bug.cgi?id=80758. Once this is fixed animVal support
- // for <animateTransform> is finished, and this class is almost empty.
- SVGElement* targetElement = this->targetElement();
- if (!targetElement || determineAnimatedPropertyType(targetElement) == AnimatedUnknown)
- return;
- RefPtr<SVGAnimatedTransformList> animatedList = animatedTransformListFor(targetElement);
- ASSERT(animatedList);
- SVGListProperty<SVGTransformList>* baseVal = static_cast<SVGListProperty<SVGTransformList>*>(animatedList->baseVal());
- ASSERT(baseVal);
-
- if (calcMode() == CalcModeDiscrete)
- percentage = percentage < 0.5 ? 0 : 1;
-
- if (!isAdditive()) {
- baseVal->detachListWrappers(0);
- baseVal->values().clear();
- }
- if (isAccumulated() && repeat)
- percentage += repeat;
- SVGTransform transform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentage).addToSVGTransform(m_fromTransform);
- baseVal->values().append(transform);
- baseVal->wrappers().append(RefPtr<SVGPropertyTearOff<SVGTransform> >());
-}
-
-bool SVGAnimateTransformElement::calculateFromAndToValues(const String& fromString, const String& toString)
-{
- m_fromTransform = parseTransformValue(fromString);
- if (!m_fromTransform.isValid())
- return false;
- m_toTransform = parseTransformValue(toString);
- return m_toTransform.isValid();
-}
-
-bool SVGAnimateTransformElement::calculateFromAndByValues(const String& fromString, const String& byString)
-{
- m_fromTransform = parseTransformValue(fromString);
- if (!m_fromTransform.isValid())
- return false;
- m_toTransform = SVGTransformDistance::addSVGTransforms(m_fromTransform, parseTransformValue(byString));
- return m_toTransform.isValid();
-}
-
-SVGTransform SVGAnimateTransformElement::parseTransformValue(const String& value) const
-{
- if (value.isEmpty())
- return SVGTransform(m_type);
- SVGTransform result;
- // FIXME: This is pretty dumb but parseTransformValue() wants those parenthesis.
- String parseString("(" + value + ")");
- const UChar* ptr = parseString.characters();
- SVGTransformable::parseTransformValue(m_type, ptr, ptr + parseString.length(), result); // ignoring return value
- return result;
-}
-
-void SVGAnimateTransformElement::applyResultsToTarget()
-{
- SVGElement* targetElement = this->targetElement();
- if (!targetElement || determineAnimatedPropertyType(targetElement) == AnimatedUnknown)
- return;
-
- // We accumulate to the target element transform list so there is not much to do here.
- if (RenderObject* renderer = targetElement->renderer()) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- }
-
- // ...except in case where we have additional instances in <use> trees.
- RefPtr<SVGAnimatedTransformList> animatedList = animatedTransformListFor(targetElement);
- if (!animatedList)
- return;
-
- // FIXME: Once we added SVGAnimatedTransformListAnimator, this whole class is unncessary.
- // See bug https://bugs.webkit.org/show_bug.cgi?id=80758. Once this is fixed animVal support
- // for <animateTransform> is finished, and this class is almost empty.
- SVGListProperty<SVGTransformList>* baseVal = static_cast<SVGListProperty<SVGTransformList>*>(animatedList->baseVal());
- ASSERT(baseVal);
- SVGTransformList& transformList = baseVal->values();
-
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
- ASSERT(shadowTreeElement);
- if (shadowTreeElement->isStyledTransformable())
- static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransformBaseValue(transformList);
- else if (shadowTreeElement->hasTagName(SVGNames::textTag))
- static_cast<SVGTextElement*>(shadowTreeElement)->setTransformBaseValue(transformList);
- else if (shadowTreeElement->hasTagName(SVGNames::linearGradientTag) || shadowTreeElement->hasTagName(SVGNames::radialGradientTag))
- static_cast<SVGGradientElement*>(shadowTreeElement)->setGradientTransformBaseValue(transformList);
- else if (shadowTreeElement->hasTagName(SVGNames::patternTag))
- static_cast<SVGPatternElement*>(shadowTreeElement)->setPatternTransformBaseValue(transformList);
- if (RenderObject* renderer = shadowTreeElement->renderer()) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- }
- }
-}
-
-float SVGAnimateTransformElement::calculateDistance(const String& fromString, const String& toString)
-{
- // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example)
- // is paced separately. To implement this we need to treat each component as individual animation everywhere.
- SVGTransform from = parseTransformValue(fromString);
- if (!from.isValid())
- return -1;
- SVGTransform to = parseTransformValue(toString);
- if (!to.isValid() || from.type() != to.type())
- return -1;
- if (to.type() == SVGTransform::SVG_TRANSFORM_TRANSLATE) {
- FloatSize diff = to.translate() - from.translate();
- return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
- }
- if (to.type() == SVGTransform::SVG_TRANSFORM_ROTATE)
- return fabsf(to.angle() - from.angle());
- if (to.type() == SVGTransform::SVG_TRANSFORM_SCALE) {
- FloatSize diff = to.scale() - from.scale();
- return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
- }
- return -1;
-}
-
-}
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.h b/Source/WebCore/svg/SVGAnimateTransformElement.h
index a3d7f79..d308e0b 100644
--- a/Source/WebCore/svg/SVGAnimateTransformElement.h
+++ b/Source/WebCore/svg/SVGAnimateTransformElement.h
@@ -22,44 +22,30 @@
#ifndef SVGAnimateTransformElement_h
#define SVGAnimateTransformElement_h
-#if ENABLE(SVG)
-#include "SVGAnimationElement.h"
+#if ENABLE(SVG)
+#include "SVGAnimateElement.h"
#include "SVGTransform.h"
-#include "SVGTransformDistance.h"
namespace WebCore {
class AffineTransform;
-class SVGAnimateTransformElement : public SVGAnimationElement {
+class SVGAnimateTransformElement : public SVGAnimateElement {
public:
static PassRefPtr<SVGAnimateTransformElement> create(const QualifiedName&, Document*);
+ SVGTransform::SVGTransformType transformType() const { return m_type; }
+
private:
SVGAnimateTransformElement(const QualifiedName&, Document*);
virtual bool hasValidAttributeType();
- AnimatedPropertyType determineAnimatedPropertyType(SVGElement*) const;
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(Attribute*) OVERRIDE;
- virtual void resetToBaseValue(const String&);
- virtual bool calculateFromAndToValues(const String& fromString, const String& toString);
- virtual bool calculateFromAndByValues(const String& fromString, const String& byString);
- virtual void calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement);
- virtual void applyResultsToTarget();
- virtual float calculateDistance(const String& fromString, const String& toString);
-
- SVGTransform parseTransformValue(const String&) const;
-
SVGTransform::SVGTransformType m_type;
-
- unsigned m_baseIndexInTransformList;
-
- SVGTransform m_toTransform;
- SVGTransform m_fromTransform;
};
} // namespace WebCore
diff --git a/Source/WebCore/svg/SVGAnimatedTransformList.cpp b/Source/WebCore/svg/SVGAnimatedTransformList.cpp
new file mode 100644
index 0000000..6e3ed94
--- /dev/null
+++ b/Source/WebCore/svg/SVGAnimatedTransformList.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) Research In Motion Limited 2012. 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)
+#include "SVGAnimatedTransformList.h"
+
+#include "SVGAnimateTransformElement.h"
+#include "SVGAnimatedNumber.h"
+#include "SVGNames.h"
+#include "SVGTransformDistance.h"
+
+namespace WebCore {
+
+SVGAnimatedTransformListAnimator::SVGAnimatedTransformListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
+ : SVGAnimatedTypeAnimator(AnimatedTransformList, animationElement, contextElement)
+{
+ // Only <animateTransform> uses this animator, as <animate> doesn't allow to animate transform lists directly.
+ ASSERT(animationElement->hasTagName(SVGNames::animateTransformTag));
+}
+
+PassOwnPtr<SVGAnimatedType> SVGAnimatedTransformListAnimator::constructFromString(const String& string)
+{
+ OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createTransformList(new SVGTransformList);
+ animatedType->transformList().parse(string);
+ ASSERT(animatedType->transformList().size() <= 1);
+ return animatedType.release();
+}
+
+PassOwnPtr<SVGAnimatedType> SVGAnimatedTransformListAnimator::constructFromCopy(SVGGenericAnimatedType* animatedType)
+{
+ ASSERT(animatedType);
+ return SVGAnimatedType::createTransformList(new SVGTransformList(*reinterpret_cast<SVGTransformList*>(animatedType)));
+}
+
+inline PassOwnPtr<SVGAnimatedType> SVGAnimatedTransformListAnimator::constructFromString(SVGAnimateTransformElement* animateTransformElement, const String& string)
+{
+ ASSERT(animateTransformElement);
+ return SVGAnimatedTransformListAnimator::constructFromString(SVGTransform::transformTypePrefixForParsing(animateTransformElement->transformType()) + string + ')');
+}
+
+void SVGAnimatedTransformListAnimator::calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString)
+{
+ ASSERT(m_animationElement);
+ SVGAnimateTransformElement* animateTransformElement = static_cast<SVGAnimateTransformElement*>(m_animationElement);
+
+ from = constructFromString(animateTransformElement, fromString);
+ to = constructFromString(animateTransformElement, toString);
+}
+
+void SVGAnimatedTransformListAnimator::calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString)
+{
+ ASSERT(m_animationElement);
+ SVGAnimateTransformElement* animateTransformElement = static_cast<SVGAnimateTransformElement*>(m_animationElement);
+
+ from = constructFromString(animateTransformElement, fromString);
+ to = constructFromString(animateTransformElement, byString);
+
+ SVGTransformList& fromTransformList = from->transformList();
+ SVGTransformList& toTransformList = to->transformList();
+ unsigned itemsCount = fromTransformList.size();
+ if (!itemsCount || itemsCount != toTransformList.size())
+ return;
+
+ ASSERT(itemsCount == 1);
+ toTransformList[0] = SVGTransformDistance::addSVGTransforms(fromTransformList[0], toTransformList[0]);
+}
+
+void SVGAnimatedTransformListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
+ OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+{
+ ASSERT(m_animationElement);
+
+ // Spec: To animations provide specific functionality to get a smooth change from the underlying value to the
+ // ‘to’ attribute value, which conflicts mathematically with the requirement for additive transform animations
+ // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations for ‘animateTransform’ is undefined.
+ // FIXME: This is not taken into account yet.
+ SVGTransformList& fromTransformList = from->transformList();
+ SVGTransformList& toTransformList = to->transformList();
+ ASSERT(fromTransformList.size() <= 1);
+ ASSERT(toTransformList.size() <= 1);
+ ASSERT(fromTransformList[0].type() == toTransformList[0].type());
+
+ SVGTransform fromTransform;
+ SVGTransform toTransform;
+ if (!toTransformList.isEmpty() && !fromTransformList.isEmpty()) {
+ fromTransform = fromTransformList[0];
+ toTransform = toTransformList[0];
+ ASSERT(fromTransform.type() == toTransform.type());
+ }
+
+ if (m_animationElement->calcMode() == CalcModeDiscrete)
+ percentage = percentage < 0.5 ? 0 : 1;
+
+ if (m_animationElement->isAccumulated() && repeatCount)
+ percentage += repeatCount;
+
+ SVGTransformList& animatedTransformList = animated->transformList();
+ if (!m_animationElement->isAdditive())
+ animatedTransformList.clear();
+
+ animatedTransformList.append(SVGTransformDistance(fromTransform, toTransform).scaledDistance(percentage).addToSVGTransform(fromTransform));
+}
+
+float SVGAnimatedTransformListAnimator::calculateDistance(const String& fromString, const String& toString)
+{
+ ASSERT(m_animationElement);
+ SVGAnimateTransformElement* animateTransformElement = static_cast<SVGAnimateTransformElement*>(m_animationElement);
+
+ // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example)
+ // is paced separately. To implement this we need to treat each component as individual animation everywhere.
+ OwnPtr<SVGAnimatedType> from = constructFromString(animateTransformElement, fromString);
+ OwnPtr<SVGAnimatedType> to = constructFromString(animateTransformElement, toString);
+
+ SVGTransformList& fromTransformList = from->transformList();
+ SVGTransformList& toTransformList = to->transformList();
+ unsigned itemsCount = fromTransformList.size();
+ if (!itemsCount || itemsCount != toTransformList.size())
+ return -1;
+
+ ASSERT(itemsCount == 1);
+ if (fromTransformList[0].type() != toTransformList[0].type())
+ return -1;
+
+ // Spec: http://www.w3.org/TR/SVG/animate.html#complexDistances
+ // Paced animations assume a notion of distance between the various animation values defined by the ‘to’, ‘from’, ‘by’ and ‘values’ attributes.
+ // Distance is defined only for scalar types (such as <length>), colors and the subset of transformation types that are supported by ‘animateTransform’.
+ return SVGTransformDistance(fromTransformList[0], toTransformList[0]).distance();
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/svg/SVGAnimatedTransformList.h b/Source/WebCore/svg/SVGAnimatedTransformList.h
index bf8038e..895a32f 100644
--- a/Source/WebCore/svg/SVGAnimatedTransformList.h
+++ b/Source/WebCore/svg/SVGAnimatedTransformList.h
@@ -22,6 +22,7 @@
#if ENABLE(SVG)
#include "SVGAnimatedTransformListPropertyTearOff.h"
+#include "SVGAnimatedTypeAnimator.h"
namespace WebCore {
@@ -34,6 +35,28 @@
#define DEFINE_ANIMATED_TRANSFORM_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
DEFINE_ANIMATED_PROPERTY(AnimatedTransformList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty)
+class SVGAnimationElement;
+class SVGAnimateTransformElement;
+class SVGGenericAnimatedType;
+
+class SVGAnimatedTransformListAnimator : public SVGAnimatedTypeAnimator {
+public:
+ SVGAnimatedTransformListAnimator(SVGAnimationElement*, SVGElement*);
+ virtual ~SVGAnimatedTransformListAnimator() { }
+
+ virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
+ virtual PassOwnPtr<SVGAnimatedType> constructFromCopy(SVGGenericAnimatedType*);
+
+ 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:
+ PassOwnPtr<SVGAnimatedType> constructFromString(SVGAnimateTransformElement*, const String&);
+};
+
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/svg/SVGAnimatedType.cpp b/Source/WebCore/svg/SVGAnimatedType.cpp
index 3abaab9..41e579c 100644
--- a/Source/WebCore/svg/SVGAnimatedType.cpp
+++ b/Source/WebCore/svg/SVGAnimatedType.cpp
@@ -32,6 +32,7 @@
#include "SVGPathParserFactory.h"
#include "SVGPointList.h"
#include "SVGPreserveAspectRatio.h"
+#include "SVGTransformList.h"
using namespace std;
@@ -87,6 +88,9 @@
case AnimatedString:
delete m_data.string;
break;
+ case AnimatedTransformList:
+ delete m_data.transformList;
+ break;
default:
ASSERT_NOT_REACHED();
break;
@@ -205,6 +209,14 @@
return animatedType.release();
}
+PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createTransformList(SVGTransformList* transformList)
+{
+ ASSERT(transformList);
+ OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedTransformList));
+ animatedType->m_data.transformList = transformList;
+ return animatedType.release();
+}
+
SVGAngle& SVGAnimatedType::angle()
{
ASSERT(m_type == AnimatedAngle);
@@ -289,6 +301,12 @@
return *m_data.string;
}
+SVGTransformList& SVGAnimatedType::transformList()
+{
+ ASSERT(m_type == AnimatedTransformList);
+ return *m_data.transformList;
+}
+
String SVGAnimatedType::valueAsString()
{
switch (m_type) {
@@ -338,6 +356,9 @@
case AnimatedString:
ASSERT(m_data.string);
return *m_data.string;
+ case AnimatedTransformList:
+ ASSERT(m_data.transformList);
+ return m_data.transformList->valueAsString();
default:
break;
}
@@ -414,6 +435,7 @@
ASSERT(m_data.string);
*m_data.string = value;
break;
+ case AnimatedTransformList:
default:
ASSERT_NOT_REACHED();
break;
@@ -429,10 +451,11 @@
bool SVGAnimatedType::supportsAnimVal(AnimatedPropertyType type)
{
- // FIXME: This lists the current state of our animVal support: only SVGLength is supported for now.
+ // FIXME: This lists the current state of our animVal support.
switch (type) {
case AnimatedLength:
case AnimatedLengthList:
+ case AnimatedTransformList:
return true;
case AnimatedAngle:
case AnimatedBoolean:
@@ -447,7 +470,6 @@
case AnimatedPreserveAspectRatio:
case AnimatedRect:
case AnimatedString:
- case AnimatedTransformList:
case AnimatedUnknown:
return false;
}
@@ -458,7 +480,7 @@
void SVGAnimatedType::setVariantValue(SVGGenericAnimatedType* type)
{
- // FIXME: This lists the current state of our animVal support: only SVGLength is supported for now.
+ // FIXME: This lists the current state of our animVal support.
switch (m_type) {
case AnimatedLength:
*m_data.length = *reinterpret_cast<SVGLength*>(type);
@@ -466,6 +488,9 @@
case AnimatedLengthList:
*m_data.lengthList = *reinterpret_cast<SVGLengthList*>(type);
return;
+ case AnimatedTransformList:
+ *m_data.transformList = *reinterpret_cast<SVGTransformList*>(type);
+ return;
case AnimatedAngle:
case AnimatedBoolean:
case AnimatedColor:
@@ -479,7 +504,6 @@
case AnimatedPreserveAspectRatio:
case AnimatedRect:
case AnimatedString:
- case AnimatedTransformList:
case AnimatedUnknown:
break;
}
diff --git a/Source/WebCore/svg/SVGAnimatedType.h b/Source/WebCore/svg/SVGAnimatedType.h
index 152e34f..77dc6e3 100644
--- a/Source/WebCore/svg/SVGAnimatedType.h
+++ b/Source/WebCore/svg/SVGAnimatedType.h
@@ -35,6 +35,7 @@
class SVGPathByteStream;
class SVGPointList;
class SVGPreserveAspectRatio;
+class SVGTransformList;
class SVGAnimatedType {
WTF_MAKE_FAST_ALLOCATED;
@@ -55,6 +56,7 @@
static PassOwnPtr<SVGAnimatedType> createPreserveAspectRatio(SVGPreserveAspectRatio*);
static PassOwnPtr<SVGAnimatedType> createRect(FloatRect*);
static PassOwnPtr<SVGAnimatedType> createString(String*);
+ static PassOwnPtr<SVGAnimatedType> createTransformList(SVGTransformList*);
static bool supportsAnimVal(AnimatedPropertyType);
AnimatedPropertyType type() const { return m_type; }
@@ -73,6 +75,7 @@
SVGPreserveAspectRatio& preserveAspectRatio();
FloatRect& rect();
String& string();
+ SVGTransformList& transformList();
// Use with care, the actual type of the generic animated object has to be equal to our type().
void setVariantValue(SVGGenericAnimatedType*);
@@ -109,6 +112,7 @@
SVGPointList* pointList;
FloatRect* rect;
String* string;
+ SVGTransformList* transformList;
SVGGenericAnimatedType* variant;
} m_data;
};
diff --git a/Source/WebCore/svg/SVGAnimatorFactory.h b/Source/WebCore/svg/SVGAnimatorFactory.h
index fbc746f..028daf6 100644
--- a/Source/WebCore/svg/SVGAnimatorFactory.h
+++ b/Source/WebCore/svg/SVGAnimatorFactory.h
@@ -35,6 +35,7 @@
#include "SVGAnimatedPreserveAspectRatio.h"
#include "SVGAnimatedRect.h"
#include "SVGAnimatedString.h"
+#include "SVGAnimatedTransformList.h"
namespace WebCore {
@@ -76,8 +77,9 @@
return adoptPtr(new SVGAnimatedRectAnimator(animationElement, contextElement));
case AnimatedString:
return adoptPtr(new SVGAnimatedStringAnimator(animationElement, contextElement));
+ case AnimatedTransformList:
+ return adoptPtr(new SVGAnimatedTransformListAnimator(animationElement, contextElement));
case AnimatedEnumeration: // FIXME: Implementation needed.
- case AnimatedTransformList: // FIXME: Implementation needed.
case AnimatedUnknown:
break;
}
diff --git a/Source/WebCore/svg/SVGGradientElement.cpp b/Source/WebCore/svg/SVGGradientElement.cpp
index c959464..07a88ad 100644
--- a/Source/WebCore/svg/SVGGradientElement.cpp
+++ b/Source/WebCore/svg/SVGGradientElement.cpp
@@ -91,9 +91,7 @@
if (attr->name() == SVGNames::gradientTransformAttr) {
SVGTransformList newList;
- if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
- newList.clear();
-
+ newList.parse(attr->value());
detachAnimatedGradientTransformListWrappers(newList.size());
setGradientTransformBaseValue(newList);
return;
diff --git a/Source/WebCore/svg/SVGPatternElement.cpp b/Source/WebCore/svg/SVGPatternElement.cpp
index 8bf97b3..780f57b 100644
--- a/Source/WebCore/svg/SVGPatternElement.cpp
+++ b/Source/WebCore/svg/SVGPatternElement.cpp
@@ -127,9 +127,7 @@
return;
} else if (attr->name() == SVGNames::patternTransformAttr) {
SVGTransformList newList;
- if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
- newList.clear();
-
+ newList.parse(attr->value());
detachAnimatedPatternTransformListWrappers(newList.size());
setPatternTransformBaseValue(newList);
return;
diff --git a/Source/WebCore/svg/SVGStyledTransformableElement.cpp b/Source/WebCore/svg/SVGStyledTransformableElement.cpp
index 02f35d3..7e6f1dd 100644
--- a/Source/WebCore/svg/SVGStyledTransformableElement.cpp
+++ b/Source/WebCore/svg/SVGStyledTransformableElement.cpp
@@ -107,8 +107,7 @@
if (attr->name() == SVGNames::transformAttr) {
SVGTransformList newList;
- if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
- newList.clear();
+ newList.parse(attr->value());
detachAnimatedTransformListWrappers(newList.size());
setTransformBaseValue(newList);
return;
diff --git a/Source/WebCore/svg/SVGTextElement.cpp b/Source/WebCore/svg/SVGTextElement.cpp
index 54a64a5..cc8b674 100644
--- a/Source/WebCore/svg/SVGTextElement.cpp
+++ b/Source/WebCore/svg/SVGTextElement.cpp
@@ -73,9 +73,7 @@
if (attr->name() == SVGNames::transformAttr) {
SVGTransformList newList;
- if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
- newList.clear();
-
+ newList.parse(attr->value());
detachAnimatedTransformListWrappers(newList.size());
setTransformBaseValue(newList);
return;
diff --git a/Source/WebCore/svg/SVGTransform.cpp b/Source/WebCore/svg/SVGTransform.cpp
index 70bdad7..4561d42 100644
--- a/Source/WebCore/svg/SVGTransform.cpp
+++ b/Source/WebCore/svg/SVGTransform.cpp
@@ -129,49 +129,75 @@
m_matrix.skewY(angle);
}
-String SVGTransform::valueAsString() const
+const String& SVGTransform::transformTypePrefixForParsing(SVGTransformType type)
{
- switch (m_type) {
+ switch (type) {
case SVG_TRANSFORM_UNKNOWN:
- return String();
+ return emptyString();
case SVG_TRANSFORM_MATRIX: {
DEFINE_STATIC_LOCAL(String, matrixString, ("matrix("));
- StringBuilder builder;
- builder.append(matrixString + String::number(m_matrix.a()) + ' ' + String::number(m_matrix.b()) + ' ' + String::number(m_matrix.c()) + ' ' +
- String::number(m_matrix.d()) + ' ' + String::number(m_matrix.e()) + ' ' + String::number(m_matrix.f()) + ')');
- return builder.toString();
+ return matrixString;
}
case SVG_TRANSFORM_TRANSLATE: {
DEFINE_STATIC_LOCAL(String, translateString, ("translate("));
- return translateString + String::number(m_matrix.e()) + ' ' + String::number(m_matrix.f()) + ')';
+ return translateString;
}
case SVG_TRANSFORM_SCALE: {
DEFINE_STATIC_LOCAL(String, scaleString, ("scale("));
- return scaleString + String::number(m_matrix.xScale()) + ' ' + String::number(m_matrix.yScale()) + ')';
+ return scaleString;
}
case SVG_TRANSFORM_ROTATE: {
DEFINE_STATIC_LOCAL(String, rotateString, ("rotate("));
+ return rotateString;
+ }
+ case SVG_TRANSFORM_SKEWX: {
+ DEFINE_STATIC_LOCAL(String, skewXString, ("skewX("));
+ return skewXString;
+ }
+ case SVG_TRANSFORM_SKEWY: {
+ DEFINE_STATIC_LOCAL(String, skewYString, ("skewY("));
+ return skewYString;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyString();
+}
+
+String SVGTransform::valueAsString() const
+{
+ const String& prefix = transformTypePrefixForParsing(m_type);
+ switch (m_type) {
+ case SVG_TRANSFORM_UNKNOWN:
+ return prefix;
+ case SVG_TRANSFORM_MATRIX: {
+ StringBuilder builder;
+ builder.append(prefix + String::number(m_matrix.a()) + ' ' + String::number(m_matrix.b()) + ' ' + String::number(m_matrix.c()) + ' ' +
+ String::number(m_matrix.d()) + ' ' + String::number(m_matrix.e()) + ' ' + String::number(m_matrix.f()) + ')');
+ return builder.toString();
+ }
+ case SVG_TRANSFORM_TRANSLATE:
+ return prefix + String::number(m_matrix.e()) + ' ' + String::number(m_matrix.f()) + ')';
+ case SVG_TRANSFORM_SCALE:
+ return prefix + String::number(m_matrix.xScale()) + ' ' + String::number(m_matrix.yScale()) + ')';
+ case SVG_TRANSFORM_ROTATE: {
double angleInRad = deg2rad(m_angle);
double cosAngle = cos(angleInRad);
double sinAngle = sin(angleInRad);
float cx = narrowPrecisionToFloat(cosAngle != 1 ? (m_matrix.e() * (1 - cosAngle) - m_matrix.f() * sinAngle) / (1 - cosAngle) / 2 : 0);
float cy = narrowPrecisionToFloat(cosAngle != 1 ? (m_matrix.e() * sinAngle / (1 - cosAngle) + m_matrix.f()) / 2 : 0);
if (cx || cy)
- return rotateString + String::number(m_angle) + ' ' + String::number(cx) + ' ' + String::number(cy) + ')';
- return rotateString + String::number(m_angle) + ')';
- }
- case SVG_TRANSFORM_SKEWX: {
- DEFINE_STATIC_LOCAL(String, skewXString, ("skewX("));
- return skewXString + String::number(m_angle) + ')';
+ return prefix + String::number(m_angle) + ' ' + String::number(cx) + ' ' + String::number(cy) + ')';
+ return prefix + String::number(m_angle) + ')';
}
- case SVG_TRANSFORM_SKEWY: {
- DEFINE_STATIC_LOCAL(String, skewYString, ("skewY("));
- return skewYString + String::number(m_angle) + ')';
- }
+ case SVG_TRANSFORM_SKEWX:
+ return prefix + String::number(m_angle) + ')';
+ case SVG_TRANSFORM_SKEWY:
+ return prefix + String::number(m_angle) + ')';
}
ASSERT_NOT_REACHED();
- return String();
+ return emptyString();
}
} // namespace WebCore
diff --git a/Source/WebCore/svg/SVGTransform.h b/Source/WebCore/svg/SVGTransform.h
index 14718ae..6a08b73 100644
--- a/Source/WebCore/svg/SVGTransform.h
+++ b/Source/WebCore/svg/SVGTransform.h
@@ -68,6 +68,8 @@
bool isValid() const { return m_type != SVG_TRANSFORM_UNKNOWN; }
String valueAsString() const;
+ static const String& transformTypePrefixForParsing(SVGTransformType);
+
private:
friend bool operator==(const SVGTransform& a, const SVGTransform& b);
diff --git a/Source/WebCore/svg/SVGTransformList.cpp b/Source/WebCore/svg/SVGTransformList.cpp
index 5cc8492..d97461d 100644
--- a/Source/WebCore/svg/SVGTransformList.cpp
+++ b/Source/WebCore/svg/SVGTransformList.cpp
@@ -26,6 +26,7 @@
#include "AffineTransform.h"
#include "SVGSVGElement.h"
#include "SVGTransform.h"
+#include "SVGTransformable.h"
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -73,6 +74,13 @@
return builder.toString();
}
+void SVGTransformList::parse(const String& transform)
+{
+ const UChar* start = transform.characters();
+ if (!SVGTransformable::parseTransformAttribute(*this, start, start + transform.length()))
+ clear();
+}
+
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/svg/SVGTransformList.h b/Source/WebCore/svg/SVGTransformList.h
index 0afc832..14aba3b 100644
--- a/Source/WebCore/svg/SVGTransformList.h
+++ b/Source/WebCore/svg/SVGTransformList.h
@@ -39,6 +39,7 @@
bool concatenate(AffineTransform& result) const;
String valueAsString() const;
+ void parse(const String&);
};
template<>
diff --git a/Source/WebCore/svg/SVGTransformable.cpp b/Source/WebCore/svg/SVGTransformable.cpp
index d4193bc..094ced9 100644
--- a/Source/WebCore/svg/SVGTransformable.cpp
+++ b/Source/WebCore/svg/SVGTransformable.cpp
@@ -170,10 +170,12 @@
return true;
}
-bool SVGTransformable::parseTransformAttribute(SVGTransformList& list, const AtomicString& transform)
+SVGTransform::SVGTransformType SVGTransformable::parseTransformType(const String& typeString)
{
- const UChar* start = transform.characters();
- return parseTransformAttribute(list, start, start + transform.length());
+ unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
+ const UChar* characters = typeString.characters();
+ parseAndSkipType(characters, characters + typeString.length(), type);
+ return static_cast<SVGTransform::SVGTransformType>(type);
}
bool SVGTransformable::parseTransformAttribute(SVGTransformList& list, const UChar*& currTransform, const UChar* end, TransformParsingMode mode)
diff --git a/Source/WebCore/svg/SVGTransformable.h b/Source/WebCore/svg/SVGTransformable.h
index ffd9cee..7168ba3 100644
--- a/Source/WebCore/svg/SVGTransformable.h
+++ b/Source/WebCore/svg/SVGTransformable.h
@@ -22,16 +22,14 @@
#define SVGTransformable_h
#if ENABLE(SVG)
-#include "PlatformString.h"
#include "SVGLocatable.h"
+#include "SVGTransform.h"
#include "SVGTransformList.h"
-#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
class AffineTransform;
-class SVGTransform;
-class QualifiedName;
class SVGTransformable : virtual public SVGLocatable {
public:
@@ -42,9 +40,9 @@
virtual ~SVGTransformable();
- static bool parseTransformAttribute(SVGTransformList&, const AtomicString& transform);
static bool parseTransformAttribute(SVGTransformList&, const UChar*& ptr, const UChar* end, TransformParsingMode mode = ClearList);
static bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform&);
+ static SVGTransform::SVGTransformType parseTransformType(const String&);
virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const { return animatedLocalTransform(); }
virtual AffineTransform animatedLocalTransform() const = 0;
diff --git a/Source/WebCore/svg/SVGViewSpec.cpp b/Source/WebCore/svg/SVGViewSpec.cpp
index ce7bd19..d09ea59 100644
--- a/Source/WebCore/svg/SVGViewSpec.cpp
+++ b/Source/WebCore/svg/SVGViewSpec.cpp
@@ -48,7 +48,7 @@
void SVGViewSpec::setTransform(const String& transform)
{
- SVGTransformable::parseTransformAttribute(m_transform, transform);
+ m_transform.parse(transform);
}
void SVGViewSpec::setViewBoxString(const String& viewBoxStr)