Bug 730658 - use element does not display properly when animated with set. r=dholbert

This commit is contained in:
Robert Longson 2012-02-28 14:54:33 +00:00
parent 204efe6b21
commit d3e65e2f49
39 changed files with 300 additions and 60 deletions

View File

@ -392,9 +392,9 @@ void
SMILPreserveAspectRatio::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(PackPreserveAspectRatio(mVal->GetBaseValue()),
mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal = mVal->mBaseVal;
mSVGElement->DidAnimatePreserveAspectRatio();
}
}

View File

@ -510,8 +510,10 @@ nsSVGAngle::SMILOrient::ClearAnimValue()
{
if (mAngle->mIsAnimated) {
mOrientType->SetAnimValue(mOrientType->GetBaseValue());
mAngle->SetAnimValue(mAngle->mBaseVal, mAngle->mBaseValUnit, mSVGElement);
mAngle->mIsAnimated = false;
mAngle->mAnimVal = mAngle->mBaseVal;
mAngle->mAnimValUnit = mAngle->mBaseValUnit;
mSVGElement->DidAnimateAngle(mAngle->mAttrEnum);
}
}

View File

@ -190,8 +190,9 @@ void
nsSVGBoolean::SMILBool::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal = mVal->mBaseVal;
mSVGElement->DidAnimateBoolean(mVal->mAttrEnum);
}
}

View File

@ -67,6 +67,9 @@ public:
NS_FORWARD_NSIDOMELEMENT(nsSVGCircleElementBase::)
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGCircleElementBase::)
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
// nsSVGPathGeometryElement methods:
virtual void ConstructPath(gfxContext *aCtx);
@ -143,6 +146,13 @@ NS_IMETHODIMP nsSVGCircleElement::GetR(nsIDOMSVGAnimatedLength * *aR)
//----------------------------------------------------------------------
// nsSVGElement methods
/* virtual */ bool
nsSVGCircleElement::HasValidDimensions() const
{
return mLengthAttributes[R].IsExplicitlySet() &&
mLengthAttributes[R].GetAnimValInSpecifiedUnits() > 0;
}
nsSVGElement::LengthAttributesInfo
nsSVGCircleElement::GetLengthInfo()
{

View File

@ -195,6 +195,9 @@ public:
bool NumberAttrAllowsPercentage(PRUint8 aAttrEnum) {
return GetNumberInfo().mNumberInfo[aAttrEnum].mPercentagesAllowed;
}
virtual bool HasValidDimensions() const {
return true;
}
void SetLength(nsIAtom* aName, const nsSVGLength2 &aLength);
nsAttrValue WillChangeLength(PRUint8 aAttrEnum);

View File

@ -68,6 +68,9 @@ public:
NS_FORWARD_NSIDOMELEMENT(nsSVGEllipseElementBase::)
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGEllipseElementBase::)
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
// nsSVGPathGeometryElement methods:
virtual void ConstructPath(gfxContext *aCtx);
@ -151,6 +154,15 @@ NS_IMETHODIMP nsSVGEllipseElement::GetRy(nsIDOMSVGAnimatedLength * *aRy)
//----------------------------------------------------------------------
// nsSVGElement methods
/* virtual */ bool
nsSVGEllipseElement::HasValidDimensions() const
{
return mLengthAttributes[RX].IsExplicitlySet() &&
mLengthAttributes[RX].GetAnimValInSpecifiedUnits() > 0 &&
mLengthAttributes[RY].IsExplicitlySet() &&
mLengthAttributes[RY].GetAnimValInSpecifiedUnits() > 0;
}
nsSVGElement::LengthAttributesInfo
nsSVGEllipseElement::GetLengthInfo()
{

View File

@ -200,8 +200,9 @@ void
nsSVGEnum::SMILEnum::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal = mVal->mBaseVal;
mSVGElement->DidAnimateEnum(mVal->mAttrEnum);
}
}

View File

