diff --git a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
index 5a947c44039..4e6919c40f5 100644
--- a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
+++ b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
@@ -237,6 +237,7 @@ SVGAnimatedPreserveAspectRatio::SetBaseValueString(
}
mBaseVal = val;
+ mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal = mBaseVal;
}
@@ -281,6 +282,7 @@ SVGAnimatedPreserveAspectRatio::SetBaseAlign(PRUint16 aAlign,
{
nsresult rv = mBaseVal.SetAlign(aAlign);
NS_ENSURE_SUCCESS(rv, rv);
+ mIsBaseSet = PR_TRUE;
mAnimVal.mAlign = mBaseVal.mAlign;
aSVGElement->DidChangePreserveAspectRatio(PR_TRUE);
@@ -299,6 +301,7 @@ SVGAnimatedPreserveAspectRatio::SetBaseMeetOrSlice(PRUint16 aMeetOrSlice,
{
nsresult rv = mBaseVal.SetMeetOrSlice(aMeetOrSlice);
NS_ENSURE_SUCCESS(rv, rv);
+ mIsBaseSet = PR_TRUE;
mAnimVal.mMeetOrSlice = mBaseVal.mMeetOrSlice;
aSVGElement->DidChangePreserveAspectRatio(PR_TRUE);
diff --git a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
index 0d98f820361..f129e79d46c 100644
--- a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
+++ b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
@@ -100,6 +100,7 @@ public:
mBaseVal.mDefer = PR_FALSE;
mAnimVal = mBaseVal;
mIsAnimated = PR_FALSE;
+ mIsBaseSet = PR_FALSE;
}
nsresult SetBaseValueString(const nsAString& aValue,
@@ -117,6 +118,8 @@ public:
{ return mAnimVal; }
PRBool IsAnimated() const
{ return mIsAnimated; }
+ PRBool IsExplicitlySet() const
+ { return mIsAnimated || mIsBaseSet; }
nsresult ToDOMAnimatedPreserveAspectRatio(
nsIDOMSVGAnimatedPreserveAspectRatio **aResult,
@@ -131,6 +134,7 @@ private:
SVGPreserveAspectRatio mAnimVal;
SVGPreserveAspectRatio mBaseVal;
PRPackedBool mIsAnimated;
+ PRPackedBool mIsBaseSet;
nsresult ToDOMBaseVal(nsIDOMSVGPreserveAspectRatio **aResult,
nsSVGElement* aSVGElement);
diff --git a/content/svg/content/src/nsSVGAnimatedTransformList.cpp b/content/svg/content/src/nsSVGAnimatedTransformList.cpp
index 4cfa10bac6b..17976ca2319 100644
--- a/content/svg/content/src/nsSVGAnimatedTransformList.cpp
+++ b/content/svg/content/src/nsSVGAnimatedTransformList.cpp
@@ -136,6 +136,31 @@ nsSVGAnimatedTransformList::DidModifySVGObservable (nsISVGValue* observable,
return NS_OK;
}
+//----------------------------------------------------------------------
+// Misc nsSVGAnimatedTransformList methods
+
+PRBool
+nsSVGAnimatedTransformList::IsExplicitlySet() const
+{
+ // XXX Dummy implementation until bug 602759 is fixed.
+ // Like other methods of this name, we need to know when a transform value has
+ // been explicitly set (either by markup, a DOM call, or animation).
+ // Given our current implementation, we can say that's the case so long as
+ // mBaseVal has something in it or mAnimVal exists.
+ // It's not quite right because, for example, if we have transform="" we
+ // should probably behave as if the value is set, but for now it will do until
+ // bug 602759 is fixed.
+ if (mAnimVal)
+ return PR_TRUE;
+
+ if (!mBaseVal)
+ return PR_FALSE;
+
+ PRUint32 numItems = 0;
+ nsIDOMSVGTransformList *list = mBaseVal.get();
+ list->GetNumberOfItems(&numItems);
+ return numItems > 0;
+}
////////////////////////////////////////////////////////////////////////
// Exported creation functions:
diff --git a/content/svg/content/src/nsSVGAnimatedTransformList.h b/content/svg/content/src/nsSVGAnimatedTransformList.h
index dac8e6d1c03..94ab20e97db 100644
--- a/content/svg/content/src/nsSVGAnimatedTransformList.h
+++ b/content/svg/content/src/nsSVGAnimatedTransformList.h
@@ -80,6 +80,8 @@ public:
// nsISupportsWeakReference
// implementation inherited from nsSupportsWeakReference
+ PRBool IsExplicitlySet() const;
+
protected:
friend class nsSVGTransformSMILAttr;
diff --git a/content/svg/content/src/nsSVGEnum.cpp b/content/svg/content/src/nsSVGEnum.cpp
index 8abfe2a3d3b..dcc49a62e85 100644
--- a/content/svg/content/src/nsSVGEnum.cpp
+++ b/content/svg/content/src/nsSVGEnum.cpp
@@ -79,6 +79,7 @@ nsSVGEnum::SetBaseValueString(const nsAString& aValue,
while (mapping && mapping->mKey) {
if (valAtom == *(mapping->mKey)) {
+ mIsBaseSet = PR_TRUE;
if (mBaseVal != mapping->mVal) {
mBaseVal = mapping->mVal;
if (!mIsAnimated) {
@@ -127,6 +128,7 @@ nsSVGEnum::SetBaseValue(PRUint16 aValue,
while (mapping && mapping->mKey) {
if (mapping->mVal == aValue) {
+ mIsBaseSet = PR_TRUE;
if (mBaseVal != PRUint8(aValue)) {
mBaseVal = PRUint8(aValue);
if (!mIsAnimated) {
diff --git a/content/svg/content/src/nsSVGEnum.h b/content/svg/content/src/nsSVGEnum.h
index 0926a4d8ce6..8c782de425d 100644
--- a/content/svg/content/src/nsSVGEnum.h
+++ b/content/svg/content/src/nsSVGEnum.h
@@ -55,6 +55,7 @@ public:
mAnimVal = mBaseVal = PRUint8(aValue);
mAttrEnum = aAttrEnum;
mIsAnimated = PR_FALSE;
+ mIsBaseSet = PR_FALSE;
}
nsresult SetBaseValueString(const nsAString& aValue,
@@ -72,6 +73,8 @@ public:
void SetAnimValue(PRUint16 aValue, nsSVGElement *aSVGElement);
PRUint16 GetAnimValue() const
{ return mAnimVal; }
+ PRBool IsExplicitlySet() const
+ { return mIsAnimated || mIsBaseSet; }
nsresult ToDOMAnimatedEnum(nsIDOMSVGAnimatedEnumeration **aResult,
nsSVGElement* aSVGElement);
@@ -85,6 +88,7 @@ private:
nsSVGEnumValue mBaseVal;
PRUint8 mAttrEnum; // element specified tracking for attribute
PRPackedBool mIsAnimated;
+ PRPackedBool mIsBaseSet;
nsSVGEnumMapping *GetMapping(nsSVGElement *aSVGElement);
diff --git a/content/svg/content/src/nsSVGLength2.h b/content/svg/content/src/nsSVGLength2.h
index 2c43d10c380..c6bd8963ae3 100644
--- a/content/svg/content/src/nsSVGLength2.h
+++ b/content/svg/content/src/nsSVGLength2.h
@@ -97,7 +97,7 @@ public:
// explicitly set by markup or a DOM call), PR_FALSE otherwise.
// If this returns PR_FALSE, the animated value is still valid, that is,
// useable, and represents the default base value of the attribute.
- PRBool IsAnimValSet() const
+ PRBool IsExplicitlySet() const
{ return mIsAnimated || mIsBaseSet; }
nsresult ToDOMAnimatedLength(nsIDOMSVGAnimatedLength **aResult,
diff --git a/content/svg/content/src/nsSVGRectElement.cpp b/content/svg/content/src/nsSVGRectElement.cpp
index 6fb3c8e94ad..42fdec36f0a 100644
--- a/content/svg/content/src/nsSVGRectElement.cpp
+++ b/content/svg/content/src/nsSVGRectElement.cpp
@@ -192,8 +192,8 @@ nsSVGRectElement::ConstructPath(gfxContext *aCtx)
/* If either the 'rx' or the 'ry' attribute isn't set, then we
have to set it to the value of the other. */
- PRBool hasRx = mLengthAttributes[RX].IsAnimValSet();
- PRBool hasRy = mLengthAttributes[RY].IsAnimValSet();
+ PRBool hasRx = mLengthAttributes[RX].IsExplicitlySet();
+ PRBool hasRy = mLengthAttributes[RY].IsExplicitlySet();
if (hasRx && !hasRy)
ry = rx;
else if (hasRy && !hasRx)
diff --git a/layout/reftests/svg/smil/anim-pattern-attr-presence-01-ref.svg b/layout/reftests/svg/smil/anim-pattern-attr-presence-01-ref.svg
new file mode 100644
index 00000000000..ddb0ffe4547
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-pattern-attr-presence-01-ref.svg
@@ -0,0 +1,103 @@
+
diff --git a/layout/reftests/svg/smil/anim-pattern-attr-presence-01.svg b/layout/reftests/svg/smil/anim-pattern-attr-presence-01.svg
new file mode 100644
index 00000000000..b33a58fa271
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-pattern-attr-presence-01.svg
@@ -0,0 +1,138 @@
+
diff --git a/layout/reftests/svg/smil/anim-pattern-attr-presence-02-ref.svg b/layout/reftests/svg/smil/anim-pattern-attr-presence-02-ref.svg
new file mode 100644
index 00000000000..cfe0027d5f1
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-pattern-attr-presence-02-ref.svg
@@ -0,0 +1,35 @@
+
diff --git a/layout/reftests/svg/smil/anim-pattern-attr-presence-02.svg b/layout/reftests/svg/smil/anim-pattern-attr-presence-02.svg
new file mode 100644
index 00000000000..e0d2e35dfff
--- /dev/null
+++ b/layout/reftests/svg/smil/anim-pattern-attr-presence-02.svg
@@ -0,0 +1,52 @@
+
diff --git a/layout/reftests/svg/smil/reftest.list b/layout/reftests/svg/smil/reftest.list
index 618101892a6..b2d9f3f991a 100644
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -197,7 +197,11 @@ random == anim-text-x-y-dx-dy-01.svg anim-text-x-y-dx-dy-01-ref.svg # bug 579588
== anim-y-interp-5.svg anim-y-interp-5-ref.svg
== anim-y-interp-6.svg anim-y-interp-6-ref.svg
+# Test we don't rely on HasAttr to see if an attribute has been set
== anim-rect-rxry-1.svg anim-rect-rxry-1-ref.svg
+== 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
== api-sanity-1.svg lime.svg
diff --git a/layout/svg/base/src/nsSVGPatternFrame.cpp b/layout/svg/base/src/nsSVGPatternFrame.cpp
index 9bffc01fde5..f443783d638 100644
--- a/layout/svg/base/src/nsSVGPatternFrame.cpp
+++ b/layout/svg/base/src/nsSVGPatternFrame.cpp
@@ -51,6 +51,7 @@
#include "nsSVGPatternElement.h"
#include "nsSVGGeometryFrame.h"
#include "nsSVGPatternFrame.h"
+#include "nsSVGAnimatedTransformList.h"
#include "gfxContext.h"
#include "gfxPlatform.h"
#include "gfxPattern.h"
@@ -58,6 +59,27 @@
using namespace mozilla;
+//----------------------------------------------------------------------
+// Helper classes
+
+class nsSVGPatternFrame::AutoPatternReferencer
+{
+public:
+ AutoPatternReferencer(nsSVGPatternFrame *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 = PR_TRUE;
+ }
+ ~AutoPatternReferencer() {
+ mFrame->mLoopFlag = PR_FALSE;
+ }
+private:
+ nsSVGPatternFrame *mFrame;
+};
+
//----------------------------------------------------------------------
// Implementation
@@ -331,48 +353,64 @@ nsSVGPatternFrame::GetPatternFirstChild(nsIFrame **kid)
return NS_OK;
// No, see if we chain to someone who does
- nsSVGPatternFrame *next = GetReferencedPattern();
+ AutoPatternReferencer patternRef(this);
- mLoopFlag = PR_TRUE;
- if (!next || next->mLoopFlag) {
- mLoopFlag = PR_FALSE;
+ nsSVGPatternFrame *next = GetReferencedPatternIfNotInUse();
+ if (!next)
return NS_ERROR_FAILURE;
- }
- nsresult rv = next->GetPatternFirstChild(kid);
- mLoopFlag = PR_FALSE;
- return rv;
+ return next->GetPatternFirstChild(kid);
}
PRUint16
-nsSVGPatternFrame::GetPatternUnits()
+nsSVGPatternFrame::GetEnumValue(PRUint32 aIndex, nsIContent *aDefault)
{
- // See if we need to get the value from another pattern
- nsSVGPatternElement *patternElement =
- GetPatternWithAttr(nsGkAtoms::patternUnits, mContent);
- return patternElement->mEnumAttributes[nsSVGPatternElement::PATTERNUNITS].GetAnimValue();
+ nsSVGEnum& thisEnum =
+ static_cast(mContent)->mEnumAttributes[aIndex];
+
+ if (thisEnum.IsExplicitlySet())
+ return thisEnum.GetAnimValue();
+
+ AutoPatternReferencer patternRef(this);
+
+ nsSVGPatternFrame *next = GetReferencedPatternIfNotInUse();
+ return next ? next->GetEnumValue(aIndex, aDefault) :
+ static_cast(aDefault)->
+ mEnumAttributes[aIndex].GetAnimValue();
}
-PRUint16
-nsSVGPatternFrame::GetPatternContentUnits()
+nsIDOMSVGAnimatedTransformList*
+nsSVGPatternFrame::GetPatternTransformList(nsIContent* aDefault)
{
- nsSVGPatternElement *patternElement =
- GetPatternWithAttr(nsGkAtoms::patternContentUnits, mContent);
- return patternElement->mEnumAttributes[nsSVGPatternElement::PATTERNCONTENTUNITS].GetAnimValue();
+ nsIDOMSVGAnimatedTransformList *thisTransformList =
+ static_cast(mContent)->mPatternTransform.get();
+
+ // XXX We should be able to do something cleaner than this casting once
+ // bug 602759 is fixed and we have a proper animated transform list class
+ const nsSVGAnimatedTransformList *thisListAsConcreteType =
+ static_cast(thisTransformList);
+ if (thisListAsConcreteType && thisListAsConcreteType->IsExplicitlySet())
+ return thisTransformList;
+
+ AutoPatternReferencer patternRef(this);
+
+ nsSVGPatternFrame *next = GetReferencedPatternIfNotInUse();
+ return next ? next->GetPatternTransformList(aDefault) :
+ static_cast(aDefault)->mPatternTransform.get();
}
gfxMatrix
nsSVGPatternFrame::GetPatternTransform()
{
- nsSVGPatternElement *patternElement =
- GetPatternWithAttr(nsGkAtoms::patternTransform, mContent);
+ nsIDOMSVGAnimatedTransformList* transformList =
+ GetPatternTransformList(mContent);
static const gfxMatrix identityMatrix;
- if (!patternElement->mPatternTransform) {
+ if (!transformList) {
return identityMatrix;
}
nsCOMPtr lTrans;
- patternElement->mPatternTransform->GetAnimVal(getter_AddRefs(lTrans));
+ transformList->GetAnimVal(getter_AddRefs(lTrans));
nsCOMPtr patternTransform =
nsSVGTransformList::GetConsolidationMatrix(lTrans);
if (!patternTransform) {
@@ -382,49 +420,51 @@ nsSVGPatternFrame::GetPatternTransform()
}
const nsSVGViewBox &
-nsSVGPatternFrame::GetViewBox()
+nsSVGPatternFrame::GetViewBox(nsIContent* aDefault)
{
- nsSVGPatternElement *patternElement =
- GetPatternWithAttr(nsGkAtoms::viewBox, mContent);
+ const nsSVGViewBox &thisViewBox =
+ static_cast(mContent)->mViewBox;
- return patternElement->mViewBox;
+ if (thisViewBox.IsValid())
+ return thisViewBox;
+
+ AutoPatternReferencer patternRef(this);
+
+ nsSVGPatternFrame *next = GetReferencedPatternIfNotInUse();
+ return next ? next->GetViewBox(aDefault) :
+ static_cast(aDefault)->mViewBox;
}
const SVGAnimatedPreserveAspectRatio &
-nsSVGPatternFrame::GetPreserveAspectRatio()
+nsSVGPatternFrame::GetPreserveAspectRatio(nsIContent *aDefault)
{
- nsSVGPatternElement *patternElement =
- GetPatternWithAttr(nsGkAtoms::preserveAspectRatio, mContent);
+ const SVGAnimatedPreserveAspectRatio &thisPar =
+ static_cast(mContent)->mPreserveAspectRatio;
- return patternElement->mPreserveAspectRatio;
+ if (thisPar.IsExplicitlySet())
+ return thisPar;
+
+ AutoPatternReferencer patternRef(this);
+
+ nsSVGPatternFrame *next = GetReferencedPatternIfNotInUse();
+ return next ? next->GetPreserveAspectRatio(aDefault) :
+ static_cast(aDefault)->mPreserveAspectRatio;
}
const nsSVGLength2 *
-nsSVGPatternFrame::GetX()
+nsSVGPatternFrame::GetLengthValue(PRUint32 aIndex, nsIContent *aDefault)
{
- nsSVGPatternElement *pattern = GetPatternWithAttr(nsGkAtoms::x, mContent);
- return &pattern->mLengthAttributes[nsSVGPatternElement::X];
-}
+ const nsSVGLength2 *thisLength =
+ &static_cast(mContent)->mLengthAttributes[aIndex];
-const nsSVGLength2 *
-nsSVGPatternFrame::GetY()
-{
- nsSVGPatternElement *pattern = GetPatternWithAttr(nsGkAtoms::y, mContent);
- return &pattern->mLengthAttributes[nsSVGPatternElement::Y];
-}
+ if (thisLength->IsExplicitlySet())
+ return thisLength;
-const nsSVGLength2 *
-nsSVGPatternFrame::GetWidth()
-{
- nsSVGPatternElement *pattern = GetPatternWithAttr(nsGkAtoms::width, mContent);
- return &pattern->mLengthAttributes[nsSVGPatternElement::WIDTH];
-}
+ AutoPatternReferencer patternRef(this);
-const nsSVGLength2 *
-nsSVGPatternFrame::GetHeight()
-{
- nsSVGPatternElement *pattern = GetPatternWithAttr(nsGkAtoms::height, mContent);
- return &pattern->mLengthAttributes[nsSVGPatternElement::HEIGHT];
+ nsSVGPatternFrame *next = GetReferencedPatternIfNotInUse();
+ return next ? next->GetLengthValue(aIndex, aDefault) :
+ &static_cast(aDefault)->mLengthAttributes[aIndex];
}
// Private (helper) methods
@@ -470,33 +510,20 @@ nsSVGPatternFrame::GetReferencedPattern()
return static_cast(result);
}
-nsSVGPatternElement *
-nsSVGPatternFrame::GetPatternWithAttr(nsIAtom *aAttrName, nsIContent *aDefault)
+nsSVGPatternFrame *
+nsSVGPatternFrame::GetReferencedPatternIfNotInUse()
{
- // XXX TODO: this method needs to take account of SMIL animation, since it
- // the requested attribute may be animated even if it is not set in the DOM.
- // The callers also need to be fixed up to then ask for the right thing from
- // the pattern we return! Do we neet to call mContent->FlushAnimations()?
+ nsSVGPatternFrame *referenced = GetReferencedPattern();
+ if (!referenced)
+ return nsnull;
- if (mContent->HasAttr(kNameSpaceID_None, aAttrName))
- return static_cast(mContent);
+ if (referenced->mLoopFlag) {
+ // XXXjwatt: we should really send an error to the JavaScript Console here:
+ NS_WARNING("pattern reference loop detected while inheriting attribute!");
+ return nsnull;
+ }
- nsSVGPatternElement *pattern = static_cast(aDefault);
-
- nsSVGPatternFrame *next = GetReferencedPattern();
- if (!next)
- return pattern;
-
- // Set mLoopFlag before checking mNextGrad->mLoopFlag in case we are mNextGrad
- mLoopFlag = PR_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)
- pattern = next->GetPatternWithAttr(aAttrName, aDefault);
- mLoopFlag = PR_FALSE;
-
- return pattern;
+ return referenced;
}
// -------------------------------------------------------------------------
@@ -509,17 +536,17 @@ nsSVGPatternFrame::GetPatternRect(const gfxRect &aTargetBBox,
nsIFrame *aTarget)
{
// Get our type
- PRUint16 type = GetPatternUnits();
+ PRUint16 type = GetEnumValue(nsSVGPatternElement::PATTERNUNITS);
// We need to initialize our box
float x,y,width,height;
// Get the pattern x,y,width, and height
const nsSVGLength2 *tmpX, *tmpY, *tmpHeight, *tmpWidth;
- tmpX = GetX();
- tmpY = GetY();
- tmpHeight = GetHeight();
- tmpWidth = GetWidth();
+ tmpX = GetLengthValue(nsSVGPatternElement::X);
+ tmpY = GetLengthValue(nsSVGPatternElement::Y);
+ tmpHeight = GetLengthValue(nsSVGPatternElement::HEIGHT);
+ tmpWidth = GetLengthValue(nsSVGPatternElement::WIDTH);
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
x = nsSVGUtils::ObjectSpace(aTargetBBox, tmpX);
@@ -547,7 +574,7 @@ nsSVGPatternFrame::ConstructCTM(const gfxRect &callerBBox,
nsIContent* targetContent = aTarget->GetContent();
// The objectBoundingBox conversion must be handled in the CTM:
- if (GetPatternContentUnits() ==
+ if (GetEnumValue(nsSVGPatternElement::PATTERNCONTENTUNITS) ==
nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
tCTM.Scale(callerBBox.Width(), callerBBox.Height());
} else {
@@ -569,16 +596,20 @@ nsSVGPatternFrame::ConstructCTM(const gfxRect &callerBBox,
// If we're dealing with an SVG target only retrieve the context once.
// Calling the nsIFrame* variant of GetAnimValue would look it up on
// every call.
- viewportWidth = GetWidth()->GetAnimValue(ctx);
- viewportHeight = GetHeight()->GetAnimValue(ctx);
- refX = GetX()->GetAnimValue(ctx);
- refY = GetY()->GetAnimValue(ctx);
+ viewportWidth =
+ GetLengthValue(nsSVGPatternElement::WIDTH)->GetAnimValue(ctx);
+ viewportHeight =
+ GetLengthValue(nsSVGPatternElement::HEIGHT)->GetAnimValue(ctx);
+ refX = GetLengthValue(nsSVGPatternElement::X)->GetAnimValue(ctx);
+ refY = GetLengthValue(nsSVGPatternElement::Y)->GetAnimValue(ctx);
} else {
// No SVG target, call the nsIFrame* variant of GetAnimValue.
- viewportWidth = GetWidth()->GetAnimValue(aTarget);
- viewportHeight = GetHeight()->GetAnimValue(aTarget);
- refX = GetX()->GetAnimValue(aTarget);
- refY = GetY()->GetAnimValue(aTarget);
+ viewportWidth =
+ GetLengthValue(nsSVGPatternElement::WIDTH)->GetAnimValue(aTarget);
+ viewportHeight =
+ GetLengthValue(nsSVGPatternElement::HEIGHT)->GetAnimValue(aTarget);
+ refX = GetLengthValue(nsSVGPatternElement::X)->GetAnimValue(aTarget);
+ refY = GetLengthValue(nsSVGPatternElement::Y)->GetAnimValue(aTarget);
}
gfxMatrix viewBoxTM = nsSVGUtils::GetViewBoxTransform(patternElement,
viewportWidth, viewportHeight,
@@ -605,7 +636,7 @@ nsSVGPatternFrame::GetPatternMatrix(const gfxRect &bbox,
float minx = bbox.X();
float miny = bbox.Y();
- PRUint16 type = GetPatternContentUnits();
+ PRUint16 type = GetEnumValue(nsSVGPatternElement::PATTERNCONTENTUNITS);
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
minx += callerBBox.X();
miny += callerBBox.Y();
@@ -627,7 +658,7 @@ nsSVGPatternFrame::GetTargetGeometry(gfxMatrix *aCTM,
*aBBox = aOverrideBounds ? *aOverrideBounds : nsSVGUtils::GetBBox(aTarget);
// Sanity check
- PRUint16 type = GetPatternUnits();
+ PRUint16 type = GetEnumValue(nsSVGPatternElement::PATTERNUNITS);
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
if (aBBox->Width() <= 0 || aBBox->Height() <= 0) {
return NS_ERROR_FAILURE;
diff --git a/layout/svg/base/src/nsSVGPatternFrame.h b/layout/svg/base/src/nsSVGPatternFrame.h
index 742ce101e0b..4a2606c0c19 100644
--- a/layout/svg/base/src/nsSVGPatternFrame.h
+++ b/layout/svg/base/src/nsSVGPatternFrame.h
@@ -110,25 +110,31 @@ public:
protected:
// Internal methods for handling referenced patterns
+ class AutoPatternReferencer;
nsSVGPatternFrame* GetReferencedPattern();
- // Helper to look at our pattern and then along its reference chain (if any)
- // to find the first pattern with the specified attribute. Returns
- // null if there isn't one.
- nsSVGPatternElement* GetPatternWithAttr(nsIAtom *aAttrName, nsIContent *aDefault);
+ nsSVGPatternFrame* GetReferencedPatternIfNotInUse();
- //
- const nsSVGLength2 *GetX();
- const nsSVGLength2 *GetY();
- const nsSVGLength2 *GetWidth();
- const nsSVGLength2 *GetHeight();
-
- PRUint16 GetPatternUnits();
- PRUint16 GetPatternContentUnits();
+ // Accessors to lookup pattern attributes
+ PRUint16 GetEnumValue(PRUint32 aIndex, nsIContent *aDefault);
+ PRUint16 GetEnumValue(PRUint32 aIndex)
+ {
+ return GetEnumValue(aIndex, mContent);
+ }
+ nsIDOMSVGAnimatedTransformList* GetPatternTransformList(nsIContent* aDefault);
gfxMatrix GetPatternTransform();
-
- const nsSVGViewBox &GetViewBox();
- const SVGAnimatedPreserveAspectRatio &GetPreserveAspectRatio();
-
+ const nsSVGViewBox &GetViewBox(nsIContent *aDefault);
+ const nsSVGViewBox &GetViewBox() { return GetViewBox(mContent); }
+ const SVGAnimatedPreserveAspectRatio &GetPreserveAspectRatio(
+ nsIContent *aDefault);
+ const SVGAnimatedPreserveAspectRatio &GetPreserveAspectRatio()
+ {
+ return GetPreserveAspectRatio(mContent);
+ }
+ const nsSVGLength2 *GetLengthValue(PRUint32 aIndex, nsIContent *aDefault);
+ const nsSVGLength2 *GetLengthValue(PRUint32 aIndex)
+ {
+ return GetLengthValue(aIndex, mContent);
+ }
nsresult PaintPattern(gfxASurface **surface,
gfxMatrix *patternMatrix,