mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 540588. Add support for SMIL animation of <integer> attributes in SVG. r=dholbert
This commit is contained in:
parent
232dae9b42
commit
f2e0136d80
@ -72,6 +72,7 @@ CPPSRCS += \
|
||||
nsSMILValue.cpp \
|
||||
SMILBoolType.cpp \
|
||||
SMILEnumType.cpp \
|
||||
SMILIntegerType.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
123
content/smil/SMILIntegerType.cpp
Normal file
123
content/smil/SMILIntegerType.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "SMILIntegerType.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "nsDebug.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/*static*/ SMILIntegerType SMILIntegerType::sSingleton;
|
||||
|
||||
nsresult
|
||||
SMILIntegerType::Init(nsSMILValue& aValue) const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected value type");
|
||||
aValue.mU.mInt = 0;
|
||||
aValue.mType = this;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
SMILIntegerType::Destroy(nsSMILValue& aValue) const
|
||||
{
|
||||
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
|
||||
aValue.mU.mInt = 0;
|
||||
aValue.mType = &nsSMILNullType::sSingleton;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SMILIntegerType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
|
||||
{
|
||||
NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
|
||||
NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
|
||||
aDest.mU.mInt = aSrc.mU.mInt;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SMILIntegerType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
|
||||
PRUint32 aCount) const
|
||||
{
|
||||
NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
|
||||
"Trying to add invalid types");
|
||||
NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
|
||||
aDest.mU.mInt += aValueToAdd.mU.mInt * aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SMILIntegerType::ComputeDistance(const nsSMILValue& aFrom,
|
||||
const nsSMILValue& aTo,
|
||||
double& aDistance) const
|
||||
{
|
||||
NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
|
||||
NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
|
||||
aDistance = fabs(double(aTo.mU.mInt - aFrom.mU.mInt));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SMILIntegerType::Interpolate(const nsSMILValue& aStartVal,
|
||||
const nsSMILValue& aEndVal,
|
||||
double aUnitDistance,
|
||||
nsSMILValue& aResult) const
|
||||
{
|
||||
NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
|
||||
"Trying to interpolate different types");
|
||||
NS_PRECONDITION(aStartVal.mType == this,
|
||||
"Unexpected types for interpolation");
|
||||
NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
|
||||
|
||||
const double startVal = double(aStartVal.mU.mInt);
|
||||
const double endVal = double(aEndVal.mU.mInt);
|
||||
const double currentVal = startVal + (endVal - startVal) * aUnitDistance;
|
||||
|
||||
// When currentVal is exactly midway between its two nearest integers, we
|
||||
// jump to the "next" integer to provide simple, easy to remember and
|
||||
// consistent behaviour (from the SMIL author's point of view).
|
||||
|
||||
if (startVal < endVal) {
|
||||
aResult.mU.mInt = PRInt64(floor(currentVal + 0.5)); // round mid up
|
||||
} else {
|
||||
aResult.mU.mInt = PRInt64(ceil(currentVal - 0.5)); // round mid down
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
68
content/smil/SMILIntegerType.h
Normal file
68
content/smil/SMILIntegerType.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MOZILLA_SMILINTEGERTYPE_H_
|
||||
#define MOZILLA_SMILINTEGERTYPE_H_
|
||||
|
||||
#include "nsISMILType.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class SMILIntegerType : public nsISMILType
|
||||
{
|
||||
public:
|
||||
virtual nsresult Init(nsSMILValue& aValue) const;
|
||||
virtual void Destroy(nsSMILValue&) const;
|
||||
virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const;
|
||||
virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
|
||||
PRUint32 aCount) const;
|
||||
virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
|
||||
const nsSMILValue& aTo,
|
||||
double& aDistance) const;
|
||||
virtual nsresult Interpolate(const nsSMILValue& aStartVal,
|
||||
const nsSMILValue& aEndVal,
|
||||
double aUnitDistance,
|
||||
nsSMILValue& aResult) const;
|
||||
|
||||
static SMILIntegerType sSingleton;
|
||||
|
||||
private:
|
||||
SMILIntegerType() {}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_SMILINTEGERTYPE_H_
|
@ -1336,6 +1336,19 @@ nsSVGElement::DidChangeInteger(PRUint8 aAttrEnum, PRBool aDoSetAttr)
|
||||
newStr, PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGElement::DidAnimateInteger(PRUint8 aAttrEnum)
|
||||
{
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
|
||||
if (frame) {
|
||||
IntegerAttributesInfo info = GetIntegerInfo();
|
||||
frame->AttributeChanged(kNameSpaceID_None,
|
||||
*info.mIntegerInfo[aAttrEnum].mName,
|
||||
nsIDOMMutationEvent::MODIFICATION);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGElement::GetAnimatedIntegerValues(PRInt32 *aFirst, ...)
|
||||
{
|
||||
@ -1351,7 +1364,7 @@ nsSVGElement::GetAnimatedIntegerValues(PRInt32 *aFirst, ...)
|
||||
va_start(args, aFirst);
|
||||
|
||||
while (n && i < info.mIntegerCount) {
|
||||
*n = info.mIntegers[i++].GetAnimValue();
|
||||
*n = info.mIntegers[i++].GetAnimValue(this);
|
||||
n = va_arg(args, PRInt32*);
|
||||
}
|
||||
va_end(args);
|
||||
@ -1766,6 +1779,16 @@ nsSVGElement::GetAnimatedAttr(const nsIAtom* aName)
|
||||
}
|
||||
}
|
||||
|
||||
// Integers:
|
||||
{
|
||||
IntegerAttributesInfo info = GetIntegerInfo();
|
||||
for (PRUint32 i = 0; i < info.mIntegerCount; i++) {
|
||||
if (aName == *info.mIntegerInfo[i].mName) {
|
||||
return info.mIntegers[i].ToSMILAttr(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enumerations:
|
||||
{
|
||||
EnumAttributesInfo info = GetEnumInfo();
|
||||
|
@ -157,6 +157,7 @@ public:
|
||||
|
||||
virtual void DidAnimateLength(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateNumber(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateInteger(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateAngle(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateEnum(PRUint8 aAttrEnum);
|
||||
|
@ -323,6 +323,12 @@ nsSVGFE::DidAnimateNumber(PRUint8 aAttrEnum)
|
||||
DidAnimateAttr(this);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGFE::DidAnimateInteger(PRUint8 aAttrEnum)
|
||||
{
|
||||
DidAnimateAttr(this);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGFE::DidAnimateEnum(PRUint8 aAttrEnum)
|
||||
{
|
||||
@ -3203,7 +3209,7 @@ nsSVGFETurbulenceElement::Filter(nsSVGFilterInstance *instance,
|
||||
#endif
|
||||
|
||||
float fX, fY, seed;
|
||||
PRInt32 octaves = mIntegerAttributes[OCTAVES].GetAnimValue();
|
||||
PRInt32 octaves = mIntegerAttributes[OCTAVES].GetAnimValue(this);
|
||||
PRUint16 type = mEnumAttributes[TYPE].GetAnimValue(this);
|
||||
PRUint16 stitch = mEnumAttributes[STITCHTILES].GetAnimValue(this);
|
||||
|
||||
|
@ -219,6 +219,7 @@ protected:
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
virtual void DidAnimateLength(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateNumber(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateInteger(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateEnum(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
|
||||
virtual void DidAnimatePreserveAspectRatio();
|
||||
|
@ -35,7 +35,12 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGInteger.h"
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsSMILValue.h"
|
||||
#include "SMILIntegerType.h"
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGInteger::DOMAnimatedInteger, mSVGElement)
|
||||
|
||||
@ -67,7 +72,14 @@ nsSVGInteger::SetBaseValueString(const nsAString &aValueAsString,
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
mBaseVal = mAnimVal = val;
|
||||
if (val != mBaseVal) {
|
||||
mBaseVal = mAnimVal = val;
|
||||
#ifdef MOZ_SMIL
|
||||
if (mIsAnimated) {
|
||||
aSVGElement->AnimationNeedsResample();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -84,8 +96,23 @@ nsSVGInteger::SetBaseValue(int aValue,
|
||||
nsSVGElement *aSVGElement,
|
||||
PRBool aDoSetAttr)
|
||||
{
|
||||
mAnimVal = mBaseVal = aValue;
|
||||
aSVGElement->DidChangeInteger(mAttrEnum, aDoSetAttr);
|
||||
if (aValue != mBaseVal) {
|
||||
mBaseVal = mAnimVal = aValue;
|
||||
aSVGElement->DidChangeInteger(mAttrEnum, aDoSetAttr);
|
||||
#ifdef MOZ_SMIL
|
||||
if (mIsAnimated) {
|
||||
aSVGElement->AnimationNeedsResample();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGInteger::SetAnimValue(int aValue, nsSVGElement *aSVGElement)
|
||||
{
|
||||
mAnimVal = aValue;
|
||||
mIsAnimated = PR_TRUE;
|
||||
aSVGElement->DidAnimateInteger(mAttrEnum);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -99,3 +126,62 @@ nsSVGInteger::ToDOMAnimatedInteger(nsIDOMSVGAnimatedInteger **aResult,
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
nsISMILAttr*
|
||||
nsSVGInteger::ToSMILAttr(nsSVGElement *aSVGElement)
|
||||
{
|
||||
return new SMILInteger(this, aSVGElement);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGInteger::SMILInteger::ValueFromString(const nsAString& aStr,
|
||||
const nsISMILAnimationElement* /*aSrcElement*/,
|
||||
nsSMILValue& aValue) const
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aStr);
|
||||
const char *str = value.get();
|
||||
|
||||
if (NS_IsAsciiWhitespace(*str))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
char *rest;
|
||||
PRInt32 val = strtol(str, &rest, 10);
|
||||
if (rest == str || *rest != '\0') {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsSMILValue smilVal(&SMILIntegerType::sSingleton);
|
||||
smilVal.mU.mInt = val;
|
||||
aValue = smilVal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsSMILValue
|
||||
nsSVGInteger::SMILInteger::GetBaseValue() const
|
||||
{
|
||||
nsSMILValue val(&SMILIntegerType::sSingleton);
|
||||
val.mU.mInt = mVal->mBaseVal;
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGInteger::SMILInteger::ClearAnimValue()
|
||||
{
|
||||
if (mVal->mIsAnimated) {
|
||||
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
|
||||
mVal->mIsAnimated = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGInteger::SMILInteger::SetAnimValue(const nsSMILValue& aValue)
|
||||
{
|
||||
NS_ASSERTION(aValue.mType == &SMILIntegerType::sSingleton,
|
||||
"Unexpected type to assign animated value");
|
||||
if (aValue.mType == &SMILIntegerType::sSingleton) {
|
||||
mVal->SetAnimValue(int(aValue.mU.mInt), mSVGElement);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
void Init(PRUint8 aAttrEnum = 0xff, PRInt32 aValue = 0) {
|
||||
mAnimVal = mBaseVal = aValue;
|
||||
mAttrEnum = aAttrEnum;
|
||||
mIsAnimated = PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult SetBaseValueString(const nsAString& aValue,
|
||||
@ -58,17 +59,29 @@ public:
|
||||
void SetBaseValue(PRInt32 aValue, nsSVGElement *aSVGElement, PRBool aDoSetAttr);
|
||||
PRInt32 GetBaseValue() const
|
||||
{ return mBaseVal; }
|
||||
PRInt32 GetAnimValue() const
|
||||
{ return mAnimVal; }
|
||||
|
||||
void SetAnimValue(int aValue, nsSVGElement *aSVGElement);
|
||||
int GetAnimValue(nsSVGElement *aSVGElement) const
|
||||
{
|
||||
#ifdef MOZ_SMIL
|
||||
aSVGElement->FlushAnimations();
|
||||
#endif
|
||||
return mAnimVal;
|
||||
}
|
||||
|
||||
nsresult ToDOMAnimatedInteger(nsIDOMSVGAnimatedInteger **aResult,
|
||||
nsSVGElement* aSVGElement);
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// Returns a new nsISMILAttr object that the caller must delete
|
||||
nsISMILAttr* ToSMILAttr(nsSVGElement* aSVGElement);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
private:
|
||||
|
||||
PRInt32 mAnimVal;
|
||||
PRInt32 mBaseVal;
|
||||
PRUint8 mAttrEnum; // element specified tracking for attribute
|
||||
PRPackedBool mIsAnimated;
|
||||
|
||||
struct DOMAnimatedInteger : public nsIDOMSVGAnimatedInteger
|
||||
{
|
||||
@ -86,9 +99,32 @@ private:
|
||||
NS_IMETHOD SetBaseVal(PRInt32 aValue)
|
||||
{ mVal->SetBaseValue(aValue, mSVGElement, PR_TRUE); return NS_OK; }
|
||||
NS_IMETHOD GetAnimVal(PRInt32* aResult)
|
||||
{ *aResult = mVal->GetAnimValue(); return NS_OK; }
|
||||
{ *aResult = mVal->GetAnimValue(mSVGElement); return NS_OK; }
|
||||
|
||||
};
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
struct SMILInteger : public nsISMILAttr
|
||||
{
|
||||
public:
|
||||
SMILInteger(nsSVGInteger* aVal, nsSVGElement* aSVGElement)
|
||||
: mVal(aVal), mSVGElement(aSVGElement) {}
|
||||
|
||||
// These will stay alive because a nsISMILAttr only lives as long
|
||||
// as the Compositing step, and DOM elements don't get a chance to
|
||||
// die during that.
|
||||
nsSVGInteger* mVal;
|
||||
nsSVGElement* mSVGElement;
|
||||
|
||||
// nsISMILAttr methods
|
||||
virtual nsresult ValueFromString(const nsAString& aStr,
|
||||
const nsISMILAnimationElement* aSrcElement,
|
||||
nsSMILValue& aValue) const;
|
||||
virtual nsSMILValue GetBaseValue() const;
|
||||
virtual void ClearAnimValue();
|
||||
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
|
||||
};
|
||||
#endif // MOZ_SMIL
|
||||
};
|
||||
|
||||
#endif //__NS_SVGINTEGER_H__
|
||||
|
@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<filter id="filter_1" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1"/>
|
||||
</filter>
|
||||
<filter id="filter_2" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="2"/>
|
||||
</filter>
|
||||
<filter id="filter_3" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="3"/>
|
||||
</filter>
|
||||
<filter id="filter_4" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4"/>
|
||||
</filter>
|
||||
<rect x="0" y="0" width="20" height="20" filter="url(#filter_3)"/>
|
||||
<rect x="20" y="0" width="20" height="20" filter="url(#filter_4)"/>
|
||||
<rect x="0" y="20" width="20" height="20" filter="url(#filter_2)"/>
|
||||
<rect x="20" y="20" width="20" height="20" filter="url(#filter_1)"/>
|
||||
<rect x="0" y="40" width="20" height="20" filter="url(#filter_3)"/>
|
||||
<rect x="20" y="40" width="20" height="20" filter="url(#filter_4)"/>
|
||||
<rect x="0" y="60" width="20" height="20" filter="url(#filter_2)"/>
|
||||
<rect x="20" y="60" width="20" height="20" filter="url(#filter_1)"/>
|
||||
<rect x="0" y="80" width="20" height="20" filter="url(#filter_1)"/>
|
||||
<rect x="20" y="80" width="20" height="20" filter="url(#filter_4)"/>
|
||||
<rect x="0" y="100" width="20" height="20" filter="url(#filter_4)"/>
|
||||
<rect x="20" y="100" width="20" height="20" filter="url(#filter_1)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
213
layout/reftests/svg/smil/anim-feTurbulence-numOctaves-01.svg
Normal file
213
layout/reftests/svg/smil/anim-feTurbulence-numOctaves-01.svg
Normal file
@ -0,0 +1,213 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="setTimeAndSnapshot(5, true)">
|
||||
<title>Test animation of the "numOctaves" <integer> attribute on the "feTurbulence" element</title>
|
||||
<script xlink:href="smil-util.js" type="text/javascript"/>
|
||||
|
||||
|
||||
<!-- Our implementation strategy for animating integers with
|
||||
calcMode="linear" is to use round(), with the slight twist that we
|
||||
round "to the NEXT value" when the current time puts us exactly midway
|
||||
between two integer values. (This is so that the result of midpoint
|
||||
rounding does not depend on whether we're animating up to a higher
|
||||
value or animating down to a lower value.) Note that one of the quirks
|
||||
of using round() is that the start and end values of any integer
|
||||
range only receive half as much time as any intermediary values. This
|
||||
is as you would expect mathematically, but it's probably unexpected
|
||||
for most users!
|
||||
|
||||
We could try to avoid this round() quirk by coming up with a better
|
||||
implementation strategy for calcMode="linear", but animation of the
|
||||
few integer attributes in SVG 1.1 is extremely unlikely (so this
|
||||
issue is very low priority), and it's actually difficult to find a
|
||||
better strategy that doesn't have its own undesirable quirks.
|
||||
|
||||
One alternative could be to divide the time evenly amoungst each
|
||||
integer. (I.e. it would be similar to calcMode="discrete", except it
|
||||
would also visit all the intermediary values, not just the start and
|
||||
end values). The issue with this approach is that for a simple "to"
|
||||
animation the animation wouldn't actually seem to change anything until
|
||||
interpolation reaches the second integer value. This could be avoided
|
||||
by skipping the initial value and distributing the time between the
|
||||
other values, but then in the case of a "from-to" animation where the
|
||||
from value is different to the underlying attribute value, the
|
||||
animation would seem to skip the first value. Not that the same sort of
|
||||
problem exists at the other end of the simple duration, where it will
|
||||
reach the final integer value before the end of the simple duration.
|
||||
This could be avoided by only setting the final value right at the end
|
||||
of the simple duration and distributing the time between evenly
|
||||
between the other values, but then the final value will only be seen if
|
||||
fill="freeze".
|
||||
|
||||
There are many other problems with other implementation strategies. The
|
||||
more you think about them, add the complexity of 'values', 'by' etc,
|
||||
and think of cases where they behave strangely (e.g. animating between
|
||||
just two adjacent integers, up or down, etc.), the more ugly it gets.
|
||||
It's really not worth it for SVG 1.1. Maybe if you could use SMIL for
|
||||
'font-size' or something even more likely to be animated it would be.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Some calcMode="linear" tests animating *up* to higer values. -->
|
||||
|
||||
<!-- At 5s the animated value should be 3. -->
|
||||
<filter id="filter_1" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="6.1s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="0" width="20" height="20" filter="url(#filter_1)"/>
|
||||
|
||||
<!-- At exactly 5s the animated value should change to 4. -->
|
||||
<filter id="filter_2" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="6s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" width="20" height="20" filter="url(#filter_2)"/>
|
||||
|
||||
|
||||
<!-- Some calcMode="linear" tests animating *down* to lower values. -->
|
||||
|
||||
<!-- At 5s the animated value should be 2. -->
|
||||
<filter id="filter_3" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="6.1s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="0" y="20" width="20" height="20" filter="url(#filter_3)"/>
|
||||
|
||||
<!-- At exactly 5s the animated value should change to 1. -->
|
||||
<filter id="filter_4" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="6s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="20" width="20" height="20" filter="url(#filter_4)"/>
|
||||
|
||||
|
||||
<!-- Some 'by' animation tests -->
|
||||
|
||||
<!-- At 5s the animated value should be 3. -->
|
||||
<filter id="filter_5" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="6.1s"
|
||||
by="3"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect y="40" width="20" height="20" filter="url(#filter_5)"/>
|
||||
|
||||
<!-- At exactly 5s the animated value should change to 4. -->
|
||||
<filter id="filter_6" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="6s"
|
||||
by="3"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="40" width="20" height="20" filter="url(#filter_6)"/>
|
||||
|
||||
|
||||
<!-- calcMode="paced" tests -->
|
||||
|
||||
<!-- At 5s the animated value should be 2. -->
|
||||
<filter id="filter_7" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="paced"
|
||||
begin="0s" dur="6.1s"
|
||||
values="4; 3; 1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect y="60" width="20" height="20" filter="url(#filter_7)"/>
|
||||
|
||||
<!-- At exactly 5s the animated value should change to 1. -->
|
||||
<filter id="filter_8" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="paced"
|
||||
begin="0s" dur="6s"
|
||||
values="4; 3; 1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="60" width="20" height="20" filter="url(#filter_8)"/>
|
||||
|
||||
|
||||
<!-- Some calcMode="discrete" tests animating *up* to higer values. -->
|
||||
|
||||
<!-- At 5s the animated value should be 1. -->
|
||||
<filter id="filter_9" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="10.1s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="0" y="80" width="20" height="20" filter="url(#filter_9)"/>
|
||||
|
||||
<!-- At exactly 5s the animated value should change to 4. -->
|
||||
<filter id="filter_10" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="10s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="80" width="20" height="20" filter="url(#filter_10)"/>
|
||||
|
||||
|
||||
<!-- Some calcMode="discrete" tests animating *down* to lower values. -->
|
||||
|
||||
<!-- At 5s the animated value should be 4. -->
|
||||
<filter id="filter_11" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="10.1s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="0" y="100" width="20" height="20" filter="url(#filter_11)"/>
|
||||
|
||||
<!-- At exactly 5s the animated value should change to 1. -->
|
||||
<filter id="filter_12" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="10s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="100" width="20" height="20" filter="url(#filter_12)"/>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 8.8 KiB |
202
layout/reftests/svg/smil/anim-feTurbulence-numOctaves-02.svg
Normal file
202
layout/reftests/svg/smil/anim-feTurbulence-numOctaves-02.svg
Normal file
@ -0,0 +1,202 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait"
|
||||
onload="setTimeAndSnapshot(3, true)">
|
||||
<title>Test animation of the "numOctaves" <integer> attribute on the "feTurbulence" element</title>
|
||||
<script xlink:href="smil-util.js" type="text/javascript"/>
|
||||
|
||||
<!-- This is an unfinished and unused testcase that would not pass given the
|
||||
current implementation strategy. This testcase assumes that the
|
||||
strategy should be to give each value an equal slice of the simple
|
||||
duration. In other words if animating from 1 to 4 in 4 seconds, then
|
||||
each of the values 1, 2, 3 and 4 would get 1 second each.
|
||||
|
||||
See the comment in anim-feTurbulence-numOctaves-01.svg for more on
|
||||
implementation strategy.
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<!-- Animation of integers is actually more complicated than lengths. It's
|
||||
necessary to "jump" from value to value since you're dealing with
|
||||
discrete integers rather than continuous real numbers.
|
||||
|
||||
The spec doesn't say exactly how to behave, but we assume that the each
|
||||
of the values in a from-to animation gets an equal slice of the simple
|
||||
duration. We also assume that at times that are exactly midway between
|
||||
two integers, we should jump to the "next" integer. In other words, when
|
||||
animating from 0 to 1 in 1 second, at 0.5 seconds the value changes to
|
||||
1; but when animating from 1 to 0 in 1 second, at 0.5 seconds the value
|
||||
changes to 0. This is different from floor(), round() or ceil()
|
||||
behavior, and we test that by animating both "up" and "down" below.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Some tests animating *up* to higer values. -->
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 3.25s - so at 3s the animated value should still be 1. -->
|
||||
<filter id="filter_1" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="13s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect width="20" height="20" filter="url(#filter_1)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 3s - so at exactly 3s the animated value should become 2. -->
|
||||
<filter id="filter_2" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="12s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" width="20" height="20" filter="url(#filter_2)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1.25s - so at 3s the animated value should still be 3. -->
|
||||
<filter id="filter_3" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="5s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="40" width="20" height="20" filter="url(#filter_3)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1s - so at exactly 3s the animated value should become 4. -->
|
||||
<filter id="filter_4" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="4s"
|
||||
to="4"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="60" width="20" height="20" filter="url(#filter_4)"/>
|
||||
|
||||
|
||||
<!-- Some tests animating *down* to lower values. -->
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 3.25s - so at 3s the animated value should still be 4. -->
|
||||
<filter id="filter_5" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="13s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect y="20" width="20" height="20" filter="url(#filter_5)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 3s - so at exactly 3s the animated value should become 3. -->
|
||||
<filter id="filter_6" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="12s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="20" width="20" height="20" filter="url(#filter_6)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1.25s - so at 3s the animated value should still be 2. -->
|
||||
<filter id="filter_7" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="5s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="40" y="20" width="20" height="20" filter="url(#filter_7)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1s - so at exactly 3s the animated value should become 1. -->
|
||||
<filter id="filter_8" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="4s"
|
||||
to="1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="60" y="20" width="20" height="20" filter="url(#filter_8)"/>
|
||||
|
||||
|
||||
<!-- Some 'by' animation tests -->
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1.25s - so at 3s the animated value should still be 3. -->
|
||||
<filter id="filter_9" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="5s"
|
||||
by="3"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect y="40" width="20" height="20" filter="url(#filter_9)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1s - so at exactly 3s the animated value should become 4. -->
|
||||
<filter id="filter_10" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="1">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="linear"
|
||||
begin="0s" dur="4s"
|
||||
by="3"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="40" width="20" height="20" filter="url(#filter_10)"/>
|
||||
|
||||
|
||||
<!-- calcMode="paced" tests -->
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1.25s - so at 3s the animated value should still be 2. -->
|
||||
<filter id="filter_11" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="paced"
|
||||
begin="0s" dur="5s"
|
||||
values="4; 3; 1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect y="60" width="20" height="20" filter="url(#filter_11)"/>
|
||||
|
||||
<!-- Each of the four values should get an equal slice of the duration -
|
||||
that is 1s - so at exactly 3s the animated value should become 1. -->
|
||||
<filter id="filter_12" x="0%" y="0%" width="100%" height="100%">
|
||||
<feTurbulence type="turbulence" baseFrequency="0.01" numOctaves="4">
|
||||
<animate attributeName="numOctaves"
|
||||
calcMode="paced"
|
||||
begin="0s" dur="4s"
|
||||
values="4; 3; 1"
|
||||
fill="freeze"/>
|
||||
</feTurbulence>
|
||||
</filter>
|
||||
<rect x="20" y="60" width="20" height="20" filter="url(#filter_12)"/>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 8.3 KiB |
@ -81,6 +81,9 @@ fails == anim-fillopacity-1xml.svg anim-standard-ref.svg # bug 534028
|
||||
== anim-offset-01.svg lime.svg
|
||||
== anim-pathLength-01.svg anim-pathLength-01-ref.svg
|
||||
|
||||
# animate some <integer> attributes:
|
||||
== anim-feTurbulence-numOctaves-01.svg anim-feTurbulence-numOctaves-01-ref.svg
|
||||
|
||||
# animate some <angle> attributes:
|
||||
== anim-marker-orient-01.svg lime.svg
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user