diff --git a/layout/reftests/svg/smil/anim-gradient-attr-presence-01-ref.svg b/layout/reftests/svg/smil/anim-gradient-attr-presence-01-ref.svg
new file mode 100644
index 00000000000..44e380bc026
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-gradient-attr-presence-01-ref.svg
@@ -0,0 +1,142 @@
+
+
diff --git a/layout/reftests/svg/smil/anim-gradient-attr-presence-01.svg b/layout/reftests/svg/smil/anim-gradient-attr-presence-01.svg
new file mode 100644
index 00000000000..71a6aa89cf5
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-gradient-attr-presence-01.svg
@@ -0,0 +1,193 @@
+
+
diff --git a/layout/reftests/svg/smil/reftest.list b/layout/reftests/svg/smil/reftest.list
index a029ca4d4b8..9e713e93bb4 100644
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -226,6 +226,7 @@ random == anim-text-x-y-dx-dy-01.svg anim-text-x-y-dx-dy-01-ref.svg # bug 579588
== anim-pattern-attr-presence-01.svg anim-pattern-attr-presence-01-ref.svg
fails == anim-pattern-attr-presence-02.svg anim-pattern-attr-presence-02-ref.svg
# ^ bug 621651
+== anim-gradient-attr-presence-01.svg anim-gradient-attr-presence-01-ref.svg
== api-sanity-1.svg lime.svg
diff --git a/layout/svg/base/src/nsSVGGradientFrame.cpp b/layout/svg/base/src/nsSVGGradientFrame.cpp
index 9c0e49cd215..8a1b7c2bb53 100644
--- a/layout/svg/base/src/nsSVGGradientFrame.cpp
+++ b/layout/svg/base/src/nsSVGGradientFrame.cpp
@@ -51,6 +51,27 @@
using mozilla::SVGAnimatedTransformList;
+//----------------------------------------------------------------------
+// Helper classes
+
+class nsSVGGradientFrame::AutoGradientReferencer
+{
+public:
+ AutoGradientReferencer(nsSVGGradientFrame *aFrame)
+ : mFrame(aFrame)
+ {
+ // Reference loops should normally be detected in advance and handled, so
+ // we're not expecting to encounter them here
+ NS_ABORT_IF_FALSE(!mFrame->mLoopFlag, "Undetected reference loop!");
+ mFrame->mLoopFlag = true;
+ }
+ ~AutoGradientReferencer() {
+ mFrame->mLoopFlag = false;
+ }
+private:
+ nsSVGGradientFrame *mFrame;
+};
+
//----------------------------------------------------------------------
// Implementation
@@ -134,6 +155,40 @@ nsSVGGradientFrame::GetStopInformation(PRInt32 aIndex,
*aStopOpacity = stopFrame->GetStyleSVGReset()->mStopOpacity;
}
+PRUint16
+nsSVGGradientFrame::GetEnumValue(PRUint32 aIndex, nsIContent *aDefault)
+{
+ const nsSVGEnum& thisEnum =
+ static_cast(mContent)->mEnumAttributes[aIndex];
+
+ if (thisEnum.IsExplicitlySet())
+ return thisEnum.GetAnimValue();
+
+ AutoGradientReferencer gradientRef(this);
+
+ nsSVGGradientFrame *next = GetReferencedGradientIfNotInUse();
+ return next ? next->GetEnumValue(aIndex, aDefault) :
+ static_cast(aDefault)->
+ mEnumAttributes[aIndex].GetAnimValue();
+}
+
+const SVGAnimatedTransformList*
+nsSVGGradientFrame::GetGradientTransformList(nsIContent* aDefault)
+{
+ SVGAnimatedTransformList *thisTransformList =
+ static_cast(mContent)->GetAnimatedTransformList();
+
+ if (thisTransformList->IsExplicitlySet())
+ return thisTransformList;
+
+ AutoGradientReferencer gradientRef(this);
+
+ nsSVGGradientFrame *next = GetReferencedGradientIfNotInUse();
+ return next ? next->GetGradientTransformList(aDefault) :
+ static_cast(aDefault)
+ ->mGradientTransform.get();
+}
+
gfxMatrix
nsSVGGradientFrame::GetGradientTransform(nsIFrame *aSource,
const gfxRect *aOverrideBounds)
@@ -150,19 +205,19 @@ nsSVGGradientFrame::GetGradientTransform(nsIFrame *aSource,
else
mSource = aSource;
} else {
- NS_ASSERTION(gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
- "Unknown gradientUnits type");
+ NS_ASSERTION(
+ gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
+ "Unknown gradientUnits type");
// objectBoundingBox is the default anyway
- gfxRect bbox = aOverrideBounds ? *aOverrideBounds : nsSVGUtils::GetBBox(aSource);
- bboxMatrix = gfxMatrix(bbox.Width(), 0, 0, bbox.Height(), bbox.X(), bbox.Y());
+ gfxRect bbox =
+ aOverrideBounds ? *aOverrideBounds : nsSVGUtils::GetBBox(aSource);
+ bboxMatrix =
+ gfxMatrix(bbox.Width(), 0, 0, bbox.Height(), bbox.X(), bbox.Y());
}
- nsSVGGradientElement *element =
- GetGradientWithAttr(nsGkAtoms::gradientTransform, mContent);
-
- SVGAnimatedTransformList* animTransformList =
- element->GetAnimatedTransformList();
+ const SVGAnimatedTransformList* animTransformList =
+ GetGradientTransformList(mContent);
if (!animTransformList)
return bboxMatrix;
@@ -171,13 +226,32 @@ nsSVGGradientFrame::GetGradientTransform(nsIFrame *aSource,
return bboxMatrix.PreMultiply(gradientTransform);
}
-PRUint16
-nsSVGGradientFrame::GetSpreadMethod()
+nsSVGLinearGradientElement *
+nsSVGGradientFrame::GetLinearGradientWithLength(PRUint32 aIndex,
+ nsSVGLinearGradientElement* aDefault)
{
- nsSVGGradientElement *element =
- GetGradientWithAttr(nsGkAtoms::spreadMethod, mContent);
+ // If this was a linear gradient with the required length, we would have
+ // already found it in nsSVGLinearGradientFrame::GetLinearGradientWithLength.
+ // Since we didn't find the length, continue looking down the chain.
- return element->mEnumAttributes[nsSVGGradientElement::SPREADMETHOD].GetAnimValue();
+ AutoGradientReferencer gradientRef(this);
+
+ nsSVGGradientFrame *next = GetReferencedGradientIfNotInUse();
+ return next ? next->GetLinearGradientWithLength(aIndex, aDefault) : aDefault;
+}
+
+nsSVGRadialGradientElement *
+nsSVGGradientFrame::GetRadialGradientWithLength(PRUint32 aIndex,
+ nsSVGRadialGradientElement* aDefault)
+{
+ // If this was a radial gradient with the required length, we would have
+ // already found it in nsSVGRadialGradientFrame::GetRadialGradientWithLength.
+ // Since we didn't find the length, continue looking down the chain.
+
+ AutoGradientReferencer gradientRef(this);
+
+ nsSVGGradientFrame *next = GetReferencedGradientIfNotInUse();
+ return next ? next->GetRadialGradientWithLength(aIndex, aDefault) : aDefault;
}
//----------------------------------------------------------------------
@@ -289,53 +363,20 @@ nsSVGGradientFrame::GetReferencedGradient()
return static_cast(result);
}
-nsSVGGradientElement *
-nsSVGGradientFrame::GetGradientWithAttr(nsIAtom *aAttrName, nsIContent *aDefault)
+nsSVGGradientFrame *
+nsSVGGradientFrame::GetReferencedGradientIfNotInUse()
{
- if (mContent->HasAttr(kNameSpaceID_None, aAttrName))
- return static_cast(mContent);
+ nsSVGGradientFrame *referenced = GetReferencedGradient();
+ if (!referenced)
+ return nsnull;
- nsSVGGradientElement *grad = static_cast(aDefault);
+ if (referenced->mLoopFlag) {
+ // XXXjwatt: we should really send an error to the JavaScript Console here:
+ NS_WARNING("gradient reference loop detected while inheriting attribute!");
+ return nsnull;
+ }
- nsSVGGradientFrame *next = GetReferencedGradient();
- if (!next)
- return grad;
-
- // Set mLoopFlag before checking mNextGrad->mLoopFlag in case we are mNextGrad
- mLoopFlag = true;
- // XXXjwatt: we should really send an error to the JavaScript Console here:
- NS_WARN_IF_FALSE(!next->mLoopFlag, "gradient reference loop detected "
- "while inheriting attribute!");
- if (!next->mLoopFlag)
- grad = next->GetGradientWithAttr(aAttrName, aDefault);
- mLoopFlag = false;
-
- return grad;
-}
-
-nsSVGGradientElement *
-nsSVGGradientFrame::GetGradientWithAttr(nsIAtom *aAttrName, nsIAtom *aGradType,
- nsIContent *aDefault)
-{
- if (GetType() == aGradType && mContent->HasAttr(kNameSpaceID_None, aAttrName))
- return static_cast(mContent);
-
- nsSVGGradientElement *grad = static_cast(aDefault);
-
- nsSVGGradientFrame *next = GetReferencedGradient();
- if (!next)
- return grad;
-
- // Set mLoopFlag before checking mNextGrad->mLoopFlag in case we are mNextGrad
- mLoopFlag = true;
- // XXXjwatt: we should really send an error to the JavaScript Console here:
- NS_WARN_IF_FALSE(!next->mLoopFlag, "gradient reference loop detected "
- "while inheriting attribute!");
- if (!next->mLoopFlag)
- grad = next->GetGradientWithAttr(aAttrName, aGradType, aDefault);
- mLoopFlag = false;
-
- return grad;
+ return referenced;
}
PRInt32
@@ -359,33 +400,12 @@ nsSVGGradientFrame::GetStopFrame(PRInt32 aIndex, nsIFrame * *aStopFrame)
// Our gradient element doesn't have stops - try to "inherit" them
- nsSVGGradientFrame *next = GetReferencedGradient();
- if (!next) {
- if (aStopFrame)
- *aStopFrame = nsnull;
- return 0;
- }
+ AutoGradientReferencer gradientRef(this);
+ nsSVGGradientFrame* next = GetReferencedGradientIfNotInUse();
+ if (!next)
+ return nsnull;
- // Set mLoopFlag before checking mNextGrad->mLoopFlag in case we are mNextGrad
- mLoopFlag = true;
- // XXXjwatt: we should really send an error to the JavaScript Console here:
- NS_WARN_IF_FALSE(!next->mLoopFlag, "gradient reference loop detected "
- "while inheriting stop!");
- if (!next->mLoopFlag)
- stopCount = next->GetStopFrame(aIndex, aStopFrame);
- mLoopFlag = false;
-
- return stopCount;
-}
-
-PRUint16
-nsSVGGradientFrame::GetGradientUnits()
-{
- // This getter is called every time the others are called - maybe cache it?
-
- nsSVGGradientElement *element =
- GetGradientWithAttr(nsGkAtoms::gradientUnits, mContent);
- return element->mEnumAttributes[nsSVGGradientElement::GRADIENTUNITS].GetAnimValue();
+ return next->GetStopFrame(aIndex, aStopFrame);
}
// -------------------------------------------------------------------------
@@ -431,11 +451,16 @@ nsSVGLinearGradientFrame::AttributeChanged(PRInt32 aNameSpaceID,
//----------------------------------------------------------------------
float
-nsSVGLinearGradientFrame::GradientLookupAttribute(nsIAtom *aAtomName,
- PRUint16 aEnumName)
+nsSVGLinearGradientFrame::GetLengthValue(PRUint32 aIndex)
{
- nsSVGLinearGradientElement *element =
- GetLinearGradientWithAttr(aAtomName, mContent);
+ nsSVGLinearGradientElement* lengthElement =
+ GetLinearGradientWithLength(aIndex,
+ static_cast(mContent));
+ // We passed in mContent as a fallback, so, assuming mContent is non-null, the
+ // return value should also be non-null.
+ NS_ABORT_IF_FALSE(lengthElement,
+ "Got unexpected null element from GetLinearGradientWithLength");
+ const nsSVGLength2 &length = lengthElement->mLengthAttributes[aIndex];
// Object bounding box units are handled by setting the appropriate
// transform in GetGradientTransform, but we need to handle user
@@ -443,15 +468,30 @@ nsSVGLinearGradientFrame::GradientLookupAttribute(nsIAtom *aAtomName,
PRUint16 gradientUnits = GetGradientUnits();
if (gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
- return nsSVGUtils::UserSpace(mSource,
- &element->mLengthAttributes[aEnumName]);
+ return nsSVGUtils::UserSpace(mSource, &length);
}
- NS_ASSERTION(gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
- "Unknown gradientUnits type");
+ NS_ASSERTION(
+ gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
+ "Unknown gradientUnits type");
- return element->mLengthAttributes[aEnumName].
- GetAnimValue(static_cast(nsnull));
+ return length.GetAnimValue(static_cast(nsnull));
+}
+
+nsSVGLinearGradientElement *
+nsSVGLinearGradientFrame::GetLinearGradientWithLength(PRUint32 aIndex,
+ nsSVGLinearGradientElement* aDefault)
+{
+ nsSVGLinearGradientElement* thisElement =
+ static_cast(mContent);
+ const nsSVGLength2 &length = thisElement->mLengthAttributes[aIndex];
+
+ if (length.IsExplicitlySet()) {
+ return thisElement;
+ }
+
+ return nsSVGLinearGradientFrameBase::GetLinearGradientWithLength(aIndex,
+ aDefault);
}
already_AddRefed
@@ -459,10 +499,10 @@ nsSVGLinearGradientFrame::CreateGradient()
{
float x1, y1, x2, y2;
- x1 = GradientLookupAttribute(nsGkAtoms::x1, nsSVGLinearGradientElement::X1);
- y1 = GradientLookupAttribute(nsGkAtoms::y1, nsSVGLinearGradientElement::Y1);
- x2 = GradientLookupAttribute(nsGkAtoms::x2, nsSVGLinearGradientElement::X2);
- y2 = GradientLookupAttribute(nsGkAtoms::y2, nsSVGLinearGradientElement::Y2);
+ x1 = GetLengthValue(nsSVGLinearGradientElement::X1);
+ y1 = GetLengthValue(nsSVGLinearGradientElement::Y1);
+ x2 = GetLengthValue(nsSVGLinearGradientElement::X2);
+ y2 = GetLengthValue(nsSVGLinearGradientElement::Y2);
gfxPattern *pattern = new gfxPattern(x1, y1, x2, y2);
NS_IF_ADDREF(pattern);
@@ -513,17 +553,33 @@ nsSVGRadialGradientFrame::AttributeChanged(PRInt32 aNameSpaceID,
//----------------------------------------------------------------------
float
-nsSVGRadialGradientFrame::GradientLookupAttribute(nsIAtom *aAtomName,
- PRUint16 aEnumName,
- nsSVGRadialGradientElement *aElement)
+nsSVGRadialGradientFrame::GetLengthValue(PRUint32 aIndex)
{
- nsSVGRadialGradientElement *element;
+ nsSVGRadialGradientElement* lengthElement =
+ GetRadialGradientWithLength(aIndex,
+ static_cast(mContent));
+ // We passed in mContent as a fallback, so, assuming mContent is non-null,
+ // the return value should also be non-null.
+ NS_ABORT_IF_FALSE(lengthElement,
+ "Got unexpected null element from GetRadialGradientWithLength");
+ return GetLengthValueFromElement(aIndex, *lengthElement);
+}
- if (aElement) {
- element = aElement;
- } else {
- element = GetRadialGradientWithAttr(aAtomName, mContent);
- }
+float
+nsSVGRadialGradientFrame::GetLengthValue(PRUint32 aIndex, float aDefaultValue)
+{
+ nsSVGRadialGradientElement* lengthElement =
+ GetRadialGradientWithLength(aIndex, nsnull);
+
+ return lengthElement ? GetLengthValueFromElement(aIndex, *lengthElement)
+ : aDefaultValue;
+}
+
+float
+nsSVGRadialGradientFrame::GetLengthValueFromElement(PRUint32 aIndex,
+ nsSVGRadialGradientElement& aElement)
+{
+ const nsSVGLength2 &length = aElement.mLengthAttributes[aIndex];
// Object bounding box units are handled by setting the appropriate
// transform in GetGradientTransform, but we need to handle user
@@ -531,15 +587,30 @@ nsSVGRadialGradientFrame::GradientLookupAttribute(nsIAtom *aAtomName,
PRUint16 gradientUnits = GetGradientUnits();
if (gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
- return nsSVGUtils::UserSpace(mSource,
- &element->mLengthAttributes[aEnumName]);
+ return nsSVGUtils::UserSpace(mSource, &length);
}
- NS_ASSERTION(gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
- "Unknown gradientUnits type");
+ NS_ASSERTION(
+ gradientUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX,
+ "Unknown gradientUnits type");
- return element->mLengthAttributes[aEnumName].
- GetAnimValue(static_cast(nsnull));
+ return length.GetAnimValue(static_cast(nsnull));
+}
+
+nsSVGRadialGradientElement *
+nsSVGRadialGradientFrame::GetRadialGradientWithLength(PRUint32 aIndex,
+ nsSVGRadialGradientElement* aDefault)
+{
+ nsSVGRadialGradientElement* thisElement =
+ static_cast(mContent);
+ const nsSVGLength2 &length = thisElement->mLengthAttributes[aIndex];
+
+ if (length.IsExplicitlySet()) {
+ return thisElement;
+ }
+
+ return nsSVGRadialGradientFrameBase::GetRadialGradientWithLength(aIndex,
+ aDefault);
}
already_AddRefed
@@ -547,21 +618,12 @@ nsSVGRadialGradientFrame::CreateGradient()
{
float cx, cy, r, fx, fy;
- cx = GradientLookupAttribute(nsGkAtoms::cx, nsSVGRadialGradientElement::CX);
- cy = GradientLookupAttribute(nsGkAtoms::cy, nsSVGRadialGradientElement::CY);
- r = GradientLookupAttribute(nsGkAtoms::r, nsSVGRadialGradientElement::R);
-
- nsSVGRadialGradientElement *gradient;
-
- if (!(gradient = GetRadialGradientWithAttr(nsGkAtoms::fx, nsnull)))
- fx = cx; // if fx isn't set, we must use cx
- else
- fx = GradientLookupAttribute(nsGkAtoms::fx, nsSVGRadialGradientElement::FX, gradient);
-
- if (!(gradient = GetRadialGradientWithAttr(nsGkAtoms::fy, nsnull)))
- fy = cy; // if fy isn't set, we must use cy
- else
- fy = GradientLookupAttribute(nsGkAtoms::fy, nsSVGRadialGradientElement::FY, gradient);
+ cx = GetLengthValue(nsSVGRadialGradientElement::CX);
+ cy = GetLengthValue(nsSVGRadialGradientElement::CY);
+ r = GetLengthValue(nsSVGRadialGradientElement::R);
+ // If fx or fy are not set, use cx/cy instead
+ fx = GetLengthValue(nsSVGRadialGradientElement::FX, cx);
+ fy = GetLengthValue(nsSVGRadialGradientElement::FY, cy);
if (fx != cx || fy != cy) {
// The focal point (fFx and fFy) must be clamped to be *inside* - not on -
diff --git a/layout/svg/base/src/nsSVGGradientFrame.h b/layout/svg/base/src/nsSVGGradientFrame.h
index 07294fa29c4..3a19414417c 100644
--- a/layout/svg/base/src/nsSVGGradientFrame.h
+++ b/layout/svg/base/src/nsSVGGradientFrame.h
@@ -86,45 +86,48 @@ private:
// the referenced gradient's frame if available, null otherwise.
nsSVGGradientFrame* GetReferencedGradient();
- // Helpers to look at our gradient and then along its reference chain (if any)
- // to find the first gradient with the specified attribute.
- // Returns aDefault if no content with that attribute is found
- nsSVGGradientElement* GetGradientWithAttr(nsIAtom *aAttrName, nsIContent *aDefault);
-
- // Some attributes are only valid on one type of gradient, and we *must* get
- // the right type or we won't have the data structures we require.
- // Returns aDefault if no content with that attribute is found
- nsSVGGradientElement* GetGradientWithAttr(nsIAtom *aAttrName, nsIAtom *aGradType,
- nsIContent *aDefault);
-
// Optionally get a stop frame (returns stop index/count)
PRInt32 GetStopFrame(PRInt32 aIndex, nsIFrame * *aStopFrame);
- PRUint16 GetSpreadMethod();
PRUint32 GetStopCount();
void GetStopInformation(PRInt32 aIndex,
float *aOffset, nscolor *aColor, float *aStopOpacity);
+ const mozilla::SVGAnimatedTransformList* GetGradientTransformList(
+ nsIContent* aDefault);
// Will be singular for gradientUnits="objectBoundingBox" with an empty bbox.
- gfxMatrix GetGradientTransform(nsIFrame *aSource, const gfxRect *aOverrideBounds);
+ gfxMatrix GetGradientTransform(nsIFrame *aSource,
+ const gfxRect *aOverrideBounds);
protected:
virtual already_AddRefed CreateGradient() = 0;
- // Use these inline methods instead of GetGradientWithAttr(..., aGradType)
- nsSVGLinearGradientElement* GetLinearGradientWithAttr(nsIAtom *aAttrName, nsIContent *aDefault)
+ // Internal methods for handling referenced gradients
+ class AutoGradientReferencer;
+ nsSVGGradientFrame* GetReferencedGradientIfNotInUse();
+
+ // Accessors to lookup gradient attributes
+ PRUint16 GetEnumValue(PRUint32 aIndex, nsIContent *aDefault);
+ PRUint16 GetEnumValue(PRUint32 aIndex)
{
- return static_cast(
- GetGradientWithAttr(aAttrName, nsGkAtoms::svgLinearGradientFrame, aDefault));
+ return GetEnumValue(aIndex, mContent);
}
- nsSVGRadialGradientElement* GetRadialGradientWithAttr(nsIAtom *aAttrName, nsIContent *aDefault)
+ PRUint16 GetGradientUnits()
{
- return static_cast(
- GetGradientWithAttr(aAttrName, nsGkAtoms::svgRadialGradientFrame, aDefault));
+ // This getter is called every time the others are called - maybe cache it?
+ return GetEnumValue(nsSVGGradientElement::GRADIENTUNITS);
+ }
+ PRUint16 GetSpreadMethod()
+ {
+ return GetEnumValue(nsSVGGradientElement::SPREADMETHOD);
}
- // Get the value of our gradientUnits attribute
- PRUint16 GetGradientUnits();
+ // Gradient-type-specific lookups since the length values differ between
+ // linear and radial gradients
+ virtual nsSVGLinearGradientElement * GetLinearGradientWithLength(
+ PRUint32 aIndex, nsSVGLinearGradientElement* aDefault);
+ virtual nsSVGRadialGradientElement * GetRadialGradientWithLength(
+ PRUint32 aIndex, nsSVGRadialGradientElement* aDefault);
// The frame our gradient is (currently) being applied to
nsIFrame* mSource;
@@ -178,7 +181,9 @@ public:
#endif // DEBUG
protected:
- float GradientLookupAttribute(nsIAtom *aAtomName, PRUint16 aEnumName);
+ float GetLengthValue(PRUint32 aIndex);
+ virtual nsSVGLinearGradientElement * GetLinearGradientWithLength(
+ PRUint32 aIndex, nsSVGLinearGradientElement* aDefault);
virtual already_AddRefed CreateGradient();
};
@@ -220,8 +225,12 @@ public:
#endif // DEBUG
protected:
- float GradientLookupAttribute(nsIAtom *aAtomName, PRUint16 aEnumName,
- nsSVGRadialGradientElement *aElement = nsnull);
+ float GetLengthValue(PRUint32 aIndex);
+ float GetLengthValue(PRUint32 aIndex, float aDefaultValue);
+ float GetLengthValueFromElement(PRUint32 aIndex,
+ nsSVGRadialGradientElement& aElement);
+ virtual nsSVGRadialGradientElement * GetRadialGradientWithLength(
+ PRUint32 aIndex, nsSVGRadialGradientElement* aDefault);
virtual already_AddRefed CreateGradient();
};