Bug 687340 - Make dynamic changes to mask, clipPath and marker attributes work. r=roc
--- 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