Bug 687340 - Make dynamic changes to mask, clipPath and marker attributes work. r=roc
authorRobert Longson <longsonr@gmail.com>
Mon, 19 Sep 2011 13:59:52 +0100
changeset 78443 c6d4e5bce80b58d9544405f88b2d9292a75c1ec1
parent 78442 75086668aebb002726a7e9dd27739bf5cd8b1177
child 78444 19518187d2e8051bddb81c2fc7a5f99ae4053e16
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
bugs687340
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 687340 - Make dynamic changes to mask, clipPath and marker attributes work. r=roc
content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
layout/reftests/svg/dynamic-clipPath-02.svg
layout/reftests/svg/dynamic-marker-01.svg
layout/reftests/svg/dynamic-marker-03.svg
layout/reftests/svg/dynamic-mask-01.svg
layout/reftests/svg/reftest.list
layout/svg/base/src/nsSVGClipPathFrame.cpp
layout/svg/base/src/nsSVGMaskFrame.cpp
layout/svg/base/src/nsSVGMaskFrame.h
--- a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
+++ b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
@@ -242,19 +242,17 @@ SVGAnimatedPreserveAspectRatio::SetBaseV
     mAnimVal = mBaseVal;
   }
 #ifdef MOZ_SMIL
   else {
     aSVGElement->AnimationNeedsResample();
   }
 #endif
 
-  // We don't need to call DidChange* here - we're only called by
-  // nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
-  // which takes care of notifying.
+  aSVGElement->DidChangePreserveAspectRatio(aDoSetAttr);
   return NS_OK;
 }
 
 void
 SVGAnimatedPreserveAspectRatio::GetBaseValueString(nsAString & aValueAsString)
 {
   nsAutoString tmpString;
 
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -1208,24 +1208,16 @@ nsSVGSVGElement::DidChangeLength(PRUint8
 
 nsSVGElement::LengthAttributesInfo
 nsSVGSVGElement::GetLengthInfo()
 {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               NS_ARRAY_LENGTH(sLengthInfo));
 }
 
-void
-nsSVGSVGElement::DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr)
-{
-  nsSVGSVGElementBase::DidChangeEnum(aAttrEnum, aDoSetAttr);
-
-  InvalidateTransformNotifyFrame();
-}
-
 nsSVGElement::EnumAttributesInfo
 nsSVGSVGElement::GetEnumInfo()
 {
   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
                             NS_ARRAY_LENGTH(sEnumInfo));
 }
 
 void
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -189,17 +189,16 @@ public:
   NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 #ifdef MOZ_SMIL
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 #endif // MOZ_SMIL
 
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix) const;
   virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
-  virtual void DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr);
   virtual void DidChangeViewBox(PRBool aDoSetAttr);
   virtual void DidChangePreserveAspectRatio(PRBool aDoSetAttr);
 
   virtual void DidAnimateViewBox();
   virtual void DidAnimatePreserveAspectRatio();
   
   // nsSVGSVGElement methods:
   float GetLength(PRUint8 mCtxType);
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/dynamic-clipPath-02.svg
@@ -0,0 +1,37 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+     class="reftest-wait"
+     onload="startTest()"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+  <title>Testing that dynamic changes to the clipPathUnits are reflected in the clipPath</title>
+
+  <defs>
+    <clipPath id="clip1" clipPathUnits="objectBoundingBox">
+      <rect width=".1" height=".1"/>
+    </clipPath>
+  </defs>
+
+  <rect width="100%" height="100%" fill="lime"/>
+
+  <g transform="scale(1000)">
+    <rect x=".2" y=".2" width=".6" height=".6" fill="red" clip-path="url(#clip1)"/>
+  </g>
+
+  <script>
+    function startTest() {
+      document.addEventListener("MozReftestInvalidate", doTest, false);
+      // in case we're not gecko
+      setTimeout(doTest, 5000);
+    }
+
+    function doTest() {
+      var clip1 = document.getElementById("clip1");
+      clip1.setAttribute("clipPathUnits", "userSpaceOnUse");
+
+      document.documentElement.removeAttribute("class");
+    }
+  </script>
+</svg>
--- a/layout/reftests/svg/dynamic-marker-01.svg
+++ b/layout/reftests/svg/dynamic-marker-01.svg
@@ -1,19 +1,19 @@
 <!--
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="reftest-wait" onload="startTest()" xmlns:xlink="http://www.w3.org/1999/xlink">
   <title>Testing that dynamic changes to the element for a given ID are reflected in marker</title>
   <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=309220 -->
   <defs>
