Bug 617623 - animate number-optional-number and integer-optional-integer attributes properly. r=dholbert

This commit is contained in:
Robert Longson 2011-07-01 08:19:52 +01:00
parent f5d223bf5b
commit 688d372901
32 changed files with 1953 additions and 370 deletions

View File

@ -97,6 +97,8 @@ public:
PRUint16 mUnit;
PRUint16 mOrientType;
} mOrient;
PRInt32 mIntPair[2];
float mNumberPair[2];
void* mPtr;
} mU;
const nsISMILType* mType;

View File

@ -85,6 +85,7 @@ CPPSRCS = \
nsSVGGraphicElement.cpp \
nsSVGImageElement.cpp \
nsSVGInteger.cpp \
nsSVGIntegerPair.cpp \
nsSVGLength2.cpp \
nsSVGLineElement.cpp \
nsSVGMarkerElement.cpp \
@ -92,6 +93,7 @@ CPPSRCS = \
nsSVGMatrix.cpp \
nsSVGMetadataElement.cpp \
nsSVGNumber2.cpp \
nsSVGNumberPair.cpp \
nsSVGPathDataParser.cpp \
nsSVGPathElement.cpp \
nsSVGPathGeometryElement.cpp \
@ -144,12 +146,14 @@ CPPSRCS += nsSVGAnimateElement.cpp \
nsSVGSetElement.cpp \
nsSVGTransformSMILType.cpp \
nsSVGTransformSMILAttr.cpp \
SVGIntegerPairSMILType.cpp \
SVGLengthListSMILType.cpp \
SVGMotionSMILType.cpp \
SVGMotionSMILAttr.cpp \
SVGMotionSMILAnimationFunction.cpp \
SVGMotionSMILPathUtils.cpp \
SVGNumberListSMILType.cpp \
SVGNumberPairSMILType.cpp \
SVGOrientSMILType.cpp \
SVGPathSegListSMILType.cpp \
SVGPointListSMILType.cpp \

View File

@ -69,6 +69,7 @@ SVGAnimatedNumberList::SetBaseValueString(const nsAString& aValue)
// nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
// which takes care of notifying.
mIsBaseSet = PR_TRUE;
rv = mBaseVal.CopyFrom(newBaseValue);
if (NS_FAILED(rv) && domWrapper) {
// Attempting to increase mBaseVal's length failed - reduce domWrapper
@ -88,6 +89,7 @@ SVGAnimatedNumberList::ClearBaseValue(PRUint32 aAttrEnum)
domWrapper->InternalBaseValListWillChangeTo(SVGNumberList());
}
mBaseVal.Clear();
mIsBaseSet = PR_FALSE;
// Caller notifies
}

View File

@ -96,6 +96,14 @@ public:
void ClearAnimValue(nsSVGElement *aElement,
PRUint32 aAttrEnum);
// Returns PR_TRUE if the animated value of this list has been explicitly
// set (either by animation, or by taking on the base value which has been
// explicitly set by markup or a DOM call), PR_FALSE otherwise.
// If this returns PR_FALSE, the animated value is still valid, that is,
// useable, and represents the default base value of the attribute.
PRBool IsExplicitlySet() const
{ return !!mAnimVal || mIsBaseSet; }
PRBool IsAnimating() const {
return !!mAnimVal;
}
@ -114,6 +122,7 @@ private:
SVGNumberList mBaseVal;
nsAutoPtr<SVGNumberList> mAnimVal;
PRPackedBool mIsBaseSet;
#ifdef MOZ_SMIL
struct SMILAnimatedNumberList : public nsISMILAttr

View File

@ -0,0 +1,141 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* 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 "SVGIntegerPairSMILType.h"
#include "nsSMILValue.h"
#include "nsMathUtils.h"
#include "nsDebug.h"
#include <math.h>
namespace mozilla {
/*static*/ SVGIntegerPairSMILType SVGIntegerPairSMILType::sSingleton;
void
SVGIntegerPairSMILType::Init(nsSMILValue& aValue) const
{
NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected value type");
aValue.mU.mIntPair[0] = 0;
aValue.mU.mIntPair[1] = 0;
aValue.mType = this;
}
void
SVGIntegerPairSMILType::Destroy(nsSMILValue& aValue) const
{
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
aValue.mU.mIntPair[0] = 0;
aValue.mU.mIntPair[1] = 0;
aValue.mType = &nsSMILNullType::sSingleton;
}
nsresult
SVGIntegerPairSMILType::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.mIntPair[0] = aSrc.mU.mIntPair[0];
aDest.mU.mIntPair[1] = aSrc.mU.mIntPair[1];
return NS_OK;
}
PRBool
SVGIntegerPairSMILType::IsEqual(const nsSMILValue& aLeft,
const nsSMILValue& aRight) const
{
NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
return aLeft.mU.mIntPair[0] == aRight.mU.mIntPair[0] &&
aLeft.mU.mIntPair[1] == aRight.mU.mIntPair[1];
}
nsresult
SVGIntegerPairSMILType::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.mIntPair[0] += aValueToAdd.mU.mIntPair[0] * aCount;
aDest.mU.mIntPair[1] += aValueToAdd.mU.mIntPair[1] * aCount;
return NS_OK;
}
nsresult
SVGIntegerPairSMILType::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");
double delta[2];
delta[0] = aTo.mU.mIntPair[0] - aFrom.mU.mIntPair[0];
delta[1] = aTo.mU.mIntPair[1] - aFrom.mU.mIntPair[1];
aDistance = NS_hypot(delta[0], delta[1]);
return NS_OK;
}
nsresult
SVGIntegerPairSMILType::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");
double currentVal[2];
currentVal[0] = aStartVal.mU.mIntPair[0] +
(aEndVal.mU.mIntPair[0] - aStartVal.mU.mIntPair[0]) * aUnitDistance;
currentVal[1] = aStartVal.mU.mIntPair[1] +
(aEndVal.mU.mIntPair[1] - aStartVal.mU.mIntPair[1]) * aUnitDistance;
aResult.mU.mIntPair[0] = NS_lround(currentVal[0]);
aResult.mU.mIntPair[1] = NS_lround(currentVal[1]);
return NS_OK;
}
} // namespace mozilla

View File

@ -0,0 +1,77 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* 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_SVGINTEGERPAIRSMILTYPE_H_
#define MOZILLA_SVGINTEGERPAIRSMILTYPE_H_
#include "nsISMILType.h"
namespace mozilla {
class SVGIntegerPairSMILType : public nsISMILType
{
public:
// Singleton for nsSMILValue objects to hold onto.
static SVGIntegerPairSMILType sSingleton;
protected:
// nsISMILType Methods
// -------------------
virtual void Init(nsSMILValue& aValue) const;
virtual void Destroy(nsSMILValue&) const;
virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const;
virtual PRBool IsEqual(const nsSMILValue& aLeft,
const nsSMILValue& aRight) 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;
private:
// Private constructor & destructor: prevent instances beyond my singleton,
// and prevent others from deleting my singleton.
SVGIntegerPairSMILType() {}
~SVGIntegerPairSMILType() {}
};
} // namespace mozilla
#endif // MOZILLA_SVGINTEGERPAIRSMILTYPE_H_

View File

@ -0,0 +1,139 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* 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 "SVGNumberPairSMILType.h"
#include "nsSMILValue.h"
#include "nsMathUtils.h"
#include "nsDebug.h"
#include <math.h>
namespace mozilla {
/*static*/ SVGNumberPairSMILType SVGNumberPairSMILType::sSingleton;
void
SVGNumberPairSMILType::Init(nsSMILValue& aValue) const
{
NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected value type");
aValue.mU.mNumberPair[0] = 0;
aValue.mU.mNumberPair[1] = 0;
aValue.mType = this;
}
void
SVGNumberPairSMILType::Destroy(nsSMILValue& aValue) const
{
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
aValue.mU.mNumberPair[0] = 0;
aValue.mU.mNumberPair[1] = 0;
aValue.mType = &nsSMILNullType::sSingleton;
}
nsresult
SVGNumberPairSMILType::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.mNumberPair[0] = aSrc.mU.mNumberPair[0];
aDest.mU.mNumberPair[1] = aSrc.mU.mNumberPair[1];
return NS_OK;
}
PRBool
SVGNumberPairSMILType::IsEqual(const nsSMILValue& aLeft,
const nsSMILValue& aRight) const
{
NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
return aLeft.mU.mNumberPair[0] == aRight.mU.mNumberPair[0] &&
aLeft.mU.mNumberPair[1] == aRight.mU.mNumberPair[1];
}
nsresult
SVGNumberPairSMILType::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.mNumberPair[0] += aValueToAdd.mU.mNumberPair[0] * aCount;
aDest.mU.mNumberPair[1] += aValueToAdd.mU.mNumberPair[1] * aCount;
return NS_OK;
}
nsresult
SVGNumberPairSMILType::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");
double delta[2];
delta[0] = aTo.mU.mNumberPair[0] - aFrom.mU.mNumberPair[0];
delta[1] = aTo.mU.mNumberPair[1] - aFrom.mU.mNumberPair[1];
aDistance = NS_hypot(delta[0], delta[1]);
return NS_OK;
}
nsresult
SVGNumberPairSMILType::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");
aResult.mU.mNumberPair[0] =
float(aStartVal.mU.mNumberPair[0] +
(aEndVal.mU.mNumberPair[0] - aStartVal.mU.mNumberPair[0]) * aUnitDistance);
aResult.mU.mNumberPair[1] =
float(aStartVal.mU.mNumberPair[1] +
(aEndVal.mU.mNumberPair[1] - aStartVal.mU.mNumberPair[1]) * aUnitDistance);
return NS_OK;
}
} // namespace mozilla

View File

@ -0,0 +1,77 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* 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_SVGNUMBERPAIRSMILTYPE_H_
#define MOZILLA_SVGNUMBERPAIRSMILTYPE_H_
#include "nsISMILType.h"
namespace mozilla {
class SVGNumberPairSMILType : public nsISMILType
{
public:
// Singleton for nsSMILValue objects to hold onto.
static SVGNumberPairSMILType sSingleton;
protected:
// nsISMILType Methods
// -------------------
virtual void Init(nsSMILValue& aValue) const;
virtual void Destroy(nsSMILValue&) const;
virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const;
virtual PRBool IsEqual(const nsSMILValue& aLeft,
const nsSMILValue& aRight) 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;
private:
// Private constructor & destructor: prevent instances beyond my singleton,
// and prevent others from deleting my singleton.
SVGNumberPairSMILType() {}
~SVGNumberPairSMILType() {}
};
} // namespace mozilla
#endif // MOZILLA_SVGNUMBERPAIRSMILTYPE_H_

View File

