mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Bug 386416 - Integer and Number pair attributes such as the order attribute of feConvolveMatrix should allow an optional comma as separator. r=tor,sr+a=roc
This commit is contained in:
parent
21584561f2
commit
9cfc5cc86a
@ -86,6 +86,7 @@
|
||||
#include "nsIDOMSVGAnimatedRect.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsSVGAnimatedString.h"
|
||||
#include "prdtoa.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
nsSVGEnumMapping nsSVGElement::sSVGUnitTypesMap[] = {
|
||||
@ -1163,6 +1164,106 @@ nsSVGElement::DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr)
|
||||
newStr, PR_TRUE);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGElement::ParseNumberOptionalNumber(nsIAtom* aAttribute, const nsAString& aValue,
|
||||
PRUint32 aIndex1, PRUint32 aIndex2,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aValue);
|
||||
const char *str = value.get();
|
||||
|
||||
PRBool parseError = NS_IsAsciiWhitespace(*str);
|
||||
float x, y;
|
||||
|
||||
if (!parseError) {
|
||||
char *rest;
|
||||
x = y = float(PR_strtod(str, &rest));
|
||||
|
||||
if (str == rest) {
|
||||
//first value was illformed
|
||||
parseError = PR_TRUE;
|
||||
} else if (*rest != '\0') {
|
||||
while (NS_IsAsciiWhitespace(*rest)) {
|
||||
++rest;
|
||||
}
|
||||
if (*rest == ',') {
|
||||
++rest;
|
||||
}
|
||||
|
||||
y = float(PR_strtod(rest, &rest));
|
||||
if (*rest != '\0') {
|
||||
//second value was illformed or there was trailing content
|
||||
parseError = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NumberAttributesInfo numberInfo = GetNumberInfo();
|
||||
|
||||
if (parseError) {
|
||||
ReportAttributeParseFailure(GetOwnerDoc(), aAttribute, aValue);
|
||||
x = numberInfo.mNumberInfo[aIndex1].mDefaultValue;
|
||||
y = numberInfo.mNumberInfo[aIndex2].mDefaultValue;
|
||||
} else {
|
||||
aResult.SetTo(aValue);
|
||||
}
|
||||
|
||||
numberInfo.mNumbers[aIndex1].SetBaseValue(x, this, PR_FALSE);
|
||||
numberInfo.mNumbers[aIndex2].SetBaseValue(y, this, PR_FALSE);
|
||||
|
||||
return (!parseError);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGElement::ParseIntegerOptionalInteger(nsIAtom* aAttribute, const nsAString& aValue,
|
||||
PRUint32 aIndex1, PRUint32 aIndex2,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aValue);
|
||||
const char *str = value.get();
|
||||
|
||||
PRBool parseError = NS_IsAsciiWhitespace(*str);
|
||||
PRInt32 x, y;
|
||||
|
||||
if (!parseError) {
|
||||
char *rest;
|
||||
x = y = strtol(str, &rest, 10);
|
||||
|
||||
if (str == rest) {
|
||||
//first value was illformed
|
||||
parseError = PR_TRUE;
|
||||
} else if (*rest != '\0') {
|
||||
while (NS_IsAsciiWhitespace(*rest)) {
|
||||
++rest;
|
||||
}
|
||||
if (*rest == ',') {
|
||||
++rest;
|
||||
}
|
||||
|
||||
y = strtol(rest, &rest, 10);
|
||||
if (*rest != '\0') {
|
||||
//second value was illformed or there was trailing content
|
||||
parseError = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IntegerAttributesInfo integerInfo = GetIntegerInfo();
|
||||
|
||||
if (parseError) {
|
||||
ReportAttributeParseFailure(GetOwnerDoc(), aAttribute, aValue);
|
||||
x = integerInfo.mIntegerInfo[aIndex1].mDefaultValue;
|
||||
y = integerInfo.mIntegerInfo[aIndex2].mDefaultValue;
|
||||
} else {
|
||||
aResult.SetTo(aValue);
|
||||
}
|
||||
|
||||
integerInfo.mIntegers[aIndex1].SetBaseValue(x, this, PR_FALSE);
|
||||
integerInfo.mIntegers[aIndex2].SetBaseValue(y, this, PR_FALSE);
|
||||
|
||||
return (!parseError);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGElement::ReportAttributeParseFailure(nsIDocument* aDocument,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -267,6 +267,18 @@ protected:
|
||||
|
||||
static nsSVGEnumMapping sSVGUnitTypesMap[];
|
||||
|
||||
/* read <number-optional-number> */
|
||||
PRBool
|
||||
ParseNumberOptionalNumber(nsIAtom* aAttribute, const nsAString& aValue,
|
||||
PRUint32 aIndex1, PRUint32 aIndex2,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
/* read <integer-optional-integer> */
|
||||
PRBool
|
||||
ParseIntegerOptionalInteger(nsIAtom* aAttribute, const nsAString& aValue,
|
||||
PRUint32 aIndex1, PRUint32 aIndex2,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
static nsresult ReportAttributeParseFailure(nsIDocument* aDocument,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue);
|
||||
|
@ -196,35 +196,18 @@ nsSVGFilterElement::GetHref(nsIDOMSVGAnimatedString * *aHref)
|
||||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
nsresult
|
||||
nsSVGFilterElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
PRBool
|
||||
nsSVGFilterElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
nsresult rv = nsSVGFilterElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
|
||||
if (aName == nsGkAtoms::filterRes && aNameSpaceID == kNameSpaceID_None) {
|
||||
PRUint32 resX, resY;
|
||||
char *str;
|
||||
str = ToNewCString(aValue);
|
||||
int num = sscanf(str, "%d %d\n", &resX, &resY);
|
||||
switch (num) {
|
||||
case 2:
|
||||
mIntegerAttributes[FILTERRES_X].SetBaseValue(resX, this, PR_FALSE);
|
||||
mIntegerAttributes[FILTERRES_Y].SetBaseValue(resY, this, PR_FALSE);
|
||||
break;
|
||||
case 1:
|
||||
mIntegerAttributes[FILTERRES_X].SetBaseValue(resX, this, PR_FALSE);
|
||||
mIntegerAttributes[FILTERRES_Y].SetBaseValue(resX, this, PR_FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
nsMemory::Free(str);
|
||||
return ParseIntegerOptionalInteger(aName, aValue,
|
||||
FILTERRES_X, FILTERRES_Y,
|
||||
aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return nsSVGFilterElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
aValue, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
|
@ -77,15 +77,15 @@ public:
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFilterElementBase::)
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual PRBool ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
virtual IntegerAttributesInfo GetIntegerInfo();
|
||||
virtual EnumAttributesInfo GetEnumInfo();
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include "nsISVGValueUtils.h"
|
||||
#include "nsSVGFilters.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "prdtoa.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIFrame.h"
|
||||
@ -300,52 +299,6 @@ nsSVGFE::Init()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGFE::ScanDualValueAttribute(const nsAString& aValue, nsIAtom* aAttribute,
|
||||
nsSVGNumber2* aNum1, nsSVGNumber2* aNum2,
|
||||
NumberInfo* aInfo1, NumberInfo* aInfo2,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
float x = 0.0f, y = 0.0f;
|
||||
char *rest;
|
||||
PRBool parseError = PR_FALSE;
|
||||
|
||||
NS_ConvertUTF16toUTF8 value(aValue);
|
||||
value.CompressWhitespace(PR_FALSE, PR_TRUE);
|
||||
const char *str = value.get();
|
||||
x = static_cast<float>(PR_strtod(str, &rest));
|
||||
if (str == rest) {
|
||||
//first value was illformed
|
||||
parseError = PR_TRUE;
|
||||
} else {
|
||||
if (*rest == '\0') {
|
||||
//second value was not supplied
|
||||
y = x;
|
||||
} else {
|
||||
y = static_cast<float>(PR_strtod(rest, &rest));
|
||||
if (*rest != '\0') {
|
||||
//second value was illformed or there was trailing content
|
||||
parseError = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parseError) {
|
||||
ReportAttributeParseFailure(GetOwnerDoc(), aAttribute, aValue);
|
||||
x = aInfo1->mDefaultValue;
|
||||
y = aInfo2->mDefaultValue;
|
||||
}
|
||||
|
||||
aNum1->SetBaseValue(x, this, PR_FALSE);
|
||||
aNum2->SetBaseValue(y, this, PR_FALSE);
|
||||
|
||||
if (parseError)
|
||||
return PR_FALSE;
|
||||
|
||||
aResult.SetTo(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGFE::SetupScalingFilter(nsSVGFilterInstance *aInstance,
|
||||
nsSVGFilterResource *aResource,
|
||||
@ -643,12 +596,9 @@ nsSVGFEGaussianBlurElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aName == nsGkAtoms::stdDeviation && aNameSpaceID == kNameSpaceID_None) {
|
||||
return ScanDualValueAttribute(aValue, nsGkAtoms::stdDeviation,
|
||||
&mNumberAttributes[STD_DEV_X],
|
||||
&mNumberAttributes[STD_DEV_Y],
|
||||
&sNumberInfo[STD_DEV_X],
|
||||
&sNumberInfo[STD_DEV_Y],
|
||||
aResult);
|
||||
return ParseNumberOptionalNumber(aName, aValue,
|
||||
STD_DEV_X, STD_DEV_Y,
|
||||
aResult);
|
||||
}
|
||||
return nsSVGFEGaussianBlurElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
aValue, aResult);
|
||||
@ -3203,12 +3153,9 @@ nsSVGFETurbulenceElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aName == nsGkAtoms::baseFrequency && aNameSpaceID == kNameSpaceID_None) {
|
||||
return ScanDualValueAttribute(aValue, nsGkAtoms::baseFrequency,
|
||||
&mNumberAttributes[BASE_FREQ_X],
|
||||
&mNumberAttributes[BASE_FREQ_Y],
|
||||
&sNumberInfo[BASE_FREQ_X],
|
||||
&sNumberInfo[BASE_FREQ_Y],
|
||||
aResult);
|
||||
return ParseNumberOptionalNumber(aName, aValue,
|
||||
BASE_FREQ_X, BASE_FREQ_Y,
|
||||
aResult);
|
||||
}
|
||||
return nsSVGFETurbulenceElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
aValue, aResult);
|
||||
@ -3658,12 +3605,9 @@ nsSVGFEMorphologyElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aName == nsGkAtoms::radius && aNameSpaceID == kNameSpaceID_None) {
|
||||
return ScanDualValueAttribute(aValue, nsGkAtoms::radius,
|
||||
&mNumberAttributes[RADIUS_X],
|
||||
&mNumberAttributes[RADIUS_Y],
|
||||
&sNumberInfo[RADIUS_X],
|
||||
&sNumberInfo[RADIUS_Y],
|
||||
aResult);
|
||||
return ParseNumberOptionalNumber(aName, aValue,
|
||||
RADIUS_X, RADIUS_Y,
|
||||
aResult);
|
||||
}
|
||||
return nsSVGFEMorphologyElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
aValue, aResult);
|
||||
@ -4038,54 +3982,17 @@ nsSVGFEConvolveMatrixElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aNam
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aName == nsGkAtoms::order && aNameSpaceID == kNameSpaceID_None) {
|
||||
PRInt32 x = 0, y = 0;
|
||||
char *rest;
|
||||
PRBool parseError = PR_FALSE;
|
||||
|
||||
NS_ConvertUTF16toUTF8 value(aValue);
|
||||
value.CompressWhitespace(PR_FALSE, PR_TRUE);
|
||||
const char *str = value.get();
|
||||
x = strtol(str, &rest, 10);
|
||||
if (str == rest) {
|
||||
//first value was illformed
|
||||
parseError = PR_TRUE;
|
||||
} else {
|
||||
if (*rest == '\0') {
|
||||
//second value was not supplied
|
||||
y = x;
|
||||
} else {
|
||||
y = strtol(rest, &rest, 10);
|
||||
if (*rest != '\0') {
|
||||
//second value was illformed or there was trailing content
|
||||
parseError = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::order) {
|
||||
return ParseIntegerOptionalInteger(aName, aValue,
|
||||
ORDER_X, ORDER_Y,
|
||||
aResult);
|
||||
}
|
||||
|
||||
if (parseError) {
|
||||
ReportAttributeParseFailure(GetOwnerDoc(), aName, aValue);
|
||||
x = sIntegerInfo[ORDER_X].mDefaultValue;
|
||||
y = sIntegerInfo[ORDER_Y].mDefaultValue;
|
||||
if (aName == nsGkAtoms::kernelUnitLength) {
|
||||
return ParseNumberOptionalNumber(aName, aValue,
|
||||
KERNEL_UNIT_LENGTH_X, KERNEL_UNIT_LENGTH_Y,
|
||||
aResult);
|
||||
}
|
||||
|
||||
mIntegerAttributes[ORDER_X].SetBaseValue(x, this, PR_FALSE);
|
||||
mIntegerAttributes[ORDER_Y].SetBaseValue(y, this, PR_FALSE);
|
||||
|
||||
if (parseError)
|
||||
return PR_FALSE;
|
||||
|
||||
aResult.SetTo(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::kernelUnitLength && aNameSpaceID == kNameSpaceID_None) {
|
||||
return ScanDualValueAttribute(aValue, nsGkAtoms::kernelUnitLength,
|
||||
&mNumberAttributes[KERNEL_UNIT_LENGTH_X],
|
||||
&mNumberAttributes[KERNEL_UNIT_LENGTH_Y],
|
||||
&sNumberInfo[KERNEL_UNIT_LENGTH_X],
|
||||
&sNumberInfo[KERNEL_UNIT_LENGTH_Y],
|
||||
aResult);
|
||||
}
|
||||
|
||||
return nsSVGFEConvolveMatrixElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
@ -4710,15 +4617,13 @@ nsSVGFELightingElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aName == nsGkAtoms::kernelUnitLength && aNameSpaceID == kNameSpaceID_None) {
|
||||
return ScanDualValueAttribute(aValue, nsGkAtoms::radius,
|
||||
&mNumberAttributes[KERNEL_UNIT_LENGTH_X],
|
||||
&mNumberAttributes[KERNEL_UNIT_LENGTH_Y],
|
||||
&sNumberInfo[KERNEL_UNIT_LENGTH_X],
|
||||
&sNumberInfo[KERNEL_UNIT_LENGTH_Y],
|
||||
aResult);
|
||||
return ParseNumberOptionalNumber(aName, aValue,
|
||||
KERNEL_UNIT_LENGTH_X, KERNEL_UNIT_LENGTH_Y,
|
||||
aResult);
|
||||
|
||||
}
|
||||
return nsSVGFELightingElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
aValue, aResult);
|
||||
aValue, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -55,11 +55,6 @@ protected:
|
||||
nsSVGFE(nsINodeInfo *aNodeInfo) : nsSVGFEBase(aNodeInfo) {}
|
||||
nsresult Init();
|
||||
|
||||
PRBool ScanDualValueAttribute(const nsAString& aValue, nsIAtom* aAttribute,
|
||||
nsSVGNumber2* aNum1, nsSVGNumber2* aNum2,
|
||||
NumberInfo* aInfo1, NumberInfo* aInfo2,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
struct ScaleInfo {
|
||||
nsRefPtr<gfxImageSurface> mRealSource;
|
||||
nsRefPtr<gfxImageSurface> mRealTarget;
|
||||
|
Loading…
Reference in New Issue
Block a user