@ -219,6 +219,15 @@ nsSVGFilterElement::Invalidate()
//----------------------------------------------------------------------
// nsSVGElement methods
/* virtual */ bool
nsSVGFilterElement::HasValidDimensions() const
{
return (!mLengthAttributes[WIDTH].IsExplicitlySet() ||
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[HEIGHT].IsExplicitlySet() ||
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0);
}
nsSVGElement::LengthAttributesInfo
nsSVGFilterElement::GetLengthInfo()
{

View File

@ -83,6 +83,9 @@ public:
void Invalidate();
virtual nsXPCClassInfo* GetClassInfo();
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
protected:
virtual LengthAttributesInfo GetLengthInfo();

View File

@ -310,6 +310,15 @@ nsSVGFE::IsAttributeMapped(const nsIAtom* name) const
//----------------------------------------------------------------------
// nsSVGElement methods
/* virtual */ bool
nsSVGFE::HasValidDimensions() const
{
return (!mLengthAttributes[WIDTH].IsExplicitlySet() ||
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[HEIGHT].IsExplicitlySet() ||
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0);
}
nsSVGElement::LengthAttributesInfo
nsSVGFE::GetLengthInfo()
{

View File

@ -158,6 +158,9 @@ public:
// nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
// nsSVGElement interface
virtual bool HasValidDimensions() const;
virtual nsSVGString& GetResultImageName() = 0;
// Return a list of all image names used as sources. Default is to
// return no sources.

View File

@ -136,6 +136,15 @@ nsSVGForeignObjectElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
return toUserSpace * fromUserSpace;
}
/* virtual */ bool
nsSVGForeignObjectElement::HasValidDimensions() const
{
return mLengthAttributes[WIDTH].IsExplicitlySet() &&
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
mLengthAttributes[HEIGHT].IsExplicitlySet() &&
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0;
}
//----------------------------------------------------------------------
// nsIContent methods

View File

@ -71,6 +71,7 @@ public:
// nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
virtual bool HasValidDimensions() const;
// nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;

View File

@ -267,6 +267,15 @@ nsSVGImageElement::ConstructPath(gfxContext *aCtx)
//----------------------------------------------------------------------
// nsSVGElement methods
/* virtual */ bool
nsSVGImageElement::HasValidDimensions() const
{
return mLengthAttributes[WIDTH].IsExplicitlySet() &&
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
mLengthAttributes[HEIGHT].IsExplicitlySet() &&
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0;
}
nsSVGElement::LengthAttributesInfo
nsSVGImageElement::GetLengthInfo()
{

View File

@ -90,6 +90,9 @@ public:
// nsSVGPathGeometryElement methods:
virtual void ConstructPath(gfxContext *aCtx);
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
nsresult CopyInnerTo(nsGenericElement* aDest) const;

View File

@ -185,8 +185,9 @@ void
nsSVGInteger::SMILInteger::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal = mVal->mBaseVal;
mSVGElement->DidAnimateInteger(mVal->mAttrEnum);
}
}

View File

@ -241,8 +241,10 @@ void
nsSVGIntegerPair::SMILIntegerPair::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal[0] = mVal->mBaseVal[0];
mVal->mAnimVal[1] = mVal->mBaseVal[1];
mSVGElement->DidAnimateIntegerPair(mVal->mAttrEnum);
}
}

View File

@ -570,8 +570,9 @@ void
nsSVGLength2::SMILLength::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValueInSpecifiedUnits(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal = mVal->mBaseVal;
mSVGElement->DidAnimateLength(mVal->mAttrEnum);
}
}

View File

