Bug 665392: Make <animateMotion>'s transform apply on top of the "transform" attribute, instead of the other way around. r=roc
☠☠ backed out by 06445f55f009 ☠ ☠
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 15 Sep 2011 15:42:55 -0700
changeset 78339 c3bf76213a6c4b60aa59c9d14873c6052e252913
parent 78338 dd5de1ab91406d94bf4bcecbfed7c223a1e6aa16
child 78340 6806beccdeaffd39a5852f1692e89c225e840cee
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs665392
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 665392: Make <animateMotion>'s transform apply on top of the "transform" attribute, instead of the other way around. r=roc
content/svg/content/src/nsSVGGraphicElement.cpp
layout/reftests/svg/smil/motion/animateMotion-rotate-3.svg
layout/reftests/svg/smil/motion/reftest.list
--- a/content/svg/content/src/nsSVGGraphicElement.cpp
+++ b/content/svg/content/src/nsSVGGraphicElement.cpp
@@ -184,37 +184,37 @@ nsSVGGraphicElement::IsEventName(nsIAtom
   return nsContentUtils::IsEventAttributeName(aName, EventNameType_SVGGraphic);
 }
 
 gfxMatrix
 nsSVGGraphicElement::PrependLocalTransformTo(const gfxMatrix &aMatrix) const
 {
   gfxMatrix result(aMatrix);
 
-  // animateMotion's resulting transform is supposed to apply *on top of*
-  // any transformations from the |transform| attribute. So since we're
-  // PRE-multiplying, we need to apply the animateMotion transform *first*.
-  if (mAnimateMotionTransform) {
-    result.PreMultiply(*mAnimateMotionTransform);
-  }
-
   if (mTransforms) {
     nsresult rv;
     nsCOMPtr<nsIDOMSVGTransformList> transforms;
     rv = mTransforms->GetAnimVal(getter_AddRefs(transforms));
     NS_ENSURE_SUCCESS(rv, aMatrix);
     PRUint32 count;
     transforms->GetNumberOfItems(&count);
     if (count > 0) {
       nsCOMPtr<nsIDOMSVGMatrix> matrix =
         nsSVGTransformList::GetConsolidationMatrix(transforms);
       result.PreMultiply(nsSVGUtils::ConvertSVGMatrixToThebes(matrix));
     }
   }
 
+  // <animateMotion>'s transformation is *supplemental* to the |transform|
+  // attribute and any transformations on ancestors.  So, we apply it
+  // (pre-multiply it) last.
+  if (mAnimateMotionTransform) {
+    result.PreMultiply(*mAnimateMotionTransform);
+  }
+
   return result;
 }
 
 void
 nsSVGGraphicElement::SetAnimateMotionTransform(const gfxMatrix* aMatrix)
 {
   mAnimateMotionTransform = aMatrix ? new gfxMatrix(*aMatrix) : nsnull;
   DidAnimateTransform();
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/smil/motion/animateMotion-rotate-3.svg
@@ -0,0 +1,30 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     class="reftest-wait">
+  <!-- Tests for "rotate" interacting with the transform attribute. -->
+  <script xlink:href="../smil-util.js" type="text/javascript"/>
+  <script type="text/javascript">
+    function doTest() {
+      setTimeAndSnapshot(1, false);
+    }
+    window.addEventListener("MozReftestInvalidate", doTest, false);
+  </script>
+
+  <!-- Big green background to match lime.svg -->
+  <rect height="100%" width="100%" fill="lime"/>
+
+  <!-- A "shadow" rect (should be covered up by green rect). The only difference
+       between this rect and the other one is that this rect has the
+       |transform| attr set on its <g> parent instead of on it directly. -->
+  <g transform="translate(0, 50)">
+    <rect width="50" height="50" fill="red">
+     <animateMotion begin="0s" dur="1s" fill="freeze" rotate="90"
+                    path="M50 0 h50"/>
+    </rect>
+  </g>
+
+  <rect width="50" height="50" fill="lime" transform="translate(0, 50)">
+    <animateMotion begin="0s" dur="1s" fill="freeze" rotate="90"
+                   path="M50 0 h50"/>
+  </rect>
+</svg>
--- a/layout/reftests/svg/smil/motion/reftest.list
+++ b/layout/reftests/svg/smil/motion/reftest.list
@@ -3,16 +3,17 @@
 
 == animateMotion-by-1.svg      lime.svg
 == animateMotion-from-to-1.svg lime.svg
 == animateMotion-indefinite-to-1.svg lime.svg
 == animateMotion-indefinite-to-2.svg lime.svg
 == animateMotion-rotate-1a.svg lime.svg
 == animateMotion-rotate-1b.svg lime.svg
 == animateMotion-rotate-2.svg  lime.svg
+== animateMotion-rotate-3.svg  lime.svg
 == animateMotion-to-overridden-1.svg lime.svg
 == animateMotion-values-linear-1.svg animateMotion-values-linear-1-ref.svg
 == animateMotion-values-paced-1a.svg animateMotion-values-paced-1-ref.svg
 == animateMotion-values-paced-1b.svg animateMotion-values-paced-1-ref.svg
 
 # Tests involving <mpath> sub-element
 == animateMotion-mpath-pathLength-1.svg lime.svg
 == animateMotion-mpath-targetChange-1.svg lime.svg