@ -66,7 +66,9 @@
#include "nsSVGUtils.h"
#include "nsSVGLength2.h"
#include "nsSVGNumber2.h"
#include "nsSVGNumberPair.h"
#include "nsSVGInteger.h"
#include "nsSVGIntegerPair.h"
#include "nsSVGAngle.h"
#include "nsSVGBoolean.h"
#include "nsSVGEnum.h"
@ -136,12 +138,24 @@ nsSVGElement::Init()
numberInfo.Reset(i);
}
NumberPairAttributesInfo numberPairInfo = GetNumberPairInfo();
for (i = 0; i < numberPairInfo.mNumberPairCount; i++) {
numberPairInfo.Reset(i);
}
IntegerAttributesInfo integerInfo = GetIntegerInfo();
for (i = 0; i < integerInfo.mIntegerCount; i++) {
integerInfo.Reset(i);
}
IntegerPairAttributesInfo integerPairInfo = GetIntegerPairInfo();
for (i = 0; i < integerPairInfo.mIntegerPairCount; i++) {
integerPairInfo.Reset(i);
}
AngleAttributesInfo angleInfo = GetAngleInfo();
for (i = 0; i < angleInfo.mAngleCount; i++) {
@ -438,15 +452,7 @@ nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
NumberAttributesInfo numberInfo = GetNumberInfo();
for (i = 0; i < numberInfo.mNumberCount; i++) {
if (aAttribute == *numberInfo.mNumberInfo[i].mName) {
if (i + 1 < numberInfo.mNumberCount &&
aAttribute == *numberInfo.mNumberInfo[i + 1].mName) {
rv = ParseNumberOptionalNumber(aValue, i, i + 1);
if (NS_FAILED(rv)) {
numberInfo.Reset(i + 1);
}
} else {
rv = numberInfo.mNumbers[i].SetBaseValueString(aValue, this, PR_FALSE);
}
rv = numberInfo.mNumbers[i].SetBaseValueString(aValue, this, PR_FALSE);
if (NS_FAILED(rv)) {
numberInfo.Reset(i);
}
@ -456,20 +462,27 @@ nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
}
}
if (!foundMatch) {
// Check for nsSVGNumberPair attribute
NumberPairAttributesInfo numberPairInfo = GetNumberPairInfo();
for (i = 0; i < numberPairInfo.mNumberPairCount; i++) {
if (aAttribute == *numberPairInfo.mNumberPairInfo[i].mName) {
rv = numberPairInfo.mNumberPairs[i].SetBaseValueString(aValue, this, PR_FALSE);
if (NS_FAILED(rv)) {
numberPairInfo.Reset(i);
}
foundMatch = PR_TRUE;
break;
}
}
}
if (!foundMatch) {
// Check for nsSVGInteger attribute
IntegerAttributesInfo integerInfo = GetIntegerInfo();
for (i = 0; i < integerInfo.mIntegerCount; i++) {
if (aAttribute == *integerInfo.mIntegerInfo[i].mName) {
if (i + 1 < integerInfo.mIntegerCount &&
aAttribute == *integerInfo.mIntegerInfo[i + 1].mName) {
rv = ParseIntegerOptionalInteger(aValue, i, i + 1);
if (NS_FAILED(rv)) {
integerInfo.Reset(i + 1);
}
} else {
rv = integerInfo.mIntegers[i].SetBaseValueString(aValue, this, PR_FALSE);
}
rv = integerInfo.mIntegers[i].SetBaseValueString(aValue, this, PR_FALSE);
if (NS_FAILED(rv)) {
integerInfo.Reset(i);
}
@ -479,6 +492,21 @@ nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
}
}
if (!foundMatch) {
// Check for nsSVGIntegerPair attribute
IntegerPairAttributesInfo integerPairInfo = GetIntegerPairInfo();
for (i = 0; i < integerPairInfo.mIntegerPairCount; i++) {
if (aAttribute == *integerPairInfo.mIntegerPairInfo[i].mName) {
rv = integerPairInfo.mIntegerPairs[i].SetBaseValueString(aValue, this, PR_FALSE);
if (NS_FAILED(rv)) {
integerPairInfo.Reset(i);
}
foundMatch = PR_TRUE;
break;
}
}
}
if (!foundMatch) {
// Check for nsSVGAngle attribute
AngleAttributesInfo angleInfo = GetAngleInfo();
@ -663,35 +691,45 @@ nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
for (PRUint32 i = 0; i < numInfo.mNumberCount; i++) {
if (aName == *numInfo.mNumberInfo[i].mName) {
if (i + 1 < numInfo.mNumberCount &&
aName == *numInfo.mNumberInfo[i + 1].mName) {
// found a number-optional-number
numInfo.Reset(i + 1);
DidChangeNumber(i + 1, PR_FALSE);
}
numInfo.Reset(i);
DidChangeNumber(i, PR_FALSE);
return rv;
}
}
// Check if this is a number pair attribute going away
NumberPairAttributesInfo numPairInfo = GetNumberPairInfo();
for (PRUint32 i = 0; i < numPairInfo.mNumberPairCount; i++) {
if (aName == *numPairInfo.mNumberPairInfo[i].mName) {
numPairInfo.Reset(i);
DidChangeNumberPair(i, PR_FALSE);
return rv;
}
}
// Check if this is an integer attribute going away
IntegerAttributesInfo intInfo = GetIntegerInfo();
for (PRUint32 i = 0; i < intInfo.mIntegerCount; i++) {
if (aName == *intInfo.mIntegerInfo[i].mName) {
if (i + 1 < intInfo.mIntegerCount &&
aName == *intInfo.mIntegerInfo[i + 1].mName) {
// found a number-optional-number
intInfo.Reset(i + 1);
DidChangeNumber(i + 1, PR_FALSE);
}
intInfo.Reset(i);
DidChangeInteger(i, PR_FALSE);
return rv;
}
}
// Check if this is an integer pair attribute going away
IntegerPairAttributesInfo intPairInfo = GetIntegerPairInfo();
for (PRUint32 i = 0; i < intPairInfo.mIntegerPairCount; i++) {
if (aName == *intPairInfo.mIntegerPairInfo[i].mName) {
intPairInfo.Reset(i);
DidChangeIntegerPair(i, PR_FALSE);
return rv;
}
}
// Check if this is an angle attribute going away
AngleAttributesInfo angleInfo = GetAngleInfo();
@ -1807,6 +1845,53 @@ nsSVGElement::GetAnimatedNumberValues(float *aFirst, ...)
va_end(args);
}
nsSVGElement::NumberPairAttributesInfo
nsSVGElement::GetNumberPairInfo()
{
return NumberPairAttributesInfo(nsnull, nsnull, 0);
}
void nsSVGElement::NumberPairAttributesInfo::Reset(PRUint8 aAttrEnum)
{
mNumberPairs[aAttrEnum].Init(aAttrEnum,
mNumberPairInfo[aAttrEnum].mDefaultValue1,
mNumberPairInfo[aAttrEnum].mDefaultValue2);
}
void
nsSVGElement::DidChangeNumberPair(PRUint8 aAttrEnum, PRBool aDoSetAttr)
{
if (!aDoSetAttr)
return;
NumberPairAttributesInfo info = GetNumberPairInfo();
NS_ASSERTION(info.mNumberPairCount > 0,
"DidChangePairNumber on element with no number pair attribs");
NS_ASSERTION(aAttrEnum < info.mNumberPairCount, "aAttrEnum out of range");
nsAutoString serializedValue;
info.mNumberPairs[aAttrEnum].GetBaseValueString(serializedValue);
nsAttrValue attrValue(serializedValue);
SetParsedAttr(kNameSpaceID_None, *info.mNumberPairInfo[aAttrEnum].mName, nsnull,
attrValue, PR_TRUE);
}
void
nsSVGElement::DidAnimateNumberPair(PRUint8 aAttrEnum)
{
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
NumberPairAttributesInfo info = GetNumberPairInfo();
frame->AttributeChanged(kNameSpaceID_None,
*info.mNumberPairInfo[aAttrEnum].mName,
nsIDOMMutationEvent::MODIFICATION);
}
}
nsSVGElement::IntegerAttributesInfo
nsSVGElement::GetIntegerInfo()
{
@ -1874,6 +1959,53 @@ nsSVGElement::GetAnimatedIntegerValues(PRInt32 *aFirst, ...)
va_end(args);
}
nsSVGElement::IntegerPairAttributesInfo
nsSVGElement::GetIntegerPairInfo()
{
return IntegerPairAttributesInfo(nsnull, nsnull, 0);
}
void nsSVGElement::IntegerPairAttributesInfo::Reset(PRUint8 aAttrEnum)
{
mIntegerPairs[aAttrEnum].Init(aAttrEnum,
mIntegerPairInfo[aAttrEnum].mDefaultValue1,
mIntegerPairInfo[aAttrEnum].mDefaultValue2);
}
void
nsSVGElement::DidChangeIntegerPair(PRUint8 aAttrEnum, PRBool aDoSetAttr)
{
if (!aDoSetAttr)
return;
IntegerPairAttributesInfo info = GetIntegerPairInfo();
NS_ASSERTION(info.mIntegerPairCount > 0,
"DidChangeIntegerPair on element with no integer pair attribs");
NS_ASSERTION(aAttrEnum < info.mIntegerPairCount, "aAttrEnum out of range");
nsAutoString serializedValue;
info.mIntegerPairs[aAttrEnum].GetBaseValueString(serializedValue);
nsAttrValue attrValue(serializedValue);
SetParsedAttr(kNameSpaceID_None, *info.mIntegerPairInfo[aAttrEnum].mName, nsnull,
attrValue, PR_TRUE);
}
void
nsSVGElement::DidAnimateIntegerPair(PRUint8 aAttrEnum)
{
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
IntegerPairAttributesInfo info = GetIntegerPairInfo();
frame->AttributeChanged(kNameSpaceID_None,
*info.mIntegerPairInfo[aAttrEnum].mName,
nsIDOMMutationEvent::MODIFICATION);
}
}
nsSVGElement::AngleAttributesInfo
nsSVGElement::GetAngleInfo()
{
@ -2166,89 +2298,6 @@ nsSVGElement::DidAnimateClass()
}
}
nsresult
nsSVGElement::ParseNumberOptionalNumber(const nsAString& aValue,
PRUint32 aIndex1, PRUint32 aIndex2)
{
NS_ConvertUTF16toUTF8 value(aValue);
const char *str = value.get();
if (NS_IsAsciiWhitespace(*str))
return NS_ERROR_FAILURE;
char *rest;
float x = float(PR_strtod(str, &rest));
float y = x;
if (str == rest || !NS_FloatIsFinite(x)) {
//first value was illformed
return NS_ERROR_FAILURE;
}
if (*rest != '\0') {
while (NS_IsAsciiWhitespace(*rest)) {
++rest;
}
if (*rest == ',') {
++rest;
}
y = float(PR_strtod(rest, &rest));
if (*rest != '\0' || !NS_FloatIsFinite(y)) {
//second value was illformed or there was trailing content
return NS_ERROR_FAILURE;
}
}
NumberAttributesInfo numberInfo = GetNumberInfo();
numberInfo.mNumbers[aIndex1].SetBaseValue(x, this, PR_FALSE);
numberInfo.mNumbers[aIndex2].SetBaseValue(y, this, PR_FALSE);
return NS_OK;
}
nsresult
nsSVGElement::ParseIntegerOptionalInteger(const nsAString& aValue,
PRUint32 aIndex1, PRUint32 aIndex2)
{
NS_ConvertUTF16toUTF8 value(aValue);
const char *str = value.get();
if (NS_IsAsciiWhitespace(*str))
return NS_ERROR_FAILURE;
char *rest;
PRInt32 x = strtol(str, &rest, 10);
PRInt32 y = x;
if (str == rest) {
//first value was illformed
return NS_ERROR_FAILURE;
}
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
return NS_ERROR_FAILURE;
}
}
IntegerAttributesInfo integerInfo = GetIntegerInfo();
integerInfo.mIntegers[aIndex1].SetBaseValue(x, this, PR_FALSE);
integerInfo.mIntegers[aIndex2].SetBaseValue(y, this, PR_FALSE);
return NS_OK;
}
nsresult
nsSVGElement::ReportAttributeParseFailure(nsIDocument* aDocument,
nsIAtom* aAttribute,
@ -2343,20 +2392,22 @@ nsSVGElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
{
NumberAttributesInfo info = GetNumberInfo();
for (PRUint32 i = 0; i < info.mNumberCount; i++) {
// XXX this isn't valid for either of the two properties corresponding to
// attributes of type <number-optional-number> - see filter,
// feConvolveMatrix, feDiffuseLighting, feGaussianBlur, feMorphology and
// feTurbulence.
// The way to fix this is probably to handle them as 2-item number lists
// once we implement number list animation, and put the number list loop
// *above* this one at that time to catch those properties before we get
// here. The separate properties should then point into the list.
if (aName == *info.mNumberInfo[i].mName) {
return info.mNumbers[i].ToSMILAttr(this);
}
}
}
// Number Pairs:
{
NumberPairAttributesInfo info = GetNumberPairInfo();
for (PRUint32 i = 0; i < info.mNumberPairCount; i++) {
if (aName == *info.mNumberPairInfo[i].mName) {
return info.mNumberPairs[i].ToSMILAttr(this);
}
}
}
// Integers:
{
IntegerAttributesInfo info = GetIntegerInfo();
@ -2367,6 +2418,16 @@ nsSVGElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
}
}
// Integer Pairs:
{
IntegerPairAttributesInfo info = GetIntegerPairInfo();
for (PRUint32 i = 0; i < info.mIntegerPairCount; i++) {
if (aName == *info.mIntegerPairInfo[i].mName) {
return info.mIntegerPairs[i].ToSMILAttr(this);
}
}
}
// Enumerations:
{
EnumAttributesInfo info = GetEnumInfo();

View File

@ -61,7 +61,9 @@
class nsSVGSVGElement;
class nsSVGLength2;
class nsSVGNumber2;
class nsSVGNumberPair;
class nsSVGInteger;
class nsSVGIntegerPair;
class nsSVGAngle;
class nsSVGBoolean;
class nsSVGEnum;
@ -174,7 +176,9 @@ public:
void SetLength(nsIAtom* aName, const nsSVGLength2 &aLength);
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeNumber(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeNumberPair(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeInteger(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeIntegerPair(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeAngle(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeBoolean(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr);
@ -188,7 +192,9 @@ public:
virtual void DidAnimateLength(PRUint8 aAttrEnum);
virtual void DidAnimateNumber(PRUint8 aAttrEnum);
virtual void DidAnimateNumberPair(PRUint8 aAttrEnum);
virtual void DidAnimateInteger(PRUint8 aAttrEnum);
virtual void DidAnimateIntegerPair(PRUint8 aAttrEnum);
virtual void DidAnimateAngle(PRUint8 aAttrEnum);
virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
virtual void DidAnimateEnum(PRUint8 aAttrEnum);
@ -306,6 +312,27 @@ protected:
void Reset(PRUint8 aAttrEnum);
};
struct NumberPairInfo {
nsIAtom** mName;
float mDefaultValue1;
float mDefaultValue2;
};
struct NumberPairAttributesInfo {
nsSVGNumberPair* mNumberPairs;
NumberPairInfo* mNumberPairInfo;
PRUint32 mNumberPairCount;
NumberPairAttributesInfo(nsSVGNumberPair *aNumberPairs,
NumberPairInfo *aNumberPairInfo,
PRUint32 aNumberPairCount) :
mNumberPairs(aNumberPairs), mNumberPairInfo(aNumberPairInfo),
mNumberPairCount(aNumberPairCount)
{}
void Reset(PRUint8 aAttrEnum);
};
struct IntegerInfo {
nsIAtom** mName;
PRInt32 mDefaultValue;
@ -325,6 +352,27 @@ protected:
void Reset(PRUint8 aAttrEnum);
};
struct IntegerPairInfo {
nsIAtom** mName;
PRInt32 mDefaultValue1;
PRInt32 mDefaultValue2;
};
struct IntegerPairAttributesInfo {
nsSVGIntegerPair* mIntegerPairs;
IntegerPairInfo* mIntegerPairInfo;
PRUint32 mIntegerPairCount;
IntegerPairAttributesInfo(nsSVGIntegerPair *aIntegerPairs,
IntegerPairInfo *aIntegerPairInfo,
PRUint32 aIntegerPairCount) :
mIntegerPairs(aIntegerPairs), mIntegerPairInfo(aIntegerPairInfo),
mIntegerPairCount(aIntegerPairCount)
{}
void Reset(PRUint8 aAttrEnum);
};
struct AngleInfo {
nsIAtom** mName;
float mDefaultValue;
@ -458,7 +506,9 @@ protected:
virtual LengthAttributesInfo GetLengthInfo();
virtual NumberAttributesInfo GetNumberInfo();
virtual NumberPairAttributesInfo GetNumberPairInfo();
virtual IntegerAttributesInfo GetIntegerInfo();
virtual IntegerPairAttributesInfo GetIntegerPairInfo();
virtual AngleAttributesInfo GetAngleInfo();
virtual BooleanAttributesInfo GetBooleanInfo();
virtual EnumAttributesInfo GetEnumInfo();
@ -474,16 +524,6 @@ protected:
static nsSVGEnumMapping sSVGUnitTypesMap[];
private:
/* read <number-optional-number> */
nsresult
ParseNumberOptionalNumber(const nsAString& aValue,
PRUint32 aIndex1, PRUint32 aIndex2);
/* read <integer-optional-integer> */
nsresult
ParseIntegerOptionalInteger(const nsAString& aValue,
PRUint32 aIndex1, PRUint32 aIndex2);
void ResetOldStyleBaseType(nsISVGValue *svg_value);
struct ObservableModificationData {

View File

@ -47,9 +47,8 @@ nsSVGElement::LengthInfo nsSVGFilterElement::sLengthInfo[4] =
{ &nsGkAtoms::height, 120, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, nsSVGUtils::Y },
};
nsSVGElement::IntegerInfo nsSVGFilterElement::sIntegerInfo[2] =
nsSVGElement::IntegerPairInfo nsSVGFilterElement::sIntegerPairInfo[1] =
{
{ &nsGkAtoms::filterRes, 0 },
{ &nsGkAtoms::filterRes, 0 }
};
@ -144,13 +143,17 @@ NS_IMETHODIMP nsSVGFilterElement::GetPrimitiveUnits(nsIDOMSVGAnimatedEnumeration
/* readonly attribute nsIDOMSVGAnimatedEnumeration filterResY; */
NS_IMETHODIMP nsSVGFilterElement::GetFilterResX(nsIDOMSVGAnimatedInteger * *aFilterResX)
{
return mIntegerAttributes[FILTERRES_X].ToDOMAnimatedInteger(aFilterResX, this);
return mIntegerPairAttributes[FILTERRES].ToDOMAnimatedInteger(aFilterResX,
nsSVGIntegerPair::eFirst,
this);
}
/* readonly attribute nsIDOMSVGAnimatedEnumeration filterResY; */
NS_IMETHODIMP nsSVGFilterElement::GetFilterResY(nsIDOMSVGAnimatedInteger * *aFilterResY)
{
return mIntegerAttributes[FILTERRES_Y].ToDOMAnimatedInteger(aFilterResY, this);
return mIntegerPairAttributes[FILTERRES].ToDOMAnimatedInteger(aFilterResY,
nsSVGIntegerPair::eSecond,
this);
}
/* void setFilterRes (in unsigned long filterResX, in unsigned long filterResY);
@ -158,8 +161,7 @@ NS_IMETHODIMP nsSVGFilterElement::GetFilterResY(nsIDOMSVGAnimatedInteger * *aFil
NS_IMETHODIMP
nsSVGFilterElement::SetFilterRes(PRUint32 filterResX, PRUint32 filterResY)
{
mIntegerAttributes[FILTERRES_X].SetBaseValue(filterResX, this, PR_FALSE);
mIntegerAttributes[FILTERRES_Y].SetBaseValue(filterResY, this, PR_FALSE);
mIntegerPairAttributes[FILTERRES].SetBaseValues(filterResX, filterResY, this, PR_FALSE);
return NS_OK;
}
@ -219,11 +221,11 @@ nsSVGFilterElement::GetLengthInfo()
NS_ARRAY_LENGTH(sLengthInfo));
}
nsSVGElement::IntegerAttributesInfo
nsSVGFilterElement::GetIntegerInfo()
nsSVGElement::IntegerPairAttributesInfo
nsSVGFilterElement::GetIntegerPairInfo()
{
return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
NS_ARRAY_LENGTH(sIntegerInfo));
return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
NS_ARRAY_LENGTH(sIntegerPairInfo));
}
nsSVGElement::EnumAttributesInfo

View File

@ -42,7 +42,7 @@
#include "nsIDOMSVGURIReference.h"
#include "nsIDOMSVGUnitTypes.h"
#include "nsSVGLength2.h"
#include "nsSVGInteger.h"
#include "nsSVGIntegerPair.h"
#include "nsSVGEnum.h"
#include "nsSVGString.h"
@ -84,7 +84,7 @@ public:
protected:
virtual LengthAttributesInfo GetLengthInfo();
virtual IntegerAttributesInfo GetIntegerInfo();
virtual IntegerPairAttributesInfo GetIntegerPairInfo();
virtual EnumAttributesInfo GetEnumInfo();
virtual StringAttributesInfo GetStringInfo();
@ -95,9 +95,9 @@ protected:
nsSVGLength2 mLengthAttributes[4];
static LengthInfo sLengthInfo[4];
enum { FILTERRES_X, FILTERRES_Y };
nsSVGInteger mIntegerAttributes[2];
static IntegerInfo sIntegerInfo[2];
enum { FILTERRES };
nsSVGIntegerPair mIntegerPairAttributes[1];
static IntegerPairInfo sIntegerPairInfo[1];
enum { FILTERUNITS, PRIMITIVEUNITS };
nsSVGEnum mEnumAttributes[2];

View File

@ -37,7 +37,9 @@
#include "nsSVGElement.h"
#include "nsGkAtoms.h"
#include "nsSVGNumber2.h"
#include "nsSVGNumberPair.h"
#include "nsSVGInteger.h"
#include "nsSVGIntegerPair.h"
#include "nsSVGBoolean.h"
#include "nsIDOMSVGFilters.h"
#include "nsCOMPtr.h"
@ -136,10 +138,10 @@ nsSVGFE::ScaleInfo
nsSVGFE::SetupScalingFilter(nsSVGFilterInstance *aInstance,
const Image *aSource, const Image *aTarget,
const nsIntRect& aDataRect,
nsSVGNumber2 *aUnitX, nsSVGNumber2 *aUnitY)
nsSVGNumberPair *aKernelUnitLength)
{
ScaleInfo result;
result.mRescaling = HasAttr(kNameSpaceID_None, nsGkAtoms::kernelUnitLength);
result.mRescaling = aKernelUnitLength->IsExplicitlySet();
if (!result.mRescaling) {
result.mSource = aSource->mImage;
result.mTarget = aTarget->mImage;
@ -150,16 +152,13 @@ nsSVGFE::SetupScalingFilter(nsSVGFilterInstance *aInstance,
float kernelX, kernelY;
nsSVGLength2 val;
val.Init(nsSVGUtils::X, 0xff,
aUnitX->GetAnimValue(),
aKernelUnitLength->GetAnimValue(nsSVGNumberPair::eFirst),
nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
kernelX = aInstance->GetPrimitiveLength(&val);
val.Init(nsSVGUtils::Y, 0xff,
aUnitY->GetAnimValue(),
aKernelUnitLength->GetAnimValue(nsSVGNumberPair::eSecond),
nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
kernelY = aInstance->GetPrimitiveLength(&val);
#ifdef DEBUG_tor
fprintf(stderr, "scaling kernelX/Y %f %f\n", kernelX, kernelY);
#endif
if (kernelX <= 0 || kernelY <= 0)
return result;
@ -182,9 +181,6 @@ nsSVGFE::SetupScalingFilter(nsSVGFilterInstance *aInstance,
if (!gfxUtils::GfxRectToIntRect(r, &result.mDataRect))
return result;
#ifdef DEBUG_tor
fprintf(stderr, "scaled size %d %d\n", scaledSize.width, scaledSize.height);
#endif
result.mSource = new gfxImageSurface(scaledSize,
gfxASurface::ImageFormatARGB32);
result.mTarget = new gfxImageSurface(scaledSize,
@ -335,6 +331,12 @@ nsSVGFE::DidAnimateNumber(PRUint8 aAttrEnum)
DidAnimateAttr(this);
}
void
nsSVGFE::DidAnimateNumberPair(PRUint8 aAttrEnum)
{
DidAnimateAttr(this);
}
void
nsSVGFE::DidAnimateNumberList(PRUint8 aAttrEnum)
{
@ -347,6 +349,12 @@ nsSVGFE::DidAnimateInteger(PRUint8 aAttrEnum)
DidAnimateAttr(this);
}
void
nsSVGFE::DidAnimateIntegerPair(PRUint8 aAttrEnum)
{
DidAnimateAttr(this);
}
void
nsSVGFE::DidAnimateEnum(PRUint8 aAttrEnum)
{
@ -416,12 +424,12 @@ public:
virtual nsXPCClassInfo* GetClassInfo();
protected:
virtual NumberAttributesInfo GetNumberInfo();
virtual NumberPairAttributesInfo GetNumberPairInfo();
virtual StringAttributesInfo GetStringInfo();
enum { STD_DEV_X, STD_DEV_Y };
nsSVGNumber2 mNumberAttributes[2];
static NumberInfo sNumberInfo[2];
enum { STD_DEV };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { RESULT, IN1 };
nsSVGString mStringAttributes[2];
@ -436,10 +444,9 @@ private:
PRUint32 aDX, PRUint32 aDY);
};
nsSVGElement::NumberInfo nsSVGFEGaussianBlurElement::sNumberInfo[2] =
nsSVGElement::NumberPairInfo nsSVGFEGaussianBlurElement::sNumberPairInfo[1] =
{
{ &nsGkAtoms::stdDeviation, 0, PR_FALSE },
{ &nsGkAtoms::stdDeviation, 0, PR_FALSE }
{ &nsGkAtoms::stdDeviation, 0, 0 }
};
nsSVGElement::StringInfo nsSVGFEGaussianBlurElement::sStringInfo[2] =
@ -485,21 +492,20 @@ NS_IMETHODIMP nsSVGFEGaussianBlurElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
/* readonly attribute nsIDOMSVGAnimatedNumber stdDeviationX; */
NS_IMETHODIMP nsSVGFEGaussianBlurElement::GetStdDeviationX(nsIDOMSVGAnimatedNumber * *aX)
{
return mNumberAttributes[STD_DEV_X].ToDOMAnimatedNumber(aX, this);
return mNumberPairAttributes[STD_DEV].ToDOMAnimatedNumber(aX, nsSVGNumberPair::eFirst, this);
}
/* readonly attribute nsIDOMSVGAnimatedNumber stdDeviationY; */
NS_IMETHODIMP nsSVGFEGaussianBlurElement::GetStdDeviationY(nsIDOMSVGAnimatedNumber * *aY)
{
return mNumberAttributes[STD_DEV_Y].ToDOMAnimatedNumber(aY, this);
return mNumberPairAttributes[STD_DEV].ToDOMAnimatedNumber(aY, nsSVGNumberPair::eSecond, this);
}
NS_IMETHODIMP
nsSVGFEGaussianBlurElement::SetStdDeviation(float stdDeviationX, float stdDeviationY)
{
NS_ENSURE_FINITE2(stdDeviationX, stdDeviationY, NS_ERROR_ILLEGAL_VALUE);
mNumberAttributes[STD_DEV_X].SetBaseValue(stdDeviationX, this, PR_TRUE);
mNumberAttributes[STD_DEV_Y].SetBaseValue(stdDeviationY, this, PR_TRUE);
mNumberPairAttributes[STD_DEV].SetBaseValues(stdDeviationX, stdDeviationY, this, PR_TRUE);
return NS_OK;
}
@ -644,10 +650,10 @@ nsresult
nsSVGFEGaussianBlurElement::GetDXY(PRUint32 *aDX, PRUint32 *aDY,
const nsSVGFilterInstance& aInstance)
{
float stdX, stdY;
nsSVGLength2 val;
float stdX = mNumberPairAttributes[STD_DEV].GetAnimValue(nsSVGNumberPair::eFirst);
float stdY = mNumberPairAttributes[STD_DEV].GetAnimValue(nsSVGNumberPair::eSecond);
GetAnimatedNumberValues(&stdX, &stdY, nsnull);
nsSVGLength2 val;
val.Init(nsSVGUtils::X, 0xff, stdX, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
stdX = aInstance.GetPrimitiveLength(&val);
@ -833,11 +839,11 @@ nsSVGFEGaussianBlurElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSource
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
nsSVGFEGaussianBlurElement::GetNumberInfo()
nsSVGElement::NumberPairAttributesInfo
nsSVGFEGaussianBlurElement::GetNumberPairInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
NS_ARRAY_LENGTH(sNumberInfo));
return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
NS_ARRAY_LENGTH(sNumberPairInfo));
}
nsSVGElement::StringAttributesInfo
@ -1201,14 +1207,9 @@ nsSVGFEColorMatrixElement::Filter(nsSVGFilterInstance *instance,
PRUint32 stride = aTarget->mImage->Stride();
PRUint16 type = mEnumAttributes[TYPE].GetAnimValue();
const SVGNumberList &values = GetAnimatedNumberList(VALUES)->GetAnimValue();
const SVGNumberList &values = mNumberListAttributes[VALUES].GetAnimValue();
#ifdef DEBUG_tor
fprintf(stderr, "FILTER COLOR MATRIX rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::values) &&
if (!mNumberListAttributes[VALUES].IsExplicitlySet() &&
(type == nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_MATRIX ||
type == nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_SATURATE ||
type == nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_HUE_ROTATE)) {
@ -1542,11 +1543,6 @@ nsSVGFECompositeElement::Filter(nsSVGFilterInstance *instance,
float k1, k2, k3, k4;
GetAnimatedNumberValues(&k1, &k2, &k3, &k4, nsnull);
#ifdef DEBUG_tor
fprintf(stderr, "FILTER COMPOSITE rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
// Copy the first source image
CopyRect(aTarget, aSources[0], rect);
@ -1819,11 +1815,6 @@ nsSVGFEComponentTransferElement::Filter(nsSVGFilterInstance *instance,
PRUint8* targetData = aTarget->mImage->Data();
PRUint32 stride = aTarget->mImage->Stride();
#ifdef DEBUG_tor
fprintf(stderr, "FILTER COMPONENT rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
PRUint8 tableR[256], tableG[256], tableB[256], tableA[256];
for (int i=0; i<256; i++)
tableR[i] = tableG[i] = tableB[i] = tableA[i] = i;
@ -1970,7 +1961,7 @@ nsSVGComponentTransferFunctionElement::GenerateLookupTable(PRUint8 *aTable)
&exponent, &offset, nsnull);
const SVGNumberList &tableValues =
GetAnimatedNumberList(TABLEVALUES)->GetAnimValue();
mNumberListAttributes[TABLEVALUES].GetAnimValue();
PRUint32 tvLength = tableValues.Length();
PRUint32 i;
@ -2594,11 +2585,6 @@ nsSVGFEOffsetElement::Filter(nsSVGFilterInstance *instance,
const Image* aTarget,
const nsIntRect& rect)
{
#ifdef DEBUG_tor
fprintf(stderr, "FILTER OFFSET rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
nsIntPoint offset = GetOffset(*instance);
gfxContext ctx(aTarget->mImage);
@ -2934,10 +2920,6 @@ nsSVGFETileElement::Filter(nsSVGFilterInstance *instance,
const Image* aTarget,
const nsIntRect& rect)
{
#ifdef DEBUG_tor
fprintf(stderr, "FILTER TILE rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
// XXX This code depends on the surface rect containing the filter
// primitive subregion. ComputeTargetBBox, ComputeNeededSourceBBoxes
// and ComputeChangeBBox are all pessimal, so that will normally be OK,
@ -3036,13 +3018,18 @@ public:
virtual nsXPCClassInfo* GetClassInfo();
protected:
virtual NumberAttributesInfo GetNumberInfo();
virtual NumberPairAttributesInfo GetNumberPairInfo();
virtual IntegerAttributesInfo GetIntegerInfo();
virtual EnumAttributesInfo GetEnumInfo();
virtual StringAttributesInfo GetStringInfo();
enum { BASE_FREQ_X, BASE_FREQ_Y, SEED}; // floating point seed?!
nsSVGNumber2 mNumberAttributes[3];
static NumberInfo sNumberInfo[3];
enum { SEED }; // floating point seed?!
nsSVGNumber2 mNumberAttributes[1];
static NumberInfo sNumberInfo[1];
enum { BASE_FREQ };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { OCTAVES };
nsSVGInteger mIntegerAttributes[1];
@ -3120,13 +3107,16 @@ private:
double aTileWidth, double aTileHeight);
};
nsSVGElement::NumberInfo nsSVGFETurbulenceElement::sNumberInfo[3] =
nsSVGElement::NumberInfo nsSVGFETurbulenceElement::sNumberInfo[1] =
{
{ &nsGkAtoms::baseFrequency, 0, PR_FALSE },
{ &nsGkAtoms::baseFrequency, 0, PR_FALSE },
{ &nsGkAtoms::seed, 0, PR_FALSE }
};
nsSVGElement::NumberPairInfo nsSVGFETurbulenceElement::sNumberPairInfo[1] =
{
{ &nsGkAtoms::baseFrequency, 0, 0 }
};
nsSVGElement::IntegerInfo nsSVGFETurbulenceElement::sIntegerInfo[1] =
{
{ &nsGkAtoms::numOctaves, 1 }
@ -3194,13 +3184,13 @@ NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFETurbulenceElement)
/* readonly attribute nsIDOMSVGAnimatedNumber baseFrequencyX; */
NS_IMETHODIMP nsSVGFETurbulenceElement::GetBaseFrequencyX(nsIDOMSVGAnimatedNumber * *aX)
{
return mNumberAttributes[BASE_FREQ_X].ToDOMAnimatedNumber(aX, this);
return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(aX, nsSVGNumberPair::eFirst, this);
}
/* readonly attribute nsIDOMSVGAnimatedNumber baseFrequencyY; */
NS_IMETHODIMP nsSVGFETurbulenceElement::GetBaseFrequencyY(nsIDOMSVGAnimatedNumber * *aY)
{
return mNumberAttributes[BASE_FREQ_Y].ToDOMAnimatedNumber(aY, this);
return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(aY, nsSVGNumberPair::eSecond, this);
}
/* readonly attribute nsIDOMSVGAnimatedInteger numOctaves; */
@ -3241,18 +3231,13 @@ nsSVGFETurbulenceElement::Filter(nsSVGFilterInstance *instance,
PRInt32(aTarget->mFilterPrimitiveSubregion.Width()),
PRInt32(aTarget->mFilterPrimitiveSubregion.Height()));
#ifdef DEBUG_tor
fprintf(stderr, "FILTER TURBULENCE rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
float fX, fY, seed;
float fX = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eFirst);
float fY = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eSecond);
float seed = mNumberAttributes[OCTAVES].GetAnimValue();
PRInt32 octaves = mIntegerAttributes[OCTAVES].GetAnimValue();
PRUint16 type = mEnumAttributes[TYPE].GetAnimValue();
PRUint16 stitch = mEnumAttributes[STITCHTILES].GetAnimValue();
GetAnimatedNumberValues(&fX, &fY, &seed, nsnull);
InitSeed((PRInt32)seed);
// XXXroc this makes absolutely no sense to me.
@ -3491,6 +3476,13 @@ nsSVGFETurbulenceElement::GetNumberInfo()
NS_ARRAY_LENGTH(sNumberInfo));
}
nsSVGElement::NumberPairAttributesInfo
nsSVGFETurbulenceElement::GetNumberPairInfo()
{
return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
NS_ARRAY_LENGTH(sNumberPairInfo));
}
nsSVGElement::IntegerAttributesInfo
nsSVGFETurbulenceElement::GetIntegerInfo()
{
@ -3560,13 +3552,13 @@ protected:
void GetRXY(PRInt32 *aRX, PRInt32 *aRY, const nsSVGFilterInstance& aInstance);
nsIntRect InflateRect(const nsIntRect& aRect, const nsSVGFilterInstance& aInstance);
virtual NumberAttributesInfo GetNumberInfo();
virtual NumberPairAttributesInfo GetNumberPairInfo();
virtual EnumAttributesInfo GetEnumInfo();
virtual StringAttributesInfo GetStringInfo();
enum { RADIUS_X, RADIUS_Y };
nsSVGNumber2 mNumberAttributes[2];
static NumberInfo sNumberInfo[2];
enum { RADIUS };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { OPERATOR };
nsSVGEnum mEnumAttributes[1];
@ -3578,10 +3570,9 @@ protected:
static StringInfo sStringInfo[2];
};
nsSVGElement::NumberInfo nsSVGFEMorphologyElement::sNumberInfo[2] =
nsSVGElement::NumberPairInfo nsSVGFEMorphologyElement::sNumberPairInfo[1] =
{
{ &nsGkAtoms::radius, 0, PR_FALSE },
{ &nsGkAtoms::radius, 0, PR_FALSE }
{ &nsGkAtoms::radius, 0, 0 }
};
nsSVGEnumMapping nsSVGFEMorphologyElement::sOperatorMap[] = {
@ -3647,21 +3638,20 @@ NS_IMETHODIMP nsSVGFEMorphologyElement::GetOperator(nsIDOMSVGAnimatedEnumeration
/* readonly attribute nsIDOMSVGAnimatedNumber radiusX; */
NS_IMETHODIMP nsSVGFEMorphologyElement::GetRadiusX(nsIDOMSVGAnimatedNumber * *aX)
{
return mNumberAttributes[RADIUS_X].ToDOMAnimatedNumber(aX, this);
return mNumberPairAttributes[RADIUS].ToDOMAnimatedNumber(aX, nsSVGNumberPair::eFirst, this);
}
/* readonly attribute nsIDOMSVGAnimatedNumber radiusY; */
NS_IMETHODIMP nsSVGFEMorphologyElement::GetRadiusY(nsIDOMSVGAnimatedNumber * *aY)
{
return mNumberAttributes[RADIUS_Y].ToDOMAnimatedNumber(aY, this);
return mNumberPairAttributes[RADIUS].ToDOMAnimatedNumber(aY, nsSVGNumberPair::eSecond, this);
}
NS_IMETHODIMP
nsSVGFEMorphologyElement::SetRadius(float rx, float ry)
{
NS_ENSURE_FINITE2(rx, ry, NS_ERROR_ILLEGAL_VALUE);
mNumberAttributes[RADIUS_X].SetBaseValue(rx, this, PR_TRUE);
mNumberAttributes[RADIUS_Y].SetBaseValue(ry, this, PR_TRUE);
mNumberPairAttributes[RADIUS].SetBaseValues(rx, ry, this, PR_TRUE);
return NS_OK;
}
@ -3709,9 +3699,9 @@ void
nsSVGFEMorphologyElement::GetRXY(PRInt32 *aRX, PRInt32 *aRY,
const nsSVGFilterInstance& aInstance)
{
float rx = mNumberPairAttributes[RADIUS].GetAnimValue(nsSVGNumberPair::eFirst);
float ry = mNumberPairAttributes[RADIUS].GetAnimValue(nsSVGNumberPair::eSecond);
nsSVGLength2 val;
float rx, ry;
GetAnimatedNumberValues(&rx, &ry, nsnull);
val.Init(nsSVGUtils::X, 0xff, rx, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
// Subtract an epsilon here because we don't want a value that's just
// slightly larger than an integer to round up to the next integer; it's
@ -3728,11 +3718,6 @@ nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance,
const Image* aTarget,
const nsIntRect& rect)
{
#ifdef DEBUG_tor
fprintf(stderr, "FILTER MORPH rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
PRInt32 rx, ry;
GetRXY(&rx, &ry, *instance);
@ -3818,11 +3803,11 @@ nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance,
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
nsSVGFEMorphologyElement::GetNumberInfo()
nsSVGElement::NumberPairAttributesInfo
nsSVGFEMorphologyElement::GetNumberPairInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
NS_ARRAY_LENGTH(sNumberInfo));
return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
NS_ARRAY_LENGTH(sNumberPairInfo));
}
nsSVGElement::EnumAttributesInfo
@ -3889,19 +3874,29 @@ protected:
}
virtual NumberAttributesInfo GetNumberInfo();
virtual NumberPairAttributesInfo GetNumberPairInfo();
virtual IntegerAttributesInfo GetIntegerInfo();
virtual IntegerPairAttributesInfo GetIntegerPairInfo();
virtual BooleanAttributesInfo GetBooleanInfo();
virtual EnumAttributesInfo GetEnumInfo();
virtual StringAttributesInfo GetStringInfo();
virtual NumberListAttributesInfo GetNumberListInfo();
enum { DIVISOR, BIAS, KERNEL_UNIT_LENGTH_X, KERNEL_UNIT_LENGTH_Y };
nsSVGNumber2 mNumberAttributes[4];
static NumberInfo sNumberInfo[4];
enum { DIVISOR, BIAS };
nsSVGNumber2 mNumberAttributes[2];
static NumberInfo sNumberInfo[2];
enum { ORDER_X, ORDER_Y, TARGET_X, TARGET_Y };
nsSVGInteger mIntegerAttributes[4];
static IntegerInfo sIntegerInfo[4];
enum { KERNEL_UNIT_LENGTH };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { TARGET_X, TARGET_Y };
nsSVGInteger mIntegerAttributes[2];
static IntegerInfo sIntegerInfo[2];
enum { ORDER };
nsSVGIntegerPair mIntegerPairAttributes[1];
static IntegerPairInfo sIntegerPairInfo[1];
enum { PRESERVEALPHA };
nsSVGBoolean mBooleanAttributes[1];
@ -3921,22 +3916,28 @@ protected:
static NumberListInfo sNumberListInfo[1];
};
nsSVGElement::NumberInfo nsSVGFEConvolveMatrixElement::sNumberInfo[4] =
nsSVGElement::NumberInfo nsSVGFEConvolveMatrixElement::sNumberInfo[2] =
{
{ &nsGkAtoms::divisor, 1, PR_FALSE },
{ &nsGkAtoms::bias, 0, PR_FALSE },
{ &nsGkAtoms::kernelUnitLength, 0, PR_FALSE },
{ &nsGkAtoms::kernelUnitLength, 0, PR_FALSE }
{ &nsGkAtoms::bias, 0, PR_FALSE }
};
nsSVGElement::IntegerInfo nsSVGFEConvolveMatrixElement::sIntegerInfo[4] =
nsSVGElement::NumberPairInfo nsSVGFEConvolveMatrixElement::sNumberPairInfo[1] =
{
{ &nsGkAtoms::kernelUnitLength, 0, 0 }
};
nsSVGElement::IntegerInfo nsSVGFEConvolveMatrixElement::sIntegerInfo[2] =
{
{ &nsGkAtoms::order, 3 },
{ &nsGkAtoms::order, 3 },
{ &nsGkAtoms::targetX, 0 },
{ &nsGkAtoms::targetY, 0 }
};
nsSVGElement::IntegerPairInfo nsSVGFEConvolveMatrixElement::sIntegerPairInfo[1] =
{
{ &nsGkAtoms::order, 3, 3 }
};
nsSVGElement::BooleanInfo nsSVGFEConvolveMatrixElement::sBooleanInfo[1] =
{
{ &nsGkAtoms::preserveAlpha, PR_FALSE }
@ -4002,12 +4003,12 @@ NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetIn1(nsIDOMSVGAnimatedString * *aI
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetOrderX(nsIDOMSVGAnimatedInteger * *aOrderX)
{
return mIntegerAttributes[ORDER_X].ToDOMAnimatedInteger(aOrderX, this);
return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(aOrderX, nsSVGIntegerPair::eFirst, this);
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetOrderY(nsIDOMSVGAnimatedInteger * *aOrderY)
{
return mIntegerAttributes[ORDER_Y].ToDOMAnimatedInteger(aOrderY, this);
return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(aOrderY, nsSVGIntegerPair::eSecond, this);
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetKernelMatrix(nsIDOMSVGAnimatedNumberList * *aKernelMatrix)
@ -4052,15 +4053,17 @@ nsSVGFEConvolveMatrixElement::GetBias(nsIDOMSVGAnimatedNumber **aBias)
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::GetKernelUnitLengthX(nsIDOMSVGAnimatedNumber **aKernelX)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_X].ToDOMAnimatedNumber(aKernelX,
this);
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelX,
nsSVGNumberPair::eFirst,
this);
}
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::GetKernelUnitLengthY(nsIDOMSVGAnimatedNumber **aKernelY)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_Y].ToDOMAnimatedNumber(aKernelY,
this);
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelY,
nsSVGNumberPair::eSecond,
this);
}
void
@ -4173,25 +4176,27 @@ nsSVGFEConvolveMatrixElement::Filter(nsSVGFilterInstance *instance,
const nsIntRect& rect)
{
const SVGNumberList &kernelMatrix =
GetAnimatedNumberList(KERNELMATRIX)->GetAnimValue();
mNumberListAttributes[KERNELMATRIX].GetAnimValue();
PRUint32 kmLength = kernelMatrix.Length();
PRInt32 orderX, orderY;
PRInt32 targetX, targetY;
GetAnimatedIntegerValues(&orderX, &orderY, &targetX, &targetY, nsnull);
PRInt32 orderX = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eFirst);
PRInt32 orderY = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eSecond);
if (orderX <= 0 || orderY <= 0 ||
static_cast<PRUint32>(orderX * orderY) != kmLength) {
return NS_ERROR_FAILURE;
}
if (HasAttr(kNameSpaceID_None, nsGkAtoms::targetX)) {
PRInt32 targetX, targetY;
GetAnimatedIntegerValues(&targetX, &targetY, nsnull);
if (mIntegerAttributes[TARGET_X].IsExplicitlySet()) {
if (targetX < 0 || targetX >= orderX)
return NS_ERROR_FAILURE;
} else {
targetX = orderX / 2;
}
if (HasAttr(kNameSpaceID_None, nsGkAtoms::targetY)) {
if (mIntegerAttributes[TARGET_Y].IsExplicitlySet()) {
if (targetY < 0 || targetY >= orderY)
return NS_ERROR_FAILURE;
} else {
@ -4209,7 +4214,7 @@ nsSVGFEConvolveMatrixElement::Filter(nsSVGFilterInstance *instance,
}
float divisor;
if (HasAttr(kNameSpaceID_None, nsGkAtoms::divisor)) {
if (mNumberAttributes[DIVISOR].IsExplicitlySet()) {
divisor = mNumberAttributes[DIVISOR].GetAnimValue();
if (divisor == 0)
return NS_ERROR_FAILURE;
@ -4222,18 +4227,14 @@ nsSVGFEConvolveMatrixElement::Filter(nsSVGFilterInstance *instance,
}
ScaleInfo info = SetupScalingFilter(instance, aSources[0], aTarget, rect,
&mNumberAttributes[KERNEL_UNIT_LENGTH_X],
&mNumberAttributes[KERNEL_UNIT_LENGTH_Y]);
&mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
if (!info.mTarget)
return NS_ERROR_FAILURE;
PRUint16 edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
PRBool preserveAlpha = mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
float bias = 0;
if (HasAttr(kNameSpaceID_None, nsGkAtoms::bias)) {
bias = mNumberAttributes[BIAS].GetAnimValue();
}
float bias = mNumberAttributes[BIAS].GetAnimValue();
const nsIntRect& dataRect = info.mDataRect;
PRInt32 stride = info.mSource->Stride();
@ -4267,6 +4268,13 @@ nsSVGFEConvolveMatrixElement::GetNumberInfo()
NS_ARRAY_LENGTH(sNumberInfo));
}
nsSVGElement::NumberPairAttributesInfo
nsSVGFEConvolveMatrixElement::GetNumberPairInfo()
{
return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
NS_ARRAY_LENGTH(sNumberPairInfo));
}
nsSVGElement::IntegerAttributesInfo
nsSVGFEConvolveMatrixElement::GetIntegerInfo()
{
@ -4274,6 +4282,13 @@ nsSVGFEConvolveMatrixElement::GetIntegerInfo()
NS_ARRAY_LENGTH(sIntegerInfo));
}
nsSVGElement::IntegerPairAttributesInfo
nsSVGFEConvolveMatrixElement::GetIntegerPairInfo()
{
return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
NS_ARRAY_LENGTH(sIntegerPairInfo));
}
nsSVGElement::BooleanAttributesInfo
nsSVGFEConvolveMatrixElement::GetBooleanInfo()
{
@ -4497,7 +4512,8 @@ class nsSVGFESpotLightElement : public nsSVGFESpotLightElementBase,
public nsIDOMSVGFESpotLightElement
{
friend nsresult NS_NewSVGFESpotLightElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
already_AddRefed<nsINodeInfo> aNodeInfo);
friend class nsSVGFELightingElement;
protected:
nsSVGFESpotLightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsSVGFESpotLightElementBase(aNodeInfo) {}
@ -4665,26 +4681,33 @@ protected:
nscolor color, PRUint8 *targetData) = 0;
virtual NumberAttributesInfo GetNumberInfo();
virtual NumberPairAttributesInfo GetNumberPairInfo();
virtual StringAttributesInfo GetStringInfo();
enum { SURFACE_SCALE, DIFFUSE_CONSTANT, SPECULAR_CONSTANT, SPECULAR_EXPONENT,
KERNEL_UNIT_LENGTH_X, KERNEL_UNIT_LENGTH_Y };
nsSVGNumber2 mNumberAttributes[6];
static NumberInfo sNumberInfo[6];
enum { SURFACE_SCALE, DIFFUSE_CONSTANT, SPECULAR_CONSTANT, SPECULAR_EXPONENT };
nsSVGNumber2 mNumberAttributes[4];
static NumberInfo sNumberInfo[4];
enum { KERNEL_UNIT_LENGTH };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { RESULT, IN1 };
nsSVGString mStringAttributes[2];
static StringInfo sStringInfo[2];
};
nsSVGElement::NumberInfo nsSVGFELightingElement::sNumberInfo[6] =
nsSVGElement::NumberInfo nsSVGFELightingElement::sNumberInfo[4] =
{
{ &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 }
{ &nsGkAtoms::specularExponent, 1, PR_FALSE }
};
nsSVGElement::NumberPairInfo nsSVGFELightingElement::sNumberPairInfo[1] =
{
{ &nsGkAtoms::kernelUnitLength, 0, 0 }
};
nsSVGElement::StringInfo nsSVGFELightingElement::sStringInfo[2] =
@ -4832,8 +4855,7 @@ nsSVGFELightingElement::Filter(nsSVGFilterInstance *instance,
const nsIntRect& rect)
{
ScaleInfo info = SetupScalingFilter(instance, aSources[0], aTarget, rect,
&mNumberAttributes[KERNEL_UNIT_LENGTH_X],
&mNumberAttributes[KERNEL_UNIT_LENGTH_Y]);
&mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
if (!info.mTarget)
return NS_ERROR_FAILURE;
@ -4886,21 +4908,22 @@ nsSVGFELightingElement::Filter(nsSVGFilterInstance *instance,
}
if (spotLight) {
float limitingConeAngle;
static_cast<nsSVGFESpotLightElement*>
(spotLight.get())->GetAnimatedNumberValues(lightPos,
lightPos + 1,
lightPos + 2,
pointsAt,
pointsAt + 1,
pointsAt + 2,
&specularExponent,
&limitingConeAngle,
nsnull);
nsSVGFESpotLightElement* spot =
static_cast<nsSVGFESpotLightElement*>(spotLight.get());
spot->GetAnimatedNumberValues(lightPos,
lightPos + 1,
lightPos + 2,
pointsAt,
pointsAt + 1,
pointsAt + 2,
&specularExponent,
&limitingConeAngle,
nsnull);
instance->ConvertLocation(lightPos);
instance->ConvertLocation(pointsAt);
nsCOMPtr<nsIContent> spot = do_QueryInterface(spotLight);
if (spot->HasAttr(kNameSpaceID_None, nsGkAtoms::limitingConeAngle)) {
if (spot->mNumberAttributes[nsSVGFESpotLightElement::LIMITING_CONE_ANGLE].
IsExplicitlySet()) {
cosConeAngle = NS_MAX<double>(cos(limitingConeAngle * radPerDeg), 0.0);
}
}
@ -4972,6 +4995,13 @@ nsSVGFELightingElement::GetNumberInfo()
NS_ARRAY_LENGTH(sNumberInfo));
}
nsSVGElement::NumberPairAttributesInfo
nsSVGFELightingElement::GetNumberPairInfo()
{
return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
NS_ARRAY_LENGTH(sNumberPairInfo));
}
nsSVGElement::StringAttributesInfo
nsSVGFELightingElement::GetStringInfo()
{
@ -5062,15 +5092,17 @@ nsSVGFEDiffuseLightingElement::GetDiffuseConstant(nsIDOMSVGAnimatedNumber **aCon
NS_IMETHODIMP
nsSVGFEDiffuseLightingElement::GetKernelUnitLengthX(nsIDOMSVGAnimatedNumber **aKernelX)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_X].ToDOMAnimatedNumber(aKernelX,
this);
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelX,
nsSVGNumberPair::eFirst,
this);
}
NS_IMETHODIMP
nsSVGFEDiffuseLightingElement::GetKernelUnitLengthY(nsIDOMSVGAnimatedNumber **aKernelY)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_Y].ToDOMAnimatedNumber(aKernelY,
this);
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelY,
nsSVGNumberPair::eSecond,
this);
}
//----------------------------------------------------------------------
@ -5194,15 +5226,17 @@ nsSVGFESpecularLightingElement::GetSpecularExponent(nsIDOMSVGAnimatedNumber **aE
NS_IMETHODIMP
nsSVGFESpecularLightingElement::GetKernelUnitLengthX(nsIDOMSVGAnimatedNumber **aKernelX)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_X].ToDOMAnimatedNumber(aKernelX,
this);
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelX,
nsSVGNumberPair::eFirst,
this);
}
NS_IMETHODIMP
nsSVGFESpecularLightingElement::GetKernelUnitLengthY(nsIDOMSVGAnimatedNumber **aKernelY)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_Y].ToDOMAnimatedNumber(aKernelY,
this);
return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelY,
nsSVGNumberPair::eSecond,
this);
}
//----------------------------------------------------------------------
@ -5450,7 +5484,7 @@ nsSVGFEImageElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
void
nsSVGFEImageElement::MaybeLoadSVGImage()
{
if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href) &&
if (mStringAttributes[HREF].IsExplicitlySet() &&
(NS_FAILED(LoadSVGImage(PR_FALSE, PR_TRUE)) ||
!LoadingEnabled())) {
CancelImageRequests(PR_TRUE);
@ -5467,7 +5501,7 @@ nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
if (mStringAttributes[HREF].IsExplicitlySet()) {
// FIXME: Bug 660963 it would be nice if we could just have
// ClearBrokenState update our state and do it fast...
ClearBrokenState();
@ -5510,10 +5544,6 @@ nsSVGFEImageElement::Filter(nsSVGFilterInstance *instance,
const Image* aTarget,
const nsIntRect& rect)
{
#ifdef DEBUG_tor
fprintf(stderr, "FILTER IMAGE rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
nsIFrame* frame = GetPrimaryFrame();
if (!frame) return NS_ERROR_FAILURE;
@ -5826,11 +5856,6 @@ nsSVGFEDisplacementMapElement::Filter(nsSVGFilterInstance *instance,
const Image* aTarget,
const nsIntRect& rect)
{
#ifdef DEBUG_tor
fprintf(stderr, "FILTER DISPLACEMENT rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
float scale = mNumberAttributes[SCALE].GetAnimValue();
if (scale == 0.0f) {
CopyRect(aTarget, aSources[0], rect);

View File

@ -46,6 +46,7 @@
class nsSVGFilterResource;
class nsSVGString;
class nsSVGNumberPair;
class nsSVGFilterInstance;
struct nsSVGStringInfo {
@ -113,7 +114,7 @@ protected:
const Image *aSource,
const Image *aTarget,
const nsIntRect& aDataRect,
nsSVGNumber2 *aUnitX, nsSVGNumber2 *aUnitY);
nsSVGNumberPair *aUnit);
void FinishScalingFilter(ScaleInfo *aScaleInfo);
@ -218,8 +219,10 @@ protected:
virtual LengthAttributesInfo GetLengthInfo();
virtual void DidAnimateLength(PRUint8 aAttrEnum);
virtual void DidAnimateNumber(PRUint8 aAttrEnum);
virtual void DidAnimateNumberPair(PRUint8 aAttrEnum);
virtual void DidAnimateNumberList(PRUint8 aAttrEnum);
virtual void DidAnimateInteger(PRUint8 aAttrEnum);
virtual void DidAnimateIntegerPair(PRUint8 aAttrEnum);
virtual void DidAnimateEnum(PRUint8 aAttrEnum);
virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
virtual void DidAnimatePreserveAspectRatio();

View File

@ -191,7 +191,7 @@ nsSVGImageElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
void
nsSVGImageElement::MaybeLoadSVGImage()
{
if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href) &&
if (mStringAttributes[HREF].IsExplicitlySet() &&
(NS_FAILED(LoadSVGImage(PR_FALSE, PR_TRUE)) ||
!LoadingEnabled())) {
CancelImageRequests(PR_TRUE);
@ -208,7 +208,7 @@ nsSVGImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
if (mStringAttributes[HREF].IsExplicitlySet()) {
// FIXME: Bug 660963 it would be nice if we could just have
// ClearBrokenState update our state and do it fast...
ClearBrokenState();

View File

@ -57,10 +57,9 @@ NS_INTERFACE_MAP_END
/* Implementation */
nsresult
nsSVGInteger::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
static nsresult
GetValueFromString(const nsAString &aValueAsString,
PRInt32 *aValue)
{
NS_ConvertUTF16toUTF8 value(aValueAsString);
const char *str = value.get();
@ -69,28 +68,46 @@ nsSVGInteger::SetBaseValueString(const nsAString &aValueAsString,
return NS_ERROR_DOM_SYNTAX_ERR;
char *rest;
PRInt32 val = strtol(str, &rest, 10);
*aValue = strtol(str, &rest, 10);
if (rest == str || *rest != '\0') {
return NS_ERROR_DOM_SYNTAX_ERR;
}
if (val != mBaseVal) {
mBaseVal = mAnimVal = val;
#ifdef MOZ_SMIL
if (mIsAnimated) {
aSVGElement->AnimationNeedsResample();
}
#endif
if (*rest == '\0') {
return NS_OK;
}
return NS_ERROR_DOM_SYNTAX_ERR;
}
nsresult
nsSVGInteger::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
PRInt32 value;
nsresult rv = GetValueFromString(aValueAsString, &value);
if (NS_FAILED(rv)) {
return rv;
}
mIsBaseSet = PR_TRUE;
mBaseVal = value;
if (!mIsAnimated) {
mAnimVal = mBaseVal;
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
return NS_OK;
}
void
nsSVGInteger::GetBaseValueString(nsAString & aValueAsString)
{
nsAutoString s;
s.AppendInt(mBaseVal);
aValueAsString.Assign(s);
aValueAsString.Truncate();
aValueAsString.AppendInt(mBaseVal);
}
void
@ -98,15 +115,17 @@ nsSVGInteger::SetBaseValue(int aValue,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
if (aValue != mBaseVal) {
mBaseVal = mAnimVal = aValue;
aSVGElement->DidChangeInteger(mAttrEnum, aDoSetAttr);
#ifdef MOZ_SMIL
if (mIsAnimated) {
aSVGElement->AnimationNeedsResample();
}
#endif
mBaseVal = aValue;
mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal = mBaseVal;
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
aSVGElement->DidChangeInteger(mAttrEnum, aDoSetAttr);
}
void
@ -142,16 +161,11 @@ nsSVGInteger::SMILInteger::ValueFromString(const nsAString& aStr,
nsSMILValue& aValue,
PRBool& aPreventCachingOfSandwich) const
{
NS_ConvertUTF16toUTF8 value(aStr);
const char *str = value.get();
PRInt32 val;
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;
nsresult rv = GetValueFromString(aStr, &val);
if (NS_FAILED(rv)) {
return rv;
}
nsSMILValue smilVal(&SMILIntegerType::sSingleton);

View File

@ -49,6 +49,7 @@ public:
mAnimVal = mBaseVal = aValue;
mAttrEnum = aAttrEnum;
mIsAnimated = PR_FALSE;
mIsBaseSet = PR_FALSE;
}
nsresult SetBaseValueString(const nsAString& aValue,
@ -63,6 +64,14 @@ public:
void SetAnimValue(int aValue, nsSVGElement *aSVGElement);
int GetAnimValue() const
{ return mAnimVal; }
// Returns PR_TRUE if the animated value of this integer has been explicitly
// set (either by animation, or by taking on the base value which has been
// explicitly set by markup or a DOM call), PR_FALSE otherwise.
// If this returns PR_FALSE, the animated value is still valid, that is,
// useable, and represents the default base value of the attribute.
PRBool IsExplicitlySet() const
{ return mIsAnimated || mIsBaseSet; }
nsresult ToDOMAnimatedInteger(nsIDOMSVGAnimatedInteger **aResult,
nsSVGElement* aSVGElement);
@ -77,6 +86,7 @@ private:
PRInt32 mBaseVal;
PRUint8 mAttrEnum; // element specified tracking for attribute
PRPackedBool mIsAnimated;
PRPackedBool mIsBaseSet;
public:
struct DOMAnimatedInteger : public nsIDOMSVGAnimatedInteger

View File

@ -0,0 +1,261 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 "nsSVGIntegerPair.h"
#include "nsSVGUtils.h"
#include "nsTextFormatter.h"
#include "prdtoa.h"
#ifdef MOZ_SMIL
#include "nsSMILValue.h"
#include "SVGIntegerPairSMILType.h"
#endif // MOZ_SMIL
using namespace mozilla;
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGIntegerPair::DOMAnimatedIntegerPair, mSVGElement)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGIntegerPair::DOMAnimatedIntegerPair)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGIntegerPair::DOMAnimatedIntegerPair)
DOMCI_DATA(SVGAnimatedIntegerPair, nsSVGIntegerPair::DOMAnimatedIntegerPair)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGIntegerPair::DOMAnimatedIntegerPair)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedInteger)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedIntegerPair)
NS_INTERFACE_MAP_END
/* Implementation */
static nsresult
ParseIntegerOptionalInteger(const nsAString& aValue,
PRInt32 aValues[2])
{
NS_ConvertUTF16toUTF8 value(aValue);
const char *str = value.get();
if (IsSVGWhitespace(*str))
return NS_ERROR_FAILURE;
char* rest;
PRInt32 x = strtol(str, &rest, 10);
PRInt32 y = x;
if (str == rest) {
// first value was illformed
return NS_ERROR_FAILURE;
}
if (*rest != '\0') {
while (IsSVGWhitespace(*rest)) {
++rest;
}
if (*rest == ',') {
++rest;
}
y = strtol(rest, &rest, 10);
if (*rest != '\0') {
// second value was illformed or there was trailing content
return NS_ERROR_FAILURE;
}
}
aValues[0] = x;
aValues[1] = y;
return NS_OK;
}
nsresult
nsSVGIntegerPair::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
PRInt32 val[2];
nsresult rv = ParseIntegerOptionalInteger(aValueAsString, val);
if (NS_FAILED(rv)) {
return rv;
}
mBaseVal[0] = val[0];
mBaseVal[1] = val[1];
mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal[0] = mBaseVal[0];
mAnimVal[1] = mBaseVal[1];
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
// We don't need to call DidChange* here - we're only called by
// nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
// which takes care of notifying.
return NS_OK;
}
void
nsSVGIntegerPair::GetBaseValueString(nsAString &aValueAsString)
{
aValueAsString.Truncate();
aValueAsString.AppendInt(mBaseVal[0]);
if (mBaseVal[0] != mBaseVal[1]) {
aValueAsString.AppendLiteral(", ");
aValueAsString.AppendInt(mBaseVal[1]);
}
}
void
nsSVGIntegerPair::SetBaseValue(PRInt32 aValue, PairIndex aPairIndex,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
PRUint32 index = (aPairIndex == eFirst ? 0 : 1);
mBaseVal[index] = aValue;
mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal[index] = aValue;
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
aSVGElement->DidChangeIntegerPair(mAttrEnum, aDoSetAttr);
}
void
nsSVGIntegerPair::SetBaseValues(PRInt32 aValue1, PRInt32 aValue2,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
mBaseVal[0] = aValue1;
mBaseVal[1] = aValue2;
mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal[0] = aValue1;
mAnimVal[1] = aValue2;
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
aSVGElement->DidChangeIntegerPair(mAttrEnum, aDoSetAttr);
}
void
nsSVGIntegerPair::SetAnimValue(const PRInt32 aValue[2], nsSVGElement *aSVGElement)
{
mAnimVal[0] = aValue[0];
mAnimVal[1] = aValue[1];
mIsAnimated = PR_TRUE;
aSVGElement->DidAnimateIntegerPair(mAttrEnum);
}
nsresult
nsSVGIntegerPair::ToDOMAnimatedInteger(nsIDOMSVGAnimatedInteger **aResult,
PairIndex aIndex,
nsSVGElement *aSVGElement)
{
*aResult = new DOMAnimatedIntegerPair(this, aIndex, aSVGElement);
NS_ADDREF(*aResult);
return NS_OK;
}
#ifdef MOZ_SMIL
nsISMILAttr*
nsSVGIntegerPair::ToSMILAttr(nsSVGElement *aSVGElement)
{
return new SMILIntegerPair(this, aSVGElement);
}
nsresult
nsSVGIntegerPair::SMILIntegerPair::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue,
PRBool& aPreventCachingOfSandwich) const
{
PRInt32 values[2];
nsresult rv = ParseIntegerOptionalInteger(aStr, values);
if (NS_FAILED(rv)) {
return rv;
}
nsSMILValue val(&SVGIntegerPairSMILType::sSingleton);
val.mU.mIntPair[0] = values[0];
val.mU.mIntPair[1] = values[1];
aValue = val;
aPreventCachingOfSandwich = PR_FALSE;
return NS_OK;
}
nsSMILValue
nsSVGIntegerPair::SMILIntegerPair::GetBaseValue() const
{
nsSMILValue val(&SVGIntegerPairSMILType::sSingleton);
val.mU.mIntPair[0] = mVal->mBaseVal[0];
val.mU.mIntPair[1] = mVal->mBaseVal[1];
return val;
}
void
nsSVGIntegerPair::SMILIntegerPair::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = PR_FALSE;
}
}
nsresult
nsSVGIntegerPair::SMILIntegerPair::SetAnimValue(const nsSMILValue& aValue)
{
NS_ASSERTION(aValue.mType == &SVGIntegerPairSMILType::sSingleton,
"Unexpected type to assign animated value");
if (aValue.mType == &SVGIntegerPairSMILType::sSingleton) {
mVal->SetAnimValue(aValue.mU.mIntPair, mSVGElement);
}
return NS_OK;
}
#endif // MOZ_SMIL

View File

@ -0,0 +1,162 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* 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 __NS_SVGINTEGERPAIR_H__
#define __NS_SVGINTEGERPAIR_H__
#include "nsIDOMSVGAnimatedInteger.h"
#include "nsSVGElement.h"
#include "nsDOMError.h"
#ifdef MOZ_SMIL
#include "nsISMILAttr.h"
class nsSMILValue;
class nsISMILType;
#endif // MOZ_SMIL
class nsSVGIntegerPair
{
public:
enum PairIndex {
eFirst,
eSecond
};
void Init(PRUint8 aAttrEnum = 0xff, PRInt32 aValue1 = 0, PRInt32 aValue2 = 0) {
mAnimVal[0] = mBaseVal[0] = aValue1;
mAnimVal[1] = mBaseVal[1] = aValue2;
mAttrEnum = aAttrEnum;
mIsAnimated = PR_FALSE;
mIsBaseSet = PR_FALSE;
}
nsresult SetBaseValueString(const nsAString& aValue,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr);
void GetBaseValueString(nsAString& aValue);
void SetBaseValue(PRInt32 aValue, PairIndex aIndex, nsSVGElement *aSVGElement, PRBool aDoSetAttr);
void SetBaseValues(PRInt32 aValue1, PRInt32 aValue2, nsSVGElement *aSVGElement, PRBool aDoSetAttr);
PRInt32 GetBaseValue(PairIndex aIndex) const
{ return mBaseVal[aIndex == eFirst ? 0 : 1]; }
void SetAnimValue(const PRInt32 aValue[2], nsSVGElement *aSVGElement);
PRInt32 GetAnimValue(PairIndex aIndex) const
{ return mAnimVal[aIndex == eFirst ? 0 : 1]; }
// Returns PR_TRUE if the animated value of this integer has been explicitly
// set (either by animation, or by taking on the base value which has been
// explicitly set by markup or a DOM call), PR_FALSE otherwise.
// If this returns PR_FALSE, the animated value is still valid, that is,
// useable, and represents the default base value of the attribute.
PRBool IsExplicitlySet() const
{ return mIsAnimated || mIsBaseSet; }
nsresult ToDOMAnimatedInteger(nsIDOMSVGAnimatedInteger **aResult,
PairIndex aIndex,
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[2];
PRInt32 mBaseVal[2];
PRUint8 mAttrEnum; // element specified tracking for attribute
PRPackedBool mIsAnimated;
PRPackedBool mIsBaseSet;
public:
struct DOMAnimatedIntegerPair : public nsIDOMSVGAnimatedInteger
{
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimatedIntegerPair)
DOMAnimatedIntegerPair(nsSVGIntegerPair* aVal, PairIndex aIndex, nsSVGElement *aSVGElement)
: mVal(aVal), mSVGElement(aSVGElement), mIndex(aIndex) {}
nsSVGIntegerPair* mVal; // kept alive because it belongs to content
nsRefPtr<nsSVGElement> mSVGElement;
PairIndex mIndex; // are we the first or second integer
NS_IMETHOD GetBaseVal(PRInt32* aResult)
{ *aResult = mVal->GetBaseValue(mIndex); return NS_OK; }
NS_IMETHOD SetBaseVal(PRInt32 aValue)
{
mVal->SetBaseValue(aValue, mIndex, mSVGElement, PR_TRUE);
return NS_OK;
}
// Script may have modified animation parameters or timeline -- DOM getters
// need to flush any resample requests to reflect these modifications.
NS_IMETHOD GetAnimVal(PRInt32* aResult)
{
#ifdef MOZ_SMIL
mSVGElement->FlushAnimations();
#endif
*aResult = mVal->GetAnimValue(mIndex);
return NS_OK;
}
};
#ifdef MOZ_SMIL
struct SMILIntegerPair : public nsISMILAttr
{
public:
SMILIntegerPair(nsSVGIntegerPair* 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.
nsSVGIntegerPair* mVal;
nsSVGElement* mSVGElement;
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue,
PRBool& aPreventCachingOfSandwich) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
};
#endif // MOZ_SMIL
};
#endif //__NS_SVGINTEGERPAIR_H__

View File

@ -0,0 +1,260 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 "nsSVGNumberPair.h"
#include "nsSVGUtils.h"
#include "nsTextFormatter.h"
#include "prdtoa.h"
#ifdef MOZ_SMIL
#include "nsSMILValue.h"
#include "SVGNumberPairSMILType.h"
#endif // MOZ_SMIL
using namespace mozilla;
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGNumberPair::DOMAnimatedNumberPair, mSVGElement)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGNumberPair::DOMAnimatedNumberPair)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGNumberPair::DOMAnimatedNumberPair)
DOMCI_DATA(SVGAnimatedNumberPair, nsSVGNumberPair::DOMAnimatedNumberPair)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGNumberPair::DOMAnimatedNumberPair)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedNumber)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedNumberPair)
NS_INTERFACE_MAP_END
/* Implementation */
static nsresult
ParseNumberOptionalNumber(const nsAString& aValue,
float aValues[2])
{
NS_ConvertUTF16toUTF8 value(aValue);
const char *str = value.get();
if (IsSVGWhitespace(*str))
return NS_ERROR_FAILURE;
char* rest;
float x = float(PR_strtod(str, &rest));
float y = x;
if (str == rest || !NS_FloatIsFinite(x)) {
// first value was illformed
return NS_ERROR_FAILURE;
}
if (*rest != '\0') {
while (IsSVGWhitespace(*rest)) {
++rest;
}
if (*rest == ',') {
++rest;
}
y = float(PR_strtod(rest, &rest));
if (*rest != '\0' || !NS_FloatIsFinite(y)) {
// second value was illformed or there was trailing content
return NS_ERROR_FAILURE;
}
}
aValues[0] = x;
aValues[1] = y;
return NS_OK;
}
nsresult
nsSVGNumberPair::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
float val[2];
nsresult rv = ParseNumberOptionalNumber(aValueAsString, val);
if (NS_FAILED(rv)) {
return rv;
}
mBaseVal[0] = val[0];
mBaseVal[1] = val[1];
mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal[0] = mBaseVal[0];
mAnimVal[1] = mBaseVal[1];
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
// We don't need to call DidChange* here - we're only called by
// nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
// which takes care of notifying.
return NS_OK;
}
void
nsSVGNumberPair::GetBaseValueString(nsAString &aValueAsString)
{
aValueAsString.Truncate();
aValueAsString.AppendFloat(mBaseVal[0]);
if (mBaseVal[0] != mBaseVal[1]) {
aValueAsString.AppendLiteral(", ");
aValueAsString.AppendFloat(mBaseVal[1]);
}
}
void
nsSVGNumberPair::SetBaseValue(float aValue, PairIndex aPairIndex,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
PRUint32 index = (aPairIndex == eFirst ? 0 : 1);
mBaseVal[index] = aValue;
mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal[index] = aValue;
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
aSVGElement->DidChangeNumberPair(mAttrEnum, aDoSetAttr);
}
void
nsSVGNumberPair::SetBaseValues(float aValue1, float aValue2,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
mBaseVal[0] = aValue1;
mBaseVal[1] = aValue2;
mIsBaseSet = PR_TRUE;
if (!mIsAnimated) {
mAnimVal[0] = aValue1;
mAnimVal[1] = aValue2;
}
#ifdef MOZ_SMIL
else {
aSVGElement->AnimationNeedsResample();
}
#endif
aSVGElement->DidChangeNumberPair(mAttrEnum, aDoSetAttr);
}
void
nsSVGNumberPair::SetAnimValue(const float aValue[2], nsSVGElement *aSVGElement)
{
mAnimVal[0] = aValue[0];
mAnimVal[1] = aValue[1];
mIsAnimated = PR_TRUE;
aSVGElement->DidAnimateNumberPair(mAttrEnum);
}
nsresult
nsSVGNumberPair::ToDOMAnimatedNumber(nsIDOMSVGAnimatedNumber **aResult,
PairIndex aIndex,
nsSVGElement *aSVGElement)
{
*aResult = new DOMAnimatedNumberPair(this, aIndex, aSVGElement);
NS_ADDREF(*aResult);
return NS_OK;
}
#ifdef MOZ_SMIL
nsISMILAttr*
nsSVGNumberPair::ToSMILAttr(nsSVGElement *aSVGElement)
{
return new SMILNumberPair(this, aSVGElement);
}
nsresult
nsSVGNumberPair::SMILNumberPair::ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* /*aSrcElement*/,
nsSMILValue& aValue,
PRBool& aPreventCachingOfSandwich) const
{
float values[2];
nsresult rv = ParseNumberOptionalNumber(aStr, values);
if (NS_FAILED(rv)) {
return rv;
}
nsSMILValue val(&SVGNumberPairSMILType::sSingleton);
val.mU.mNumberPair[0] = values[0];
val.mU.mNumberPair[1] = values[1];
aValue = val;
aPreventCachingOfSandwich = PR_FALSE;
return NS_OK;
}
nsSMILValue
nsSVGNumberPair::SMILNumberPair::GetBaseValue() const
{
nsSMILValue val(&SVGNumberPairSMILType::sSingleton);
val.mU.mNumberPair[0] = mVal->mBaseVal[0];
val.mU.mNumberPair[1] = mVal->mBaseVal[1];
return val;
}
void
nsSVGNumberPair::SMILNumberPair::ClearAnimValue()
{
if (mVal->mIsAnimated) {
mVal->SetAnimValue(mVal->mBaseVal, mSVGElement);
mVal->mIsAnimated = PR_FALSE;
}
}
nsresult
nsSVGNumberPair::SMILNumberPair::SetAnimValue(const nsSMILValue& aValue)
{
NS_ASSERTION(aValue.mType == &SVGNumberPairSMILType::sSingleton,
"Unexpected type to assign animated value");
if (aValue.mType == &SVGNumberPairSMILType::sSingleton) {
mVal->SetAnimValue(aValue.mU.mNumberPair, mSVGElement);
}
return NS_OK;
}
#endif // MOZ_SMIL