-	  <marker id="x" style="overflow: visible;" orient="auto" markerUnits="strokeWidth">
-		  <rect width="100%" height="100%" fill="lime"/>
-	  </marker>
+    <marker id="x" style="overflow: visible;" orient="auto" markerUnits="strokeWidth">
+      <rect width="100%" height="100%" fill="lime"/>
+    </marker>
   </defs>
 	
   <rect width="100%" height="100%" fill="red"/>
 	
   <line id="l1" x1="0" x2="0" y1="0" y2="0" fill="none" stroke="black" stroke-width="1" marker-end="url(#m1)"/>
 
   <script>
   function startTest() {
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/dynamic-marker-03.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" class="reftest-wait"
+  onload="startTest()">
+
+  <title>Testing that dynamic changes to preserveAspectRatio are reflected in the marker</title>
+  <script>
+<![CDATA[
+
+function startTest() {
+  document.addEventListener("MozReftestInvalidate", doTest, false);
+  // in case we're not gecko
+  setTimeout(doTest, 5000);
+}
+
+function doTest() {
+  m = document.getElementById("m1");
+  m.preserveAspectRatio.baseVal.align =
+    SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE;
+  document.documentElement.removeAttribute("class");
+}
+
+]]>
+  </script>
+
+  <defs>
+    <marker id="m1" orient="auto" markerUnits="userSpaceOnUse"
+      preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40" markerWidth="60" markerHeight="30">
+      <rect width="30" height="40" fill="red"/>
+    </marker>
+  </defs>
+	
+  <rect width="100%" height="100%" fill="lime"/>
+	
+  <line x1="30" x2="30" y1="10" y2="10" stroke="red" stroke-width="3" marker-end="url(#m1)"/>
+
+  <rect x="30" y="10" width="60" height="30" fill="lime"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/dynamic-mask-01.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+     class="reftest-wait"
+     onload="startTest()"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+  <title>Testing that dynamic changes to mask attributes are reflected in the mask</title>
+
+  <defs>
+    <mask id="mask1" width="1" height="1">
+      <rect width="1" height="1" fill="white"/>
+    </mask>
+  </defs>
+
+  <rect width="100%" height="100%" fill="lime"/>
+
+  <g transform="scale(500)">
+    <rect x=".2" y=".2" width=".2" height=".2" fill="red" mask="url(#mask1)"/>
+  </g>
+
+  <script>
+    function startTest() {
+      document.addEventListener("MozReftestInvalidate", doTest, false);
+      // in case we're not gecko
+      setTimeout(doTest, 5000);
+    }
+
+    function doTest() {
+      var mask1 = document.getElementById("mask1");
+      mask1.maskUnits.baseVal = SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE;
+
+      document.documentElement.removeAttribute("class");
+    }
+  </script>
+</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -57,26 +57,29 @@ fails-if(Android) == dynamic-conditions-
 == dynamic-conditions-07.svg pass.svg
 == dynamic-conditions-08.svg pass.svg
 == dynamic-conditions-09.svg about:blank
 == dynamic-conditions-10.svg about:blank
 == dynamic-conditions-11.svg pass.svg
 == dynamic-conditions-12.svg pass.svg
 == dynamic-conditions-13.svg about:blank
 == dynamic-clipPath-01.svg pass.svg
+== dynamic-clipPath-02.svg pass.svg
 == dynamic-feFlood-01.svg pass.svg
 == dynamic-feImage-01.svg pass.svg
 == dynamic-filter-contents-01a.svg dynamic-filter-contents-01-ref.svg
 == dynamic-filter-contents-01b.svg dynamic-filter-contents-01-ref.svg
 == dynamic-gradient-contents-01.svg pass.svg
 == dynamic-gradient-contents-02.svg pass.svg
 == dynamic-inner-svg-01.svg pass.svg
 == dynamic-link-style-01.svg pass.svg
 == dynamic-marker-01.svg pass.svg
 == dynamic-marker-02.svg dynamic-marker-02-ref.svg
+== dynamic-marker-03.svg pass.svg
+== dynamic-mask-01.svg pass.svg
 == dynamic-mask-contents-01.svg pass.svg
 == dynamic-pattern-01.svg pass.svg
 == dynamic-pattern-02.svg pass.svg
 == dynamic-pattern-contents-01.svg pass.svg
 == dynamic-pattern-contents-02.svg pass.svg
 == dynamic-rect-01.svg dynamic-rect-01-ref.svg
 == dynamic-rect-02.svg dynamic-rect-02-ref.svg
 == dynamic-rect-03.svg dynamic-rect-03-ref.svg
--- a/layout/svg/base/src/nsSVGClipPathFrame.cpp
+++ b/layout/svg/base/src/nsSVGClipPathFrame.cpp
@@ -275,20 +275,24 @@ nsSVGClipPathFrame::IsValid()
   return PR_TRUE;
 }
 
 NS_IMETHODIMP
 nsSVGClipPathFrame::AttributeChanged(PRInt32         aNameSpaceID,
                                      nsIAtom*        aAttribute,
                                      PRInt32         aModType)
 {
-  if (aNameSpaceID == kNameSpaceID_None &&
-      aAttribute == nsGkAtoms::transform) {
-    nsSVGUtils::NotifyChildrenOfSVGChange(this,
-                                          nsISVGChildFrame::TRANSFORM_CHANGED);
+  if (aNameSpaceID == kNameSpaceID_None) {
+    if (aAttribute == nsGkAtoms::transform) {
+      nsSVGUtils::NotifyChildrenOfSVGChange(this,
+                                            nsISVGChildFrame::TRANSFORM_CHANGED);
+    }
+    if (aAttribute == nsGkAtoms::clipPathUnits) {
+      nsSVGEffects::InvalidateRenderingObservers(this);
+    }
   }
 
   return nsSVGClipPathFrameBase::AttributeChanged(aNameSpaceID,
                                                   aAttribute, aModType);
 }
 
 NS_IMETHODIMP
 nsSVGClipPathFrame::Init(nsIContent* aContent,
--- a/layout/svg/base/src/nsSVGMaskFrame.cpp
+++ b/layout/svg/base/src/nsSVGMaskFrame.cpp
@@ -33,16 +33,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDocument.h"
 #include "nsSVGMaskFrame.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGMaskElement.h"
+#include "nsSVGEffects.h"
 #include "nsIDOMSVGMatrix.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "nsSVGMatrix.h"
 
 //----------------------------------------------------------------------
 // Implementation
 
@@ -152,16 +153,35 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRe
       memset(pixel, alpha, 4);
     }
 
   gfxPattern *retval = new gfxPattern(image);
   NS_IF_ADDREF(retval);
   return retval;
 }
 
