mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 785606 - Support viewBox=none from SVG 1.2 Tiny r=jwatt
This commit is contained in:
parent
f12e7d74a0
commit
1216de8a05
@ -321,7 +321,7 @@ SVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
|
||||
nsSVGViewBoxRect
|
||||
SVGMarkerElement::GetViewBoxRect()
|
||||
{
|
||||
if (mViewBox.IsExplicitlySet()) {
|
||||
if (mViewBox.HasRect()) {
|
||||
return mViewBox.GetAnimValue();
|
||||
}
|
||||
return nsSVGViewBoxRect(
|
||||
|
@ -847,12 +847,12 @@ nsSVGViewBoxRect
|
||||
SVGSVGElement::GetViewBoxWithSynthesis(
|
||||
float aViewportWidth, float aViewportHeight) const
|
||||
{
|
||||
// The logic here should match HasViewBox().
|
||||
// The logic here should match HasViewBoxRect().
|
||||
SVGViewElement* viewElement = GetCurrentViewElement();
|
||||
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
|
||||
if (viewElement && viewElement->mViewBox.HasRect()) {
|
||||
return viewElement->mViewBox.GetAnimValue();
|
||||
}
|
||||
if (mViewBox.IsExplicitlySet()) {
|
||||
if (mViewBox.HasRect()) {
|
||||
return mViewBox.GetAnimValue();
|
||||
}
|
||||
|
||||
@ -885,11 +885,11 @@ SVGSVGElement::GetPreserveAspectRatioWithOverride() const
|
||||
|
||||
SVGViewElement* viewElement = GetCurrentViewElement();
|
||||
|
||||
// This check is equivalent to "!HasViewBox() && ShouldSynthesizeViewBox()".
|
||||
// We're just holding onto the viewElement that HasViewBox() would look up,
|
||||
// This check is equivalent to "!HasViewBoxRect() && ShouldSynthesizeViewBox()".
|
||||
// We're just holding onto the viewElement that HasViewBoxRect() would look up,
|
||||
// so that we don't have to look it up again later.
|
||||
if (!((viewElement && viewElement->mViewBox.IsExplicitlySet()) ||
|
||||
mViewBox.IsExplicitlySet()) &&
|
||||
if (!((viewElement && viewElement->mViewBox.HasRect()) ||
|
||||
mViewBox.HasRect()) &&
|
||||
ShouldSynthesizeViewBox()) {
|
||||
// If we're synthesizing a viewBox, use preserveAspectRatio="none";
|
||||
return SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_SLICE);
|
||||
@ -912,10 +912,10 @@ SVGSVGElement::GetLength(uint8_t aCtxType)
|
||||
SVGViewElement* viewElement = GetCurrentViewElement();
|
||||
const nsSVGViewBoxRect* viewbox = nullptr;
|
||||
|
||||
// The logic here should match HasViewBox().
|
||||
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
|
||||
// The logic here should match HasViewBoxRect().
|
||||
if (viewElement && viewElement->mViewBox.HasRect()) {
|
||||
viewbox = &viewElement->mViewBox.GetAnimValue();
|
||||
} else if (mViewBox.IsExplicitlySet()) {
|
||||
} else if (mViewBox.HasRect()) {
|
||||
viewbox = &mViewBox.GetAnimValue();
|
||||
}
|
||||
|
||||
@ -1029,19 +1029,19 @@ SVGSVGElement::GetPreserveAspectRatio()
|
||||
}
|
||||
|
||||
bool
|
||||
SVGSVGElement::HasViewBox() const
|
||||
SVGSVGElement::HasViewBoxRect() const
|
||||
{
|
||||
SVGViewElement* viewElement = GetCurrentViewElement();
|
||||
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
|
||||
if (viewElement && viewElement->mViewBox.HasRect()) {
|
||||
return true;
|
||||
}
|
||||
return mViewBox.IsExplicitlySet();
|
||||
return mViewBox.HasRect();
|
||||
}
|
||||
|
||||
bool
|
||||
SVGSVGElement::ShouldSynthesizeViewBox() const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!HasViewBox(),
|
||||
NS_ABORT_IF_FALSE(!HasViewBoxRect(),
|
||||
"Should only be called if we lack a viewBox");
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
@ -1110,8 +1110,8 @@ SVGSVGElement::
|
||||
"should only override preserveAspectRatio in images");
|
||||
#endif
|
||||
|
||||
bool hasViewBox = HasViewBox();
|
||||
if (!hasViewBox && ShouldSynthesizeViewBox()) {
|
||||
bool hasViewBoxRect = HasViewBoxRect();
|
||||
if (!hasViewBoxRect && ShouldSynthesizeViewBox()) {
|
||||
// My non-<svg:image> clients will have been painting me with a synthesized
|
||||
// viewBox, but my <svg:image> client that's about to paint me now does NOT
|
||||
// want that. Need to tell ourselves to flush our transform.
|
||||
@ -1119,7 +1119,7 @@ SVGSVGElement::
|
||||
}
|
||||
mIsPaintingSVGImageElement = true;
|
||||
|
||||
if (!hasViewBox) {
|
||||
if (!hasViewBoxRect) {
|
||||
return; // preserveAspectRatio irrelevant (only matters if we have viewBox)
|
||||
}
|
||||
|
||||
@ -1141,7 +1141,7 @@ SVGSVGElement::ClearImageOverridePreserveAspectRatio()
|
||||
#endif
|
||||
|
||||
mIsPaintingSVGImageElement = false;
|
||||
if (!HasViewBox() && ShouldSynthesizeViewBox()) {
|
||||
if (!HasViewBoxRect() && ShouldSynthesizeViewBox()) {
|
||||
// My non-<svg:image> clients will want to paint me with a synthesized
|
||||
// viewBox, but my <svg:image> client that just painted me did NOT
|
||||
// use that. Need to tell ourselves to flush our transform.
|
||||
|
@ -154,19 +154,19 @@ public:
|
||||
* Note also that this method does not pay attention to whether the width or
|
||||
* height values of the viewBox rect are positive!
|
||||
*/
|
||||
bool HasViewBox() const;
|
||||
bool HasViewBoxRect() const;
|
||||
|
||||
/**
|
||||
* Returns true if we should synthesize a viewBox for ourselves (that is, if
|
||||
* we're the root element in an image document, and we're not currently being
|
||||
* painted for an <svg:image> element).
|
||||
*
|
||||
* Only call this method if HasViewBox() returns false.
|
||||
* Only call this method if HasViewBoxRect() returns false.
|
||||
*/
|
||||
bool ShouldSynthesizeViewBox() const;
|
||||
|
||||
bool HasViewBoxOrSyntheticViewBox() const {
|
||||
return HasViewBox() || ShouldSynthesizeViewBox();
|
||||
return HasViewBoxRect() || ShouldSynthesizeViewBox();
|
||||
}
|
||||
|
||||
gfxMatrix GetViewBoxTransform() const;
|
||||
|
@ -18,8 +18,7 @@ SVGViewBoxSMILType::Init(nsSMILValue& aValue) const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected value type");
|
||||
|
||||
nsSVGViewBoxRect* viewBox = new nsSVGViewBoxRect();
|
||||
aValue.mU.mPtr = viewBox;
|
||||
aValue.mU.mPtr = new nsSVGViewBoxRect();
|
||||
aValue.mType = this;
|
||||
}
|
||||
|
||||
@ -84,6 +83,10 @@ SVGViewBoxSMILType::ComputeDistance(const nsSMILValue& aFrom,
|
||||
const nsSVGViewBoxRect* from = static_cast<const nsSVGViewBoxRect*>(aFrom.mU.mPtr);
|
||||
const nsSVGViewBoxRect* to = static_cast<const nsSVGViewBoxRect*>(aTo.mU.mPtr);
|
||||
|
||||
if (from->none || to->none) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We use the distances between the edges rather than the difference between
|
||||
// the x, y, width and height for the "distance". This is necessary in
|
||||
// order for the "distance" result that we calculate to be the same for a
|
||||
@ -111,9 +114,14 @@ SVGViewBoxSMILType::Interpolate(const nsSMILValue& aStartVal,
|
||||
NS_PRECONDITION(aStartVal.mType == this,
|
||||
"Unexpected types for interpolation");
|
||||
NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
|
||||
|
||||
|
||||
const nsSVGViewBoxRect* start = static_cast<const nsSVGViewBoxRect*>(aStartVal.mU.mPtr);
|
||||
const nsSVGViewBoxRect* end = static_cast<const nsSVGViewBoxRect*>(aEndVal.mU.mPtr);
|
||||
|
||||
if (start->none || end->none) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsSVGViewBoxRect* current = static_cast<nsSVGViewBoxRect*>(aResult.mU.mPtr);
|
||||
|
||||
float x = (start->x + (end->x - start->x) * aUnitDistance);
|
||||
|
@ -25,10 +25,12 @@ nsSVGViewBoxRect::operator==(const nsSVGViewBoxRect& aOther) const
|
||||
if (&aOther == this)
|
||||
return true;
|
||||
|
||||
return x == aOther.x &&
|
||||
y == aOther.y &&
|
||||
width == aOther.width &&
|
||||
height == aOther.height;
|
||||
return (none && aOther.none) ||
|
||||
(!none && !aOther.none &&
|
||||
x == aOther.x &&
|
||||
y == aOther.y &&
|
||||
width == aOther.width &&
|
||||
height == aOther.height);
|
||||
}
|
||||
|
||||
/* Cycle collection macros for nsSVGViewBox */
|
||||
@ -79,24 +81,22 @@ static nsSVGAttrTearoffTable<nsSVGViewBox, nsSVGViewBox::DOMAnimVal>
|
||||
void
|
||||
nsSVGViewBox::Init()
|
||||
{
|
||||
mBaseVal = nsSVGViewBoxRect();
|
||||
mAnimVal = nullptr;
|
||||
mHasBaseVal = false;
|
||||
mAnimVal = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGViewBox::SetAnimValue(float aX, float aY, float aWidth, float aHeight,
|
||||
nsSVGViewBox::SetAnimValue(const nsSVGViewBoxRect& aRect,
|
||||
nsSVGElement *aSVGElement)
|
||||
{
|
||||
if (!mAnimVal) {
|
||||
// it's okay if allocation fails - and no point in reporting that
|
||||
mAnimVal = new nsSVGViewBoxRect(aX, aY, aWidth, aHeight);
|
||||
mAnimVal = new nsSVGViewBoxRect(aRect);
|
||||
} else {
|
||||
nsSVGViewBoxRect rect(aX, aY, aWidth, aHeight);
|
||||
if (rect == *mAnimVal) {
|
||||
if (aRect == *mAnimVal) {
|
||||
return;
|
||||
}
|
||||
*mAnimVal = rect;
|
||||
*mAnimVal = aRect;
|
||||
}
|
||||
aSVGElement->DidAnimateViewBox();
|
||||
}
|
||||
@ -105,7 +105,12 @@ void
|
||||
nsSVGViewBox::SetBaseValue(const nsSVGViewBoxRect& aRect,
|
||||
nsSVGElement *aSVGElement)
|
||||
{
|
||||
if (mHasBaseVal && mBaseVal == aRect) {
|
||||
if (!mHasBaseVal || mBaseVal == aRect) {
|
||||
// This method is used to set a single x, y, width
|
||||
// or height value. It can't create a base value
|
||||
// as the other components may be undefined. We record
|
||||
// the new value though, so as not to lose data.
|
||||
mBaseVal = aRect;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -123,6 +128,11 @@ nsSVGViewBox::SetBaseValue(const nsSVGViewBoxRect& aRect,
|
||||
static nsresult
|
||||
ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
|
||||
{
|
||||
if (aStr.EqualsLiteral("none")) {
|
||||
aViewBox->none = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
|
||||
tokenizer(aStr, ',',
|
||||
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||
@ -152,6 +162,7 @@ ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
|
||||
aViewBox->y = vals[1];
|
||||
aViewBox->width = vals[2];
|
||||
aViewBox->height = vals[3];
|
||||
aViewBox->none = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -162,28 +173,38 @@ nsSVGViewBox::SetBaseValueString(const nsAString& aValue,
|
||||
bool aDoSetAttr)
|
||||
{
|
||||
nsSVGViewBoxRect viewBox;
|
||||
nsresult res = ToSVGViewBoxRect(aValue, &viewBox);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
nsAttrValue emptyOrOldValue;
|
||||
if (aDoSetAttr) {
|
||||
emptyOrOldValue = aSVGElement->WillChangeViewBox();
|
||||
}
|
||||
mBaseVal = nsSVGViewBoxRect(viewBox.x, viewBox.y, viewBox.width, viewBox.height);
|
||||
mHasBaseVal = true;
|
||||
|
||||
if (aDoSetAttr) {
|
||||
aSVGElement->DidChangeViewBox(emptyOrOldValue);
|
||||
}
|
||||
if (mAnimVal) {
|
||||
aSVGElement->AnimationNeedsResample();
|
||||
}
|
||||
nsresult rv = ToSVGViewBoxRect(aValue, &viewBox);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return res;
|
||||
if (viewBox == mBaseVal) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAttrValue emptyOrOldValue;
|
||||
if (aDoSetAttr) {
|
||||
emptyOrOldValue = aSVGElement->WillChangeViewBox();
|
||||
}
|
||||
mHasBaseVal = true;
|
||||
mBaseVal = viewBox;
|
||||
|
||||
if (aDoSetAttr) {
|
||||
aSVGElement->DidChangeViewBox(emptyOrOldValue);
|
||||
}
|
||||
if (mAnimVal) {
|
||||
aSVGElement->AnimationNeedsResample();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGViewBox::GetBaseValueString(nsAString& aValue) const
|
||||
{
|
||||
if (mBaseVal.none) {
|
||||
aValue.AssignLiteral("none");
|
||||
return;
|
||||
}
|
||||
PRUnichar buf[200];
|
||||
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
|
||||
NS_LITERAL_STRING("%g %g %g %g").get(),
|
||||
@ -215,6 +236,10 @@ nsSVGViewBox::DOMAnimatedRect::~DOMAnimatedRect()
|
||||
nsresult
|
||||
nsSVGViewBox::ToDOMBaseVal(nsIDOMSVGRect **aResult, nsSVGElement *aSVGElement)
|
||||
{
|
||||
if (!mHasBaseVal || mBaseVal.none) {
|
||||
*aResult = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<DOMBaseVal> domBaseVal =
|
||||
sBaseSVGViewBoxTearoffTable.GetTearoff(this);
|
||||
if (!domBaseVal) {
|
||||
@ -234,6 +259,11 @@ nsSVGViewBox::DOMBaseVal::~DOMBaseVal()
|
||||
nsresult
|
||||
nsSVGViewBox::ToDOMAnimVal(nsIDOMSVGRect **aResult, nsSVGElement *aSVGElement)
|
||||
{
|
||||
if ((mAnimVal && mAnimVal->none) ||
|
||||
(!mAnimVal && (!mHasBaseVal || mBaseVal.none))) {
|
||||
*aResult = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<DOMAnimVal> domAnimVal =
|
||||
sAnimSVGViewBoxTearoffTable.GetTearoff(this);
|
||||
if (!domAnimVal) {
|
||||
@ -255,8 +285,7 @@ nsSVGViewBox::DOMBaseVal::SetX(float aX)
|
||||
{
|
||||
nsSVGViewBoxRect rect = mVal->GetBaseValue();
|
||||
rect.x = aX;
|
||||
mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
|
||||
mSVGElement);
|
||||
mVal->SetBaseValue(rect, mSVGElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -265,8 +294,7 @@ nsSVGViewBox::DOMBaseVal::SetY(float aY)
|
||||
{
|
||||
nsSVGViewBoxRect rect = mVal->GetBaseValue();
|
||||
rect.y = aY;
|
||||
mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
|
||||
mSVGElement);
|
||||
mVal->SetBaseValue(rect, mSVGElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -275,8 +303,7 @@ nsSVGViewBox::DOMBaseVal::SetWidth(float aWidth)
|
||||
{
|
||||
nsSVGViewBoxRect rect = mVal->GetBaseValue();
|
||||
rect.width = aWidth;
|
||||
mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
|
||||
mSVGElement);
|
||||
mVal->SetBaseValue(rect, mSVGElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -285,8 +312,7 @@ nsSVGViewBox::DOMBaseVal::SetHeight(float aHeight)
|
||||
{
|
||||
nsSVGViewBoxRect rect = mVal->GetBaseValue();
|
||||
rect.height = aHeight;
|
||||
mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
|
||||
mSVGElement);
|
||||
mVal->SetBaseValue(rect, mSVGElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -340,7 +366,7 @@ nsSVGViewBox::SMILViewBox::SetAnimValue(const nsSMILValue& aValue)
|
||||
"Unexpected type to assign animated value");
|
||||
if (aValue.mType == &SVGViewBoxSMILType::sSingleton) {
|
||||
nsSVGViewBoxRect &vb = *static_cast<nsSVGViewBoxRect*>(aValue.mU.mPtr);
|
||||
mVal->SetAnimValue(vb.x, vb.y, vb.width, vb.height, mSVGElement);
|
||||
mVal->SetAnimValue(vb, mSVGElement);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -22,12 +22,13 @@ struct nsSVGViewBoxRect
|
||||
{
|
||||
float x, y;
|
||||
float width, height;
|
||||
bool none;
|
||||
|
||||
nsSVGViewBoxRect() : x(0), y(0), width(0), height(0) {}
|
||||
nsSVGViewBoxRect() : none(true) {}
|
||||
nsSVGViewBoxRect(float aX, float aY, float aWidth, float aHeight) :
|
||||
x(aX), y(aY), width(aWidth), height(aHeight) {}
|
||||
x(aX), y(aY), width(aWidth), height(aHeight), none(false) {}
|
||||
nsSVGViewBoxRect(const nsSVGViewBoxRect& rhs) :
|
||||
x(rhs.x), y(rhs.y), width(rhs.width), height(rhs.height) {}
|
||||
x(rhs.x), y(rhs.y), width(rhs.width), height(rhs.height), none(rhs.none) {}
|
||||
bool operator==(const nsSVGViewBoxRect& aOther) const;
|
||||
};
|
||||
|
||||
@ -48,19 +49,24 @@ public:
|
||||
* positive, so callers must check whether the viewBox rect is valid where
|
||||
* necessary!
|
||||
*/
|
||||
bool HasRect() const
|
||||
{ return (mAnimVal && !mAnimVal->none) ||
|
||||
(!mAnimVal && mHasBaseVal && !mBaseVal.none); }
|
||||
|
||||
/**
|
||||
* Returns true if the corresponding "viewBox" attribute either defined a
|
||||
* rectangle with finite values or the special "none" value.
|
||||
*/
|
||||
bool IsExplicitlySet() const
|
||||
{ return (mHasBaseVal || mAnimVal); }
|
||||
{ return mAnimVal || mHasBaseVal; }
|
||||
|
||||
const nsSVGViewBoxRect& GetBaseValue() const
|
||||
{ return mBaseVal; }
|
||||
void SetBaseValue(const nsSVGViewBoxRect& aRect,
|
||||
nsSVGElement *aSVGElement);
|
||||
void SetBaseValue(float aX, float aY, float aWidth, float aHeight,
|
||||
nsSVGElement *aSVGElement)
|
||||
{ SetBaseValue(nsSVGViewBoxRect(aX, aY, aWidth, aHeight), aSVGElement); }
|
||||
const nsSVGViewBoxRect& GetAnimValue() const
|
||||
{ return mAnimVal ? *mAnimVal : mBaseVal; }
|
||||
void SetAnimValue(float aX, float aY, float aWidth, float aHeight,
|
||||
void SetAnimValue(const nsSVGViewBoxRect& aRect,
|
||||
nsSVGElement *aSVGElement);
|
||||
|
||||
nsresult SetBaseValueString(const nsAString& aValue,
|
||||
|
@ -248,19 +248,8 @@ function runTests()
|
||||
// viewBox attribute
|
||||
var baseViewBox = marker.viewBox.baseVal;
|
||||
var animViewBox = marker.viewBox.animVal;
|
||||
is(baseViewBox.x, 0, "viewBox baseVal");
|
||||
is(animViewBox.x, 0, "viewBox baseVal");
|
||||
is(baseViewBox.y, 0, "viewBox baseVal");
|
||||
is(animViewBox.y, 0, "viewBox baseVal");
|
||||
is(baseViewBox.width, 0, "viewBox baseVal");
|
||||
is(animViewBox.width, 0, "viewBox baseVal");
|
||||
is(baseViewBox.height, 0, "viewBox baseVal");
|
||||
is(animViewBox.height, 0, "viewBox baseVal");
|
||||
baseViewBox.x = 10;
|
||||
baseViewBox.y = 11;
|
||||
baseViewBox.width = 12;
|
||||
baseViewBox.height = 13;
|
||||
is(marker.getAttribute("viewBox"), "10 11 12 13", "viewBox attribute");
|
||||
is(baseViewBox, null, "viewBox baseVal");
|
||||
is(animViewBox, null, "viewBox animVal");
|
||||
|
||||
marker.setAttribute("viewBox", "1 2 3 4");
|
||||
is(marker.viewBox.baseVal.x, 1, "viewBox.x baseVal");
|
||||
@ -280,11 +269,28 @@ function runTests()
|
||||
marker.viewBox.baseVal.height = 8;
|
||||
is(marker.viewBox.animVal.height, 8, "viewBox.height animVal");
|
||||
is(marker.getAttribute("viewBox"), "5 6 7 8", "viewBox attribute");
|
||||
var storedViewBox = marker.viewBox.baseVal;
|
||||
marker.removeAttribute("viewBox");
|
||||
is(marker.hasAttribute("viewBox"), false, "viewBox hasAttribute");
|
||||
ok(marker.getAttribute("viewBox") === null, "removed viewBox attribute");
|
||||
is(marker.viewBox.baseVal, null, "viewBox baseVal");
|
||||
is(marker.viewBox.animVal, null, "viewBox animVal");
|
||||
|
||||
is(storedViewBox.width, 7, "Should not lose values");
|
||||
storedViewBox.width = 200;
|
||||
is(storedViewBox.width, 200, "Should be able to change detached viewBox rect");
|
||||
is(marker.hasAttribute("viewBox"), false, "viewBox hasAttribute should still be false");
|
||||
ok(marker.getAttribute("viewBox") === null, "viewBox attribute should still be null");
|
||||
is(marker.viewBox.baseVal, null, "viewBox baseVal");
|
||||
is(marker.viewBox.animVal, null, "viewBox animVal");
|
||||
|
||||
marker.setAttribute("viewBox", "none");
|
||||
is(marker.hasAttribute("viewBox"), true, "viewBox hasAttribute");
|
||||
is(marker.viewBox.baseVal, null, "viewBox baseVal");
|
||||
is(marker.viewBox.animVal, null, "viewBox animVal");
|
||||
|
||||
marker.setAttribute("viewBox", "");
|
||||
is(marker.hasAttribute("viewBox"), true, "viewBox hasAttribute");
|
||||
ok(marker.getAttribute("viewBox") === "", "empty viewBox attribute");
|
||||
|
||||
SimpleTest.finish();
|
||||
|
@ -236,7 +236,8 @@ function runTests()
|
||||
marker.viewBox.baseVal.height = 5;
|
||||
marker.removeAttribute("viewBox");
|
||||
marker.removeAttributeNS(null, "viewBox");
|
||||
marker.viewBox.baseVal.height = 4;
|
||||
marker.setAttribute("viewBox", "none");
|
||||
marker.setAttribute("viewBox", "none");
|
||||
|
||||
eventChecker.ignoreEvents();
|
||||
marker.setAttribute("viewBox", "1 2 3 4");
|
||||
|
@ -39,6 +39,7 @@ function runTests()
|
||||
new Test("svgView(viewBox(0,0,200,200))", true, "0 0 200 200", null, null),
|
||||
new Test("svgView(preserveAspectRatio(xMaxYMin slice))", true, null, "xMaxYMin slice", null),
|
||||
new Test("svgView(viewBox(1,2,3,4);preserveAspectRatio(xMinYMax))", true, "1 2 3 4", "xMinYMax meet", null),
|
||||
new Test("svgView(viewBox(none))", true, "none", null, null),
|
||||
new Test("svgView(zoomAndPan(disable))", true, null, null, "disable"),
|
||||
new Test("svgView(transform(translate(-10,-20) scale(2) rotate(45) translate(5,10)))", true, null, null, null),
|
||||
// No duplicates allowed
|
||||
|
18
layout/reftests/svg/smil/anim-svg-viewBox-03.svg
Normal file
18
layout/reftests/svg/smil/anim-svg-viewBox-03.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="setTimeAndSnapshot(12, true)">
|
||||
<title>Test discrete animation of the "viewBox" attribute on the "svg" element</title>
|
||||
<script xlink:href="smil-util.js" type="text/javascript"/>
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
|
||||
<svg width="200" height="200" viewBox="200 0 150 50">
|
||||
<animate attributeName="viewBox"
|
||||
calcMode="discrete"
|
||||
begin="10s" dur="4s"
|
||||
values="200 0 150 50; none; 200 0 150 50"
|
||||
fill="freeze"/>
|
||||
<rect x="-100" y="-100" width="1000" height="1000" fill="red"/>
|
||||
<rect width="200" height="200" fill="lime"/>
|
||||
</svg>
|
||||
</svg>
|
After Width: | Height: | Size: 735 B |
@ -139,6 +139,7 @@ skip-if(B2G) == anim-feConvolveMatrix-preserveAlpha-01.svg lime.svg # bug 773482
|
||||
# animate some viewBox attributes
|
||||
== anim-svg-viewBox-01.svg lime.svg
|
||||
== anim-svg-viewBox-02.svg lime.svg
|
||||
== anim-svg-viewBox-03.svg lime.svg
|
||||
== anim-view-01.svg#view lime.svg
|
||||
|
||||
# animate some preserveAspectRatio attributes
|
||||
|
@ -136,11 +136,11 @@ nsSVGInnerSVGFrame::NotifySVGChanged(uint32_t aFlags)
|
||||
|
||||
if (!(aFlags & TRANSFORM_CHANGED) &&
|
||||
(xOrYIsPercentage ||
|
||||
(widthOrHeightIsPercentage && svg->HasViewBox()))) {
|
||||
(widthOrHeightIsPercentage && svg->HasViewBoxRect()))) {
|
||||
aFlags |= TRANSFORM_CHANGED;
|
||||
}
|
||||
|
||||
if (svg->HasViewBox() || !widthOrHeightIsPercentage) {
|
||||
if (svg->HasViewBoxRect() || !widthOrHeightIsPercentage) {
|
||||
// Remove COORD_CONTEXT_CHANGED, since we establish the coordinate
|
||||
// context for our descendants and this notification won't change its
|
||||
// dimensions:
|
||||
|
@ -287,9 +287,9 @@ nsSVGOuterSVGFrame::GetIntrinsicRatio()
|
||||
const nsSVGViewBoxRect* viewbox = nullptr;
|
||||
|
||||
// The logic here should match HasViewBox().
|
||||
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
|
||||
if (viewElement && viewElement->mViewBox.HasRect()) {
|
||||
viewbox = &viewElement->mViewBox.GetAnimValue();
|
||||
} else if (content->mViewBox.IsExplicitlySet()) {
|
||||
} else if (content->mViewBox.HasRect()) {
|
||||
viewbox = &content->mViewBox.GetAnimValue();
|
||||
}
|
||||
|
||||
@ -754,7 +754,7 @@ nsSVGOuterSVGFrame::NotifyViewportOrTransformChanged(uint32_t aFlags)
|
||||
SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
|
||||
|
||||
if (aFlags & COORD_CONTEXT_CHANGED) {
|
||||
if (content->HasViewBox()) {
|
||||
if (content->HasViewBoxRect()) {
|
||||
// Percentage lengths on children resolve against the viewBox rect so we
|
||||
// don't need to notify them of the viewport change, but the viewBox
|
||||
// transform will have changed, so we need to notify them of that instead.
|
||||
|
Loading…
Reference in New Issue
Block a user