View File

@ -0,0 +1,164 @@
/* -*- 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 Robert Longson.
* Portions created by the Initial Developer are Copyright (C) 2011
* 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 __NS_SVGNUMBERPAIR_H__
#define __NS_SVGNUMBERPAIR_H__
#include "nsIDOMSVGNumber.h"
#include "nsIDOMSVGAnimatedNumber.h"
#include "nsSVGElement.h"
#include "nsDOMError.h"
#ifdef MOZ_SMIL
#include "nsISMILAttr.h"
class nsSMILValue;
class nsISMILType;
#endif // MOZ_SMIL
class nsSVGNumberPair
{
public:
enum PairIndex {
eFirst,
eSecond
};
void Init(PRUint8 aAttrEnum = 0xff, float aValue1 = 0, float aValue2 = 0) {
mAnimVal[0] = mBaseVal[0] = aValue1;
mAnimVal[1] = mBaseVal[1] = aValue2;
mAttrEnum = aAttrEnum;
mIsAnimated = PR_FALSE;
mIsBaseSet = PR_FALSE;
}
nsresult SetBaseValueString(const nsAString& aValue,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr);
void GetBaseValueString(nsAString& aValue);
void SetBaseValue(float aValue, PairIndex aIndex, nsSVGElement *aSVGElement, PRBool aDoSetAttr);
void SetBaseValues(float aValue1, float aValue2, nsSVGElement *aSVGElement, PRBool aDoSetAttr);
float GetBaseValue(PairIndex aIndex) const
{ return mBaseVal[aIndex == eFirst ? 0 : 1]; }
void SetAnimValue(const float aValue[2], nsSVGElement *aSVGElement);
float GetAnimValue(PairIndex aIndex) const
{ return mAnimVal[aIndex == eFirst ? 0 : 1]; }
// Returns PR_TRUE if the animated value of this number has been explicitly
// set (either by animation, or by taking on the base value which has been
// explicitly set by markup or a DOM call), PR_FALSE otherwise.
// If this returns PR_FALSE, the animated value is still valid, that is,
// useable, and represents the default base value of the attribute.
PRBool IsExplicitlySet() const
{ return mIsAnimated || mIsBaseSet; }
nsresult ToDOMAnimatedNumber(nsIDOMSVGAnimatedNumber **aResult,
PairIndex aIndex,
nsSVGElement* aSVGElement);
#ifdef MOZ_SMIL
// Returns a new nsISMILAttr object that the caller must delete
nsISMILAttr* ToSMILAttr(nsSVGElement* aSVGElement);
#endif // MOZ_SMIL
private:
float mAnimVal[2];
float mBaseVal[2];
PRUint8 mAttrEnum; // element specified tracking for attribute
PRPackedBool mIsAnimated;
PRPackedBool mIsBaseSet;
public:
struct DOMAnimatedNumberPair : public nsIDOMSVGAnimatedNumber
{
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimatedNumberPair)
DOMAnimatedNumberPair(nsSVGNumberPair* aVal, PairIndex aIndex, nsSVGElement *aSVGElement)
: mVal(aVal), mSVGElement(aSVGElement), mIndex(aIndex) {}
nsSVGNumberPair* mVal; // kept alive because it belongs to content
nsRefPtr<nsSVGElement> mSVGElement;
PairIndex mIndex; // are we the first or second number
NS_IMETHOD GetBaseVal(float* aResult)
{ *aResult = mVal->GetBaseValue(mIndex); return NS_OK; }
NS_IMETHOD SetBaseVal(float aValue)
{
NS_ENSURE_FINITE(aValue, NS_ERROR_ILLEGAL_VALUE);
mVal->SetBaseValue(aValue, mIndex, mSVGElement, PR_TRUE);
return NS_OK;
}
// Script may have modified animation parameters or timeline -- DOM getters
// need to flush any resample requests to reflect these modifications.
NS_IMETHOD GetAnimVal(float* aResult)
{
#ifdef MOZ_SMIL
mSVGElement->FlushAnimations();
#endif
*aResult = mVal->GetAnimValue(mIndex);
return NS_OK;
}
};
#ifdef MOZ_SMIL
struct SMILNumberPair : public nsISMILAttr
{
public:
SMILNumberPair(nsSVGNumberPair* 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.
nsSVGNumberPair* mVal;
nsSVGElement* mSVGElement;
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const nsISMILAnimationElement* aSrcElement,
nsSMILValue& aValue,
PRBool& aPreventCachingOfSandwich) const;
virtual nsSMILValue GetBaseValue() const;
virtual void ClearAnimValue();
virtual nsresult SetAnimValue(const nsSMILValue& aValue);
};
#endif // MOZ_SMIL
};
#endif //__NS_SVGNUMBERPAIR_H__

View File

@ -65,6 +65,7 @@ nsSVGString::SetBaseValue(const nsAString& aValue,
NS_ASSERTION(aSVGElement, "Null element passed to SetBaseValue");
if (aDoSetAttr) {
mIsBaseSet = PR_TRUE;
aSVGElement->SetStringBaseValue(mAttrEnum, aValue);
}
#ifdef MOZ_SMIL

View File

@ -48,6 +48,7 @@ public:
void Init(PRUint8 aAttrEnum) {
mAnimVal = nsnull;
mAttrEnum = aAttrEnum;
mIsBaseSet = PR_FALSE;
}
void SetBaseValue(const nsAString& aValue,
@ -59,6 +60,14 @@ public:
void SetAnimValue(const nsAString& aValue, nsSVGElement *aSVGElement);
void GetAnimValue(nsAString& aValue, const nsSVGElement *aSVGElement) const;
// Returns PR_TRUE if the animated value of this string has been explicitly
// set (either by animation, or by taking on the base value which has been
// explicitly set by markup or a DOM call), PR_FALSE otherwise.
// If this returns PR_FALSE, the animated value is still valid, that is,
// useable, and represents the default base value of the attribute.
PRBool IsExplicitlySet() const
{ return !!mAnimVal || mIsBaseSet; }
nsresult ToDOMAnimatedString(nsIDOMSVGAnimatedString **aResult,
nsSVGElement *aSVGElement);
#ifdef MOZ_SMIL
@ -70,6 +79,7 @@ private:
nsAutoPtr<nsString> mAnimVal;
PRUint8 mAttrEnum; // element specified tracking for attribute
PRPackedBool mIsBaseSet;
public:
struct DOMAnimatedString : public nsIDOMSVGAnimatedString

View File

@ -1,17 +1,20 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="750">
<defs>
<filter id="filter">
<!-- <boolean> (preserveAlpha) -->
<!-- <enum> (edgeMode) -->
<!-- <number> (divisor) -->
<!-- <integer> (targetX) -->
<!-- <string> (result) -->
<feConvolveMatrix id="convolve"/>
</filter>
<!-- <angle> (orient) -->
<!-- <length> (markerWidth) -->
<!-- <preserveAspectRatio> (preserveAspectRatio) -->
<marker id="marker"/>
</defs>
<defs>
<!-- <integer-optional-integer> (filterRes) -->
<filter id="filter">
<!-- <boolean> (preserveAlpha) -->
<!-- <enum> (edgeMode) -->
<!-- <number> (divisor) -->
<!-- <integer> (targetX) -->
<!-- <string> (result) -->
<feConvolveMatrix id="convolve"/>
<!-- <number-optional-number> (stdDeviation) -->
<feGaussianBlur id="blur"/>
</filter>
<!-- <angle> (orient) -->
<!-- <length> (markerWidth) -->
<!-- <preserveAspectRatio> (preserveAspectRatio) -->
<marker id="marker"/>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 473 B

After

Width:  |  Height:  |  Size: 646 B

View File

@ -25,6 +25,7 @@ function runTests()
var doc = $("svg").contentWindow.document;
var filter = doc.getElementById("filter");
var convolve = doc.getElementById("convolve");
var blur = doc.getElementById("blur");
var marker = doc.getElementById("marker");
// class attribute
@ -67,6 +68,28 @@ function runTests()
is(convolve.divisor.animVal, 7.5, "number animVal");
is(convolve.getAttribute("divisor"), "7.5", "number attribute");
// number-optional-number attribute
blur.setAttribute("stdDeviation", "20.5");
is(blur.stdDeviationX.baseVal, 20.5, "number-optional-number first baseVal");
is(blur.stdDeviationX.animVal, 20.5, "number-optional-number first animVal");
is(blur.stdDeviationY.baseVal, 20.5, "number-optional-number second baseVal");
is(blur.stdDeviationY.animVal, 20.5, "number-optional-number second animVal");
blur.stdDeviationX.baseVal = 8.5;
is(blur.stdDeviationX.animVal, 8.5, "number-optional-number first animVal");
is(blur.stdDeviationY.animVal, 20.5, "number-optional-number second animVal");
is(blur.getAttribute("stdDeviation"), "8.5, 20.5", "number-optional-number attribute");
blur.stdDeviationY.baseVal = 8.5;
is(blur.getAttribute("stdDeviation"), "8.5", "number-optional-number attribute");
blur.setStdDeviation(24.5, 0.5);
is(blur.stdDeviationX.baseVal, 24.5, "integer-optional-integer first baseVal");
is(blur.stdDeviationX.animVal, 24.5, "integer-optional-integer first animVal");
is(blur.stdDeviationY.baseVal, 0.5, "integer-optional-integer second baseVal");
is(blur.stdDeviationY.animVal, 0.5, "integer-optional-integer second animVal");
// integer attribute
convolve.setAttribute("targetX", "12");
@ -76,6 +99,28 @@ function runTests()
is(convolve.targetX.animVal, 7, "integer animVal");
is(convolve.getAttribute("targetX"), "7", "integer attribute");
// integer-optional-integer attribute
filter.setAttribute("filterRes", "100");
is(filter.filterResX.baseVal, 100, "integer-optional-integer first baseVal");
is(filter.filterResX.animVal, 100, "integer-optional-integer first animVal");
is(filter.filterResY.baseVal, 100, "integer-optional-integer second baseVal");
is(filter.filterResY.animVal, 100, "integer-optional-integer second animVal");
filter.filterResX.baseVal = 50;
is(filter.filterResX.animVal, 50, "integer-optional-integer first animVal");
is(filter.filterResY.animVal, 100, "integer-optional-integer second animVal");
is(filter.getAttribute("filterRes"), "50, 100", "integer-optional-integer attribute");
filter.filterResY.baseVal = 50;
is(filter.getAttribute("filterRes"), "50", "integer-optional-integer attribute");
filter.setFilterRes(80, 90);
is(filter.filterResX.baseVal, 80, "integer-optional-integer first baseVal");
is(filter.filterResX.animVal, 80, "integer-optional-integer first animVal");
is(filter.filterResY.baseVal, 90, "integer-optional-integer second baseVal");
is(filter.filterResY.animVal, 90, "integer-optional-integer second animVal");
// angle attribute
marker.setAttribute("orient", "90deg");

View File

@ -1162,12 +1162,16 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedInteger, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedIntegerPair, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedLength, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedLengthList, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedNumber, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedNumberPair, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedNumberList, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedPreserveAspectRatio, nsDOMGenericSH,
@ -3679,6 +3683,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedInteger)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedIntegerPair, nsIDOMSVGAnimatedInteger)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedInteger)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedLength, nsIDOMSVGAnimatedLength)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedLength)
DOM_CLASSINFO_MAP_END
@ -3691,6 +3699,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedNumber)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedNumberPair, nsIDOMSVGAnimatedNumber)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedNumber)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedNumberList, nsIDOMSVGAnimatedNumberList)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedNumberList)
DOM_CLASSINFO_MAP_END

View File

@ -305,9 +305,11 @@ DOMCI_CLASS(SVGAnimatedAngle)
DOMCI_CLASS(SVGAnimatedBoolean)
DOMCI_CLASS(SVGAnimatedEnumeration)
DOMCI_CLASS(SVGAnimatedInteger)
DOMCI_CLASS(SVGAnimatedIntegerPair)
DOMCI_CLASS(SVGAnimatedLength)
DOMCI_CLASS(SVGAnimatedLengthList)
DOMCI_CLASS(SVGAnimatedNumber)
DOMCI_CLASS(SVGAnimatedNumberPair)
DOMCI_CLASS(SVGAnimatedNumberList)
DOMCI_CLASS(SVGAnimatedPreserveAspectRatio)
DOMCI_CLASS(SVGAnimatedRect)

View File

@ -0,0 +1,25 @@
<!--
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"
onload="setTimeAndSnapshot(1.9999, true)">
<title>Test animation of the "stdDeviation" &lt;number-optional-number&gt; attribute on "feGaussianBlur" elements</title>
<script xlink:href="smil-util.js" type="text/javascript"/>
<filter id="filter" x="0" y="0" width="1" height="1" filterRes="1000">
<feGaussianBlur stdDeviation="50">
<animate attributeName="stdDeviation"
calcMode="linear"
begin="0s" dur="2s"
from="100,100" to="0"
fill="freeze"/>
</feGaussianBlur>
</filter>
<rect width="100%" height="100%" fill="lime"/>
<g transform="translate(50, 0)">
<circle fill="red" cx="100" cy="100" r="98" transform="translate(50, 0)" filter="url(#filter)"/>
</g>
<circle fill="lime" cx="200" cy="100" r="100"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,24 @@
<!--
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"
onload="setTimeAndSnapshot(1, true)">
<title>Test animation of the "filterRes" &lt;integer-optional-integer&gt; attribute on "filter" elements</title>
<script xlink:href="smil-util.js" type="text/javascript"/>
<filter id="filter" x="0" y="0" width="1" height="1" filterRes="10 10">
<animate attributeName="filterRes"
calcMode="linear"
begin="0s" dur="2s"
from="0" to="2000 2000"
fill="freeze"/>
<feGaussianBlur stdDeviation="0.001"/>
</filter>
<rect width="100%" height="100%" fill="lime"/>
<g transform="translate(50, 0)">
<circle fill="red" cx="100" cy="100" r="98" transform="translate(50, 0)" filter="url(#filter)"/>
</g>
<circle fill="lime" cx="200" cy="100" r="100"/>
</svg>

After

Width:  |  Height:  |  Size: 998 B

View File

@ -98,9 +98,15 @@ fails == anim-fillcolor-1.svg anim-standard-ref.svg # bug 436296
== anim-offset-01.svg lime.svg
== anim-pathLength-01.svg anim-pathLength-01-ref.svg
# animate some <number-optional-number> attributes:
== anim-feGaussianBlur-01.svg lime.svg
# animate some <integer> attributes:
== anim-feTurbulence-numOctaves-01.svg anim-feTurbulence-numOctaves-01-ref.svg
# animate some <integer-optional-integer> attributes:
== anim-filter-filterRes-01.svg lime.svg
# animate some <angle> attributes:
== anim-marker-orient-01.svg lime.svg

View File

@ -149,9 +149,11 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
// temporary offscreen surface that we'll paint into):
gfxIntSize filterRes;
if (filter->HasAttr(kNameSpaceID_None, nsGkAtoms::filterRes)) {
PRInt32 filterResX, filterResY;
filter->GetAnimatedIntegerValues(&filterResX, &filterResY, nsnull);
if (filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES].IsExplicitlySet()) {
PRInt32 filterResX =
filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES].GetAnimValue(nsSVGIntegerPair::eFirst);
PRInt32 filterResY =
filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES].GetAnimValue(nsSVGIntegerPair::eSecond);
// XXX what if the 'filterRes' attribute has a bad value? error console warning?
// We don't care if this overflows, because we can handle upscaling/

View File

@ -139,13 +139,13 @@ nsSVGFilterInstance::ComputeFilterPrimitiveSubregion(PrimitiveInfo* aPrimitive)
&fE->mLengthAttributes[nsSVGFE::X], mTargetBBox, mTargetFrame);
gfxRect region = UserSpaceToFilterSpace(feArea);
if (!fE->HasAttr(kNameSpaceID_None, nsGkAtoms::x))
if (!fE->mLengthAttributes[nsSVGFE::X].IsExplicitlySet())
region.x = defaultFilterSubregion.X();
if (!fE->HasAttr(kNameSpaceID_None, nsGkAtoms::y))
if (!fE->mLengthAttributes[nsSVGFE::Y].IsExplicitlySet())
region.y = defaultFilterSubregion.Y();
if (!fE->HasAttr(kNameSpaceID_None, nsGkAtoms::width))
if (!fE->mLengthAttributes[nsSVGFE::WIDTH].IsExplicitlySet())
region.width = defaultFilterSubregion.Width();
if (!fE->HasAttr(kNameSpaceID_None, nsGkAtoms::height))
if (!fE->mLengthAttributes[nsSVGFE::HEIGHT].IsExplicitlySet())
region.height = defaultFilterSubregion.Height();
// We currently require filter primitive subregions to be pixel-aligned.