+NS_IMETHODIMP
+nsSVGMaskFrame::AttributeChanged(PRInt32  aNameSpaceID,
+                                 nsIAtom* aAttribute,
+                                 PRInt32  aModType)
+{
+  if (aNameSpaceID == kNameSpaceID_None &&
+      (aAttribute == nsGkAtoms::x ||
+       aAttribute == nsGkAtoms::y ||
+       aAttribute == nsGkAtoms::width ||
+       aAttribute == nsGkAtoms::height||
+       aAttribute == nsGkAtoms::maskUnits ||
+       aAttribute == nsGkAtoms::maskContentUnits)) {
+    nsSVGEffects::InvalidateRenderingObservers(this);
+  }
+
+  return nsSVGMaskFrameBase::AttributeChanged(aNameSpaceID,
+                                              aAttribute, aModType);
+}
+
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGMaskFrame::Init(nsIContent* aContent,
                      nsIFrame* aParent,
                      nsIFrame* aPrevInFlow)
 {
   nsCOMPtr<nsIDOMSVGMaskElement> mask = do_QueryInterface(aContent);
   NS_ASSERTION(mask, "Content is not an SVG mask");
--- a/layout/svg/base/src/nsSVGMaskFrame.h
+++ b/layout/svg/base/src/nsSVGMaskFrame.h
@@ -59,16 +59,20 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsSVGMaskFrame method:
   already_AddRefed<gfxPattern> ComputeMaskAlpha(nsSVGRenderState *aContext,
                                                 nsIFrame* aParent,
                                                 const gfxMatrix &aMatrix,
                                                 float aOpacity = 1.0f);
 
+  NS_IMETHOD AttributeChanged(PRInt32         aNameSpaceID,
+                              nsIAtom*        aAttribute,
+                              PRInt32         aModType);
+
 #ifdef DEBUG
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        aPrevInFlow);
 #endif
 
   /**
    * Get the "type" of the frame