@ -306,6 +306,15 @@ nsSVGMarkerElement::SetParentCoordCtxProvider(nsSVGSVGElement *aContext)
mViewBoxToViewportTransform = nsnull;
}
/* virtual */ bool
nsSVGMarkerElement::HasValidDimensions() const
{
return (!mLengthAttributes[MARKERWIDTH].IsExplicitlySet() ||
mLengthAttributes[MARKERWIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[MARKERHEIGHT].IsExplicitlySet() ||
mLengthAttributes[MARKERHEIGHT].GetAnimValInSpecifiedUnits() > 0);
}
nsSVGElement::LengthAttributesInfo
nsSVGMarkerElement::GetLengthInfo()
{

View File

@ -133,6 +133,9 @@ public:
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
bool aNotify);
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
// public helpers
gfxMatrix GetMarkerTransform(float aStrokeWidth,
float aX, float aY, float aAutoAngle);

View File

@ -136,6 +136,15 @@ NS_IMETHODIMP nsSVGMaskElement::GetHeight(nsIDOMSVGAnimatedLength * *aHeight)
//----------------------------------------------------------------------
// nsSVGElement methods
/* virtual */ bool
nsSVGMaskElement::HasValidDimensions() const
{
return (!mLengthAttributes[WIDTH].IsExplicitlySet() ||
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[HEIGHT].IsExplicitlySet() ||
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0);
}
nsSVGElement::LengthAttributesInfo
nsSVGMaskElement::GetLengthInfo()
{

View File

@ -76,6 +76,9 @@ public:
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsXPCClassInfo* GetClassInfo();
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
protected:
virtual LengthAttributesInfo GetLengthInfo();

View File

@ -227,8 +227,9 @@ void
nsSVGNumber2::SMILNumber::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal = mVal->mBaseVal;
mSVGElement->DidAnimateNumber(mVal->mAttrEnum);
}
}

View File

@ -239,8 +239,10 @@ void
nsSVGNumberPair::SMILNumberPair::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = false;
mVal->mAnimVal[0] = mVal->mBaseVal[0];
mVal->mAnimVal[1] = mVal->mBaseVal[1];
mSVGElement->DidAnimateNumberPair(mVal->mAttrEnum);
}
}

View File

@ -214,6 +214,15 @@ nsSVGPatternElement::GetAnimatedTransformList()
return mPatternTransform;
}
/* virtual */ bool
nsSVGPatternElement::HasValidDimensions() const
{
return mLengthAttributes[WIDTH].IsExplicitlySet() &&
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
mLengthAttributes[HEIGHT].IsExplicitlySet() &&
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0;
}
nsSVGElement::LengthAttributesInfo
nsSVGPatternElement::GetLengthInfo()
{

View File

@ -96,6 +96,9 @@ public:
virtual nsXPCClassInfo* GetClassInfo();
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
virtual mozilla::SVGAnimatedTransformList* GetAnimatedTransformList();
virtual nsIAtom* GetTransformListAttrName() const {
return nsGkAtoms::patternTransform;

View File

@ -67,6 +67,9 @@ public:
NS_FORWARD_NSIDOMELEMENT(nsSVGRectElementBase::)
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGRectElementBase::)
// nsSVGSVGElement methods:
virtual bool HasValidDimensions() const;
// nsSVGPathGeometryElement methods:
virtual void ConstructPath(gfxContext *aCtx);
@ -164,6 +167,15 @@ NS_IMETHODIMP nsSVGRectElement::GetRy(nsIDOMSVGAnimatedLength * *aRy)
//----------------------------------------------------------------------
// nsSVGElement methods
/* virtual */ bool
nsSVGRectElement::HasValidDimensions() const
{
return mLengthAttributes[WIDTH].IsExplicitlySet() &&
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
mLengthAttributes[HEIGHT].IsExplicitlySet() &&
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0;
}
nsSVGElement::LengthAttributesInfo
nsSVGRectElement::GetLengthInfo()
{

View File

@ -1189,6 +1189,16 @@ nsSVGSVGElement::GetLength(PRUint8 aCtxType)
return 0;
}
void
nsSVGSVGElement::SyncWidthOrHeight(nsIAtom* aName, nsSVGElement *aTarget) const
{
NS_ASSERTION(aName == nsGkAtoms::width || aName == nsGkAtoms::height,
"The clue is in the function name");
PRUint32 index = *sLengthInfo[WIDTH].mName == aName ? WIDTH : HEIGHT;
aTarget->SetLength(aName, mLengthAttributes[index]);
}
//----------------------------------------------------------------------
// nsSVGElement methods
@ -1229,6 +1239,16 @@ nsSVGSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
return GetViewBoxTransform() * aMatrix;
}
/* virtual */ bool
nsSVGSVGElement::HasValidDimensions() const
{
return !IsInner() ||
((!mLengthAttributes[WIDTH].IsExplicitlySet() ||
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[HEIGHT].IsExplicitlySet() ||
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0));
}
nsSVGElement::LengthAttributesInfo
nsSVGSVGElement::GetLengthInfo()
{

View File

@ -188,9 +188,12 @@ public:
// nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
virtual bool HasValidDimensions() const;
// nsSVGSVGElement methods:
float GetLength(PRUint8 mCtxType);
// Copy our width or height to the target
void SyncWidthOrHeight(nsIAtom* aName, nsSVGElement *aTarget) const;
// public helpers:
gfxMatrix GetViewBoxTransform() const;

View File

@ -40,7 +40,7 @@
#include "nsIDOMSVGGElement.h"
#include "nsGkAtoms.h"
#include "nsIDOMDocument.h"
#include "nsIDOMSVGSVGElement.h"
#include "nsSVGSVGElement.h"
#include "nsIDOMSVGSymbolElement.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
@ -288,10 +288,6 @@ nsSVGUseElement::CreateAnonymousContent()
tag != nsGkAtoms::use)
return nsnull;
// Make sure the use attributes are valid
if (!HasValidDimensions())
return nsnull;
// circular loop detection
// check 1 - check if we're a document descendent of the target
@ -299,8 +295,8 @@ nsSVGUseElement::CreateAnonymousContent()
return nsnull;
// check 2 - check if we're a clone, and if we already exist in the hierarchy
if (this->GetParent() && mOriginal) {
for (nsCOMPtr<nsIContent> content = this->GetParent();
if (GetParent() && mOriginal) {
for (nsCOMPtr<nsIContent> content = GetParent();
content;
content = content->GetParent()) {
nsCOMPtr<nsIDOMSVGUseElement> useElement = do_QueryInterface(content);
@ -407,43 +403,43 @@ nsSVGUseElement::DestroyAnonymousContent()
//----------------------------------------------------------------------
// implementation helpers
bool nsSVGUseElement::HasValidDimensions()
{
nsSVGSVGElement *ctx = GetCtx();
return (!mLengthAttributes[WIDTH].IsExplicitlySet() ||
mLengthAttributes[WIDTH].GetAnimValue(ctx) > 0) &&
(!mLengthAttributes[HEIGHT].IsExplicitlySet() ||
mLengthAttributes[HEIGHT].GetAnimValue(ctx) > 0);
}
void
nsSVGUseElement::SyncWidthHeight(nsIAtom* aName)
nsSVGUseElement::SyncWidthOrHeight(nsIAtom* aName)
{
NS_ASSERTION(aName == nsGkAtoms::width || aName == nsGkAtoms::height,
"The clue is in the function name");
if (HasValidDimensions() == !mClone) {
TriggerReclone();
if (!mClone) {
return;
}
if (mClone) {
nsCOMPtr<nsIDOMSVGSymbolElement> symbol = do_QueryInterface(mClone);
nsCOMPtr<nsIDOMSVGSVGElement> svg = do_QueryInterface(mClone);
nsCOMPtr<nsIDOMSVGSymbolElement> symbol = do_QueryInterface(mClone);
nsCOMPtr<nsIDOMSVGSVGElement> svg = do_QueryInterface(mClone);
if (symbol || svg) {
PRUint32 index = *sLengthInfo[WIDTH].mName == aName ? WIDTH : HEIGHT;
if (mLengthAttributes[index].IsExplicitlySet()) {
static_cast<nsSVGElement*>(mClone.get())->
SetLength(aName, mLengthAttributes[index]);
} else {
// Our width/height attribute is now no longer explicitly set, so we
// need to revert the clone's width/height to the width/height of the
// content that's being cloned.
TriggerReclone();
}
if (symbol || svg) {
nsSVGElement *target = static_cast<nsSVGElement*>(mClone.get());
PRUint32 index = *sLengthInfo[WIDTH].mName == aName ? WIDTH : HEIGHT;
if (mLengthAttributes[index].IsExplicitlySet()) {
target->SetLength(aName, mLengthAttributes[index]);
return;
}
if (svg) {
// Our width/height attribute is now no longer explicitly set, so we
// need to revert the clone's width/height to the width/height of the
// content that's being cloned.
nsSVGSVGElement* svgElement =
static_cast<nsSVGSVGElement*>(mSource.get());
svgElement->SyncWidthOrHeight(aName, target);
return;
}
// Our width/height attribute is now no longer explicitly set, so we
// need to set the value to 100%
nsSVGLength2 length;
length.Init(nsSVGUtils::XY, 0xff,
100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE);
target->SetLength(aName, length);
return;
}
}
@ -511,6 +507,15 @@ nsSVGUseElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
return toUserSpace * fromUserSpace;
}
/* virtual */ bool
nsSVGUseElement::HasValidDimensions() const
{
return (!mLengthAttributes[WIDTH].IsExplicitlySet() ||
mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[HEIGHT].IsExplicitlySet() ||
mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0);
}
nsSVGElement::LengthAttributesInfo
nsSVGUseElement::GetLengthInfo()
{

View File

@ -105,6 +105,7 @@ public:
// nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
virtual bool HasValidDimensions() const;
// nsIContent interface
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@ -130,8 +131,7 @@ protected:
virtual LengthAttributesInfo GetLengthInfo();
virtual StringAttributesInfo GetStringInfo();
bool HasValidDimensions();
void SyncWidthHeight(nsIAtom *aName);
void SyncWidthOrHeight(nsIAtom *aName);
void LookupHref();
void TriggerReclone();
void UnlinkSource();

View File

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Test that a rect with no width/height does not display even with a filter</title>
<rect width="100%" height="100%" fill="lime"/>
<filter id="filter" filterUnits="userSpaceOnUse"
x="0" y="0" width="100%" height="100%">
<!-- data: URI is a 1x1 red GIF -->
<feImage preserveAspectRatio="xMidYMid slice"
style="image-rendering: optimizeSpeed;"
xlink:href="data:image/gif,GIF87a%01%00%01%00%80%01%00%FF%00%00%FF%FF%FF%2C%00%00%00%00%01%00%01%00%00%02%02D%01%00%3B">
</feImage>
</filter>
<rect filter="url(#filter)"/>
</svg>

After

Width:  |  Height:  |  Size: 677 B

View File

@ -215,6 +215,7 @@ random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-02.svg objectBoundin
== rect-01.svg pass.svg
== rect-02.svg pass.svg
== rect-03.svg pass.svg
== rect-04.svg pass.svg
== rect-with-rx-and-ry-01.svg pass.svg
== rect-with-rx-or-ry-01.svg rect-with-rx-or-ry-01-ref.svg
== rootElement-null-01.svg pass.svg

View File

@ -26,6 +26,6 @@
</filter>
<rect width="100" height="20" fill="red"/>
<rect filter="url(#filter)"/>
<rect width="100" height="20" filter="url(#filter)"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -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"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait">
<title>Test animation of the "width" &amp; "height" &lt;length&gt; attributes on the "use" element</title>
<script type="text/javascript">
function doTest() {
setTimeAndSnapshot(1, true);
}
window.addEventListener("MozReftestInvalidate", doTest, false);
</script>
<script xlink:href="smil-util.js" type="text/javascript"/>
<defs>
<g id="g1">
<rect width="100" height="50" fill="lime" />
</g>
<g id="g2">
<rect y="50" width="100" height="50" fill="lime" />
</g>
</defs>
<rect width="100%" height="100%" fill="lime"/>
<rect width="100" height="100" fill="red" />
<use xlink:href="#g1">
<set attributeName="width"
to="0" begin="0s" dur="0.5s"/>
</use>
<use xlink:href="#g2">
<set attributeName="height"
to="0" begin="0s" dur="0.5s"/>
</use>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -95,6 +95,7 @@ fails == anim-fillcolor-1.svg anim-standard-ref.svg # bug 436296
== anim-length-reset-01.svg lime.svg
== anim-nonpixel-length-reset-01.svg lime.svg
== anim-use-length-01.svg lime.svg
== anim-use-length-02.svg lime.svg
# animate some <number> attributes:
== anim-feComponentTransfer-01.svg lime.svg

View File

@ -320,8 +320,8 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
float x, y, width, height;
nsSVGImageElement *imgElem = static_cast<nsSVGImageElement*>(mContent);
imgElem->GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);
if (width <= 0 || height <= 0)
return NS_OK;
NS_ASSERTION(width >= 0 && height >= 0,
"Should only be painting things with valid width/height");
if (!mImageContainer) {
nsCOMPtr<imgIRequest> currentRequest;

View File

@ -51,7 +51,10 @@ class nsSVGUseFrame : public nsSVGUseFrameBase,
NS_NewSVGUseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
protected:
nsSVGUseFrame(nsStyleContext* aContext) : nsSVGUseFrameBase(aContext) {}
nsSVGUseFrame(nsStyleContext* aContext) :
nsSVGUseFrameBase(aContext),
mHasValidDimensions(true)
{}
public:
NS_DECL_QUERYFRAME
@ -59,11 +62,9 @@ public:
// nsIFrame interface:
#ifdef DEBUG
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow);
#endif
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
@ -94,6 +95,9 @@ public:
virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements);
virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
PRUint32 aFilter);
private:
bool mHasValidDimensions;
};
//----------------------------------------------------------------------
@ -123,18 +127,21 @@ NS_QUERYFRAME_TAIL_INHERITING(nsSVGUseFrameBase)
//----------------------------------------------------------------------
// nsIFrame methods:
#ifdef DEBUG
NS_IMETHODIMP
nsSVGUseFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
#ifdef DEBUG
nsCOMPtr<nsIDOMSVGUseElement> use = do_QueryInterface(aContent);
NS_ASSERTION(use, "Content is not an SVG use!");
#endif /* DEBUG */
mHasValidDimensions =
static_cast<nsSVGUseElement*>(aContent)->HasValidDimensions();
return nsSVGUseFrameBase::Init(aContent, aParent, aPrevInFlow);
}
#endif /* DEBUG */
NS_IMETHODIMP
nsSVGUseFrame::AttributeChanged(PRInt32 aNameSpaceID,
@ -150,7 +157,14 @@ nsSVGUseFrame::AttributeChanged(PRInt32 aNameSpaceID,
nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
} else if (aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
static_cast<nsSVGUseElement*>(mContent)->SyncWidthHeight(aAttribute);
static_cast<nsSVGUseElement*>(mContent)->SyncWidthOrHeight(aAttribute);
if (mHasValidDimensions !=
static_cast<nsSVGUseElement*>(mContent)->HasValidDimensions()) {
mHasValidDimensions = !mHasValidDimensions;
nsSVGUtils::UpdateGraphic(this);
}
}
} else if (aNameSpaceID == kNameSpaceID_XLink &&
aAttribute == nsGkAtoms::href) {

View File

@ -1001,6 +1001,12 @@ nsSVGUtils::PaintFrameWithEffects(nsSVGRenderState *aContext,
if (opacity == 0.0f)
return;
const nsIContent* content = aFrame->GetContent();
if (content->IsSVG() &&
!static_cast<const nsSVGElement*>(content)->HasValidDimensions()) {
return;
}
/* Properties are added lazily and may have been removed by a restyle,
so make sure all applicable ones are set again. */
@ -1159,9 +1165,9 @@ nsSVGUtils::HitTestChildren(nsIFrame *aFrame, const nsPoint &aPoint)
current = current->GetPrevSibling()) {
nsISVGChildFrame* SVGFrame = do_QueryFrame(current);
if (SVGFrame) {
result = SVGFrame->GetFrameForPoint(aPoint);
if (result)
break;
result = SVGFrame->GetFrameForPoint(aPoint);
if (result)
break;
}
}
@ -1393,13 +1399,18 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, PRUint32 aFlags)
}
svg = do_QueryFrame(aFrame);
}
nsIContent* content = aFrame->GetContent();
if (content->IsSVG() &&
!static_cast<const nsSVGElement*>(content)->HasValidDimensions()) {
return bbox;
}
gfxMatrix matrix;
if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame) {
// The spec says getBBox "Returns the tight bounding box in *current user
// space*". So we should really be doing this for all elements, but that
// needs investigation to check that we won't break too much content.
NS_ABORT_IF_FALSE(aFrame->GetContent()->IsSVG(), "bad cast");
nsSVGElement *element = static_cast<nsSVGElement*>(aFrame->GetContent());
NS_ABORT_IF_FALSE(content->IsSVG(), "bad cast");
nsSVGElement *element = static_cast<nsSVGElement*>(content);
matrix = element->PrependLocalTransformsTo(matrix,
nsSVGElement::eChildToUserSpace);
}