Bug 615666 - SMIL animation does not work with percent units for "offset" attr on <stop> elements. r=jwatt a=roc

--HG--
extra : rebase_source : 9907e24c397c5e7971256c3f0164255420585824
This commit is contained in:
Robert Longson 2010-12-05 20:33:31 +00:00
parent 9bab925233
commit 223bcc21ec
8 changed files with 86 additions and 113 deletions

View File

@ -167,6 +167,9 @@ public:
PRBool IsStringAnimatable(PRUint8 aAttrEnum) {
return GetStringInfo().mStringInfo[aAttrEnum].mIsAnimatable;
}
PRBool NumberAttrAllowsPercentage(PRUint8 aAttrEnum) {
return GetNumberInfo().mNumberInfo[aAttrEnum].mPercentagesAllowed;
}
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeNumber(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeInteger(PRUint8 aAttrEnum, PRBool aDoSetAttr);
@ -275,6 +278,7 @@ protected:
struct NumberInfo {
nsIAtom** mName;
float mDefaultValue;
PRPackedBool mPercentagesAllowed;
};
struct NumberAttributesInfo {

View File

@ -431,8 +431,8 @@ private:
nsSVGElement::NumberInfo nsSVGFEGaussianBlurElement::sNumberInfo[2] =
{
{ &nsGkAtoms::stdDeviation, 0 },
{ &nsGkAtoms::stdDeviation, 0 }
{ &nsGkAtoms::stdDeviation, 0, PR_FALSE },
{ &nsGkAtoms::stdDeviation, 0, PR_FALSE }
};
nsSVGElement::StringInfo nsSVGFEGaussianBlurElement::sStringInfo[2] =
@ -1416,10 +1416,10 @@ protected:
nsSVGElement::NumberInfo nsSVGFECompositeElement::sNumberInfo[4] =
{
{ &nsGkAtoms::k1, 0 },
{ &nsGkAtoms::k2, 0 },
{ &nsGkAtoms::k3, 0 },
{ &nsGkAtoms::k4, 0 }
{ &nsGkAtoms::k1, 0, PR_FALSE },
{ &nsGkAtoms::k2, 0, PR_FALSE },
{ &nsGkAtoms::k3, 0, PR_FALSE },
{ &nsGkAtoms::k4, 0, PR_FALSE }
};
nsSVGEnumMapping nsSVGFECompositeElement::sOperatorMap[] = {
@ -1871,11 +1871,11 @@ nsSVGElement::NumberListInfo nsSVGComponentTransferFunctionElement::sNumberListI
nsSVGElement::NumberInfo nsSVGComponentTransferFunctionElement::sNumberInfo[5] =
{
{ &nsGkAtoms::slope, 1 },
{ &nsGkAtoms::intercept, 0 },
{ &nsGkAtoms::amplitude, 1 },
{ &nsGkAtoms::exponent, 1 },
{ &nsGkAtoms::offset, 0 }
{ &nsGkAtoms::slope, 1, PR_FALSE },
{ &nsGkAtoms::intercept, 0, PR_FALSE },
{ &nsGkAtoms::amplitude, 1, PR_FALSE },
{ &nsGkAtoms::exponent, 1, PR_FALSE },
{ &nsGkAtoms::offset, 0, PR_FALSE }
};
nsSVGEnumMapping nsSVGComponentTransferFunctionElement::sTypeMap[] = {
@ -2519,8 +2519,8 @@ protected:
nsSVGElement::NumberInfo nsSVGFEOffsetElement::sNumberInfo[2] =
{
{ &nsGkAtoms::dx, 0 },
{ &nsGkAtoms::dy, 0 }
{ &nsGkAtoms::dx, 0, PR_FALSE },
{ &nsGkAtoms::dy, 0, PR_FALSE }
};
nsSVGElement::StringInfo nsSVGFEOffsetElement::sStringInfo[2] =
@ -3126,9 +3126,9 @@ private:
nsSVGElement::NumberInfo nsSVGFETurbulenceElement::sNumberInfo[3] =
{
{ &nsGkAtoms::baseFrequency, 0 },
{ &nsGkAtoms::baseFrequency, 0 },
{ &nsGkAtoms::seed, 0 }
{ &nsGkAtoms::baseFrequency, 0, PR_FALSE },
{ &nsGkAtoms::baseFrequency, 0, PR_FALSE },
{ &nsGkAtoms::seed, 0, PR_FALSE }
};
nsSVGElement::IntegerInfo nsSVGFETurbulenceElement::sIntegerInfo[1] =
@ -3584,8 +3584,8 @@ protected:
nsSVGElement::NumberInfo nsSVGFEMorphologyElement::sNumberInfo[2] =
{
{ &nsGkAtoms::radius, 0 },
{ &nsGkAtoms::radius, 0 }
{ &nsGkAtoms::radius, 0, PR_FALSE },
{ &nsGkAtoms::radius, 0, PR_FALSE }
};
nsSVGEnumMapping nsSVGFEMorphologyElement::sOperatorMap[] = {
@ -3927,10 +3927,10 @@ protected:
nsSVGElement::NumberInfo nsSVGFEConvolveMatrixElement::sNumberInfo[4] =
{
{ &nsGkAtoms::divisor, 1 },
{ &nsGkAtoms::bias, 0 },
{ &nsGkAtoms::kernelUnitLength, 0 },
{ &nsGkAtoms::kernelUnitLength, 0 }
{ &nsGkAtoms::divisor, 1, PR_FALSE },
{ &nsGkAtoms::bias, 0, PR_FALSE },
{ &nsGkAtoms::kernelUnitLength, 0, PR_FALSE },
{ &nsGkAtoms::kernelUnitLength, 0, PR_FALSE }
};
nsSVGElement::IntegerInfo nsSVGFEConvolveMatrixElement::sIntegerInfo[4] =
@ -4348,8 +4348,8 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(FEDistantLight)
nsSVGElement::NumberInfo nsSVGFEDistantLightElement::sNumberInfo[2] =
{
{ &nsGkAtoms::azimuth, 0 },
{ &nsGkAtoms::elevation, 0 }
{ &nsGkAtoms::azimuth, 0, PR_FALSE },
{ &nsGkAtoms::elevation, 0, PR_FALSE }
};
//----------------------------------------------------------------------
@ -4441,9 +4441,9 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(FEPointLight)
nsSVGElement::NumberInfo nsSVGFEPointLightElement::sNumberInfo[3] =
{
{ &nsGkAtoms::x, 0 },
{ &nsGkAtoms::y, 0 },
{ &nsGkAtoms::z, 0 }
{ &nsGkAtoms::x, 0, PR_FALSE },
{ &nsGkAtoms::y, 0, PR_FALSE },
{ &nsGkAtoms::z, 0, PR_FALSE }
};
//----------------------------------------------------------------------
@ -4540,14 +4540,14 @@ NS_IMPL_NS_NEW_SVG_ELEMENT(FESpotLight)
nsSVGElement::NumberInfo nsSVGFESpotLightElement::sNumberInfo[8] =
{
{ &nsGkAtoms::x, 0 },
{ &nsGkAtoms::y, 0 },
{ &nsGkAtoms::z, 0 },
{ &nsGkAtoms::pointsAtX, 0 },
{ &nsGkAtoms::pointsAtY, 0 },
{ &nsGkAtoms::pointsAtZ, 0 },
{ &nsGkAtoms::specularExponent, 1 },
{ &nsGkAtoms::limitingConeAngle, 0 }
{ &nsGkAtoms::x, 0, PR_FALSE },
{ &nsGkAtoms::y, 0, PR_FALSE },
{ &nsGkAtoms::z, 0, PR_FALSE },
{ &nsGkAtoms::pointsAtX, 0, PR_FALSE },
{ &nsGkAtoms::pointsAtY, 0, PR_FALSE },
{ &nsGkAtoms::pointsAtZ, 0, PR_FALSE },
{ &nsGkAtoms::specularExponent, 1, PR_FALSE },
{ &nsGkAtoms::limitingConeAngle, 0, PR_FALSE }
};
//----------------------------------------------------------------------
@ -4689,12 +4689,12 @@ protected:
nsSVGElement::NumberInfo nsSVGFELightingElement::sNumberInfo[6] =
{
{ &nsGkAtoms::surfaceScale, 1 },
{ &nsGkAtoms::diffuseConstant, 1 },
{ &nsGkAtoms::specularConstant, 1 },
{ &nsGkAtoms::specularExponent, 1 },
{ &nsGkAtoms::kernelUnitLength, 0 },
{ &nsGkAtoms::kernelUnitLength, 0 }
{ &nsGkAtoms::surfaceScale, 1, PR_FALSE },
{ &nsGkAtoms::diffuseConstant, 1, PR_FALSE },
{ &nsGkAtoms::specularConstant, 1, PR_FALSE },
{ &nsGkAtoms::specularExponent, 1, PR_FALSE },
{ &nsGkAtoms::kernelUnitLength, 0, PR_FALSE },
{ &nsGkAtoms::kernelUnitLength, 0, PR_FALSE }
};
nsSVGElement::StringInfo nsSVGFELightingElement::sStringInfo[2] =
@ -5727,7 +5727,7 @@ protected:
nsSVGElement::NumberInfo nsSVGFEDisplacementMapElement::sNumberInfo[1] =
{
{ &nsGkAtoms::scale, 0 },
{ &nsGkAtoms::scale, 0, PR_FALSE },
};
nsSVGEnumMapping nsSVGFEDisplacementMapElement::sChannelMap[] = {

View File

@ -86,10 +86,10 @@ NS_INTERFACE_MAP_END
/* Implementation */
nsresult
nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
static nsresult
GetValueFromString(const nsAString &aValueAsString,
PRBool aPercentagesAllowed,
float *aValue)
{
NS_ConvertUTF16toUTF8 value(aValueAsString);
const char *str = value.get();
@ -98,10 +98,33 @@ nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
return NS_ERROR_DOM_SYNTAX_ERR;
char *rest;
float val = float(PR_strtod(str, &rest));
if (rest == str || *rest != '\0' || !NS_FloatIsFinite(val)) {
*aValue = float(PR_strtod(str, &rest));
if (rest == str || !NS_FloatIsFinite(*aValue)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
if (*rest == '%' && aPercentagesAllowed) {
*aValue /= 100;
++rest;
}
if (*rest == '\0') {
return NS_OK;
}
return NS_ERROR_DOM_SYNTAX_ERR;
}
nsresult
nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
float val;
nsresult rv = GetValueFromString(
aValueAsString, aSVGElement->NumberAttrAllowsPercentage(mAttrEnum), &val);
if (NS_FAILED(rv)) {
return rv;
}
mBaseVal = val;
if (!mIsAnimated) {
@ -178,9 +201,11 @@ nsSVGNumber2::SMILNumber::ValueFromString(const nsAString& aStr,
{
float value;
PRBool ok = nsSVGUtils::NumberFromString(aStr, &value);
if (!ok) {
return NS_ERROR_FAILURE;
nsresult rv = GetValueFromString(
aStr, mSVGElement->NumberAttrAllowsPercentage(mVal->mAttrEnum), &value);
if (NS_FAILED(rv)) {
return rv;
}
nsSMILValue val(&nsSMILFloatType::sSingleton);

View File

@ -53,7 +53,7 @@
using namespace mozilla;
nsSVGElement::NumberInfo nsSVGPathElement::sNumberInfo =
{ &nsGkAtoms::pathLength, 0 };
{ &nsGkAtoms::pathLength, 0, PR_FALSE };
NS_IMPL_NS_NEW_SVG_ELEMENT(Path)

View File

@ -66,8 +66,6 @@ public:
// nsIContent interface
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
PRBool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
const nsAString& aValue, nsAttrValue& aResult);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@ -80,8 +78,9 @@ protected:
static NumberInfo sNumberInfo;
};
nsSVGElement::NumberInfo nsSVGStopElement::sNumberInfo = { &nsGkAtoms::offset,
0 };
nsSVGElement::NumberInfo nsSVGStopElement::sNumberInfo =
{ &nsGkAtoms::offset, 0, PR_TRUE };
NS_IMPL_NS_NEW_SVG_ELEMENT(Stop)
//----------------------------------------------------------------------
@ -130,27 +129,6 @@ nsSVGStopElement::GetNumberInfo()
return NumberAttributesInfo(&mOffset, &sNumberInfo, 1);
}
PRBool
nsSVGStopElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::offset) {
float offset = 0;
PRBool ok = nsSVGUtils::NumberFromString(aValue, &offset, PR_TRUE);
if (ok) {
mOffset.SetBaseValue(offset, this, PR_FALSE);
aResult.SetTo(aValue);
return PR_TRUE;
}
}
}
return nsSVGElement::ParseAttribute(aNamespaceID, aAttribute,
aValue, aResult);
}
//----------------------------------------------------------------------
// nsIContent methods

View File

@ -10,7 +10,7 @@
<animate attributeName="offset" attributeType="XML"
calcMode="linear"
begin="0s" dur="2s"
to="1"
to="100%"
fill="freeze"/>
</stop>
<stop stop-color="red" offset="0">
@ -28,7 +28,7 @@
<animate attributeName="offset" attributeType="XML"
calcMode="linear"
begin="0s" dur="1s"
to="1"
to="100%"
fill="freeze"/>
</stop>
<stop stop-color="red" offset="0">

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1495,29 +1495,6 @@ nsSVGUtils::IsInnerSVG(nsIContent* aContent)
ancestor->Tag() != nsGkAtoms::foreignObject;
}
/* static */ PRBool
nsSVGUtils::NumberFromString(const nsAString& aString, float* aValue,
PRBool aAllowPercentages)
{
NS_ConvertUTF16toUTF8 s(aString);
const char *str = s.get();
char *rest;
float value = float(PR_strtod(str, &rest));
if (str != rest && NS_FloatIsFinite(value)) {
if (aAllowPercentages && *rest == '%') {
value /= 100;
++rest;
}
// XXX should allow trailing whitespace
if (*rest == '\0') {
*aValue = value;
return PR_TRUE;
}
}
return PR_FALSE;
}
// ----------------------------------------------------------------------
nsSVGRenderState::nsSVGRenderState(nsIRenderingContext *aContext) :

View File

@ -586,17 +586,6 @@ public:
*/
static PRBool IsInnerSVG(nsIContent* aContent);
/**
* Parse a string that may contain either a CSS <number> or, if
* aAllowPercentages is set to true, a CSS <percentage>, and return the
* number as a float.
*
* This helper returns PR_TRUE if a number was successfully parsed from the
* string and no characters were left, else it returns PR_FALSE.
*/
static PRBool NumberFromString(const nsAString& aString, float* aValue,
PRBool aAllowPercentages = PR_FALSE);
/**
* Convert a floating-point value to a 32-bit integer value, clamping to
* the range of valid integers.