123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "nsSVGNumberPair.h"
- #include "nsSVGAttrTearoffTable.h"
- #include "nsCharSeparatedTokenizer.h"
- #include "nsSMILValue.h"
- #include "SVGContentUtils.h"
- #include "SVGNumberPairSMILType.h"
- using namespace mozilla;
- using namespace mozilla::dom;
- static nsSVGAttrTearoffTable<nsSVGNumberPair, nsSVGNumberPair::DOMAnimatedNumber>
- sSVGFirstAnimatedNumberTearoffTable;
- static nsSVGAttrTearoffTable<nsSVGNumberPair, nsSVGNumberPair::DOMAnimatedNumber>
- sSVGSecondAnimatedNumberTearoffTable;
- static nsresult
- ParseNumberOptionalNumber(const nsAString& aValue,
- float aValues[2])
- {
- nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
- tokenizer(aValue, ',',
- nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
- if (tokenizer.whitespaceBeforeFirstToken()) {
- return NS_ERROR_DOM_SYNTAX_ERR;
- }
- uint32_t i;
- for (i = 0; i < 2 && tokenizer.hasMoreTokens(); ++i) {
- if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), aValues[i])) {
- return NS_ERROR_DOM_SYNTAX_ERR;
- }
- }
- if (i == 1) {
- aValues[1] = aValues[0];
- }
- if (i == 0 || // Too few values.
- tokenizer.hasMoreTokens() || // Too many values.
- tokenizer.whitespaceAfterCurrentToken() || // Trailing whitespace.
- tokenizer.separatorAfterCurrentToken()) { // Trailing comma.
- return NS_ERROR_DOM_SYNTAX_ERR;
- }
- return NS_OK;
- }
- nsresult
- nsSVGNumberPair::SetBaseValueString(const nsAString &aValueAsString,
- nsSVGElement *aSVGElement)
- {
- float val[2];
- nsresult rv = ParseNumberOptionalNumber(aValueAsString, val);
- if (NS_FAILED(rv)) {
- return rv;
- }
- mBaseVal[0] = val[0];
- mBaseVal[1] = val[1];
- mIsBaseSet = true;
- if (!mIsAnimated) {
- mAnimVal[0] = mBaseVal[0];
- mAnimVal[1] = mBaseVal[1];
- }
- else {
- aSVGElement->AnimationNeedsResample();
- }
- // We don't need to call Will/DidChange* here - we're only called by
- // nsSVGElement::ParseAttribute under Element::SetAttr,
- // which takes care of notifying.
- return NS_OK;
- }
- void
- nsSVGNumberPair::GetBaseValueString(nsAString &aValueAsString) const
- {
- 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)
- {
- uint32_t index = (aPairIndex == eFirst ? 0 : 1);
- if (mIsBaseSet && mBaseVal[index] == aValue) {
- return;
- }
- nsAttrValue emptyOrOldValue = aSVGElement->WillChangeNumberPair(mAttrEnum);
- mBaseVal[index] = aValue;
- mIsBaseSet = true;
- if (!mIsAnimated) {
- mAnimVal[index] = aValue;
- }
- else {
- aSVGElement->AnimationNeedsResample();
- }
- aSVGElement->DidChangeNumberPair(mAttrEnum, emptyOrOldValue);
- }
- void
- nsSVGNumberPair::SetBaseValues(float aValue1, float aValue2,
- nsSVGElement *aSVGElement)
- {
- if (mIsBaseSet && mBaseVal[0] == aValue1 && mBaseVal[1] == aValue2) {
- return;
- }
- nsAttrValue emptyOrOldValue = aSVGElement->WillChangeNumberPair(mAttrEnum);
- mBaseVal[0] = aValue1;
- mBaseVal[1] = aValue2;
- mIsBaseSet = true;
- if (!mIsAnimated) {
- mAnimVal[0] = aValue1;
- mAnimVal[1] = aValue2;
- }
- else {
- aSVGElement->AnimationNeedsResample();
- }
- aSVGElement->DidChangeNumberPair(mAttrEnum, emptyOrOldValue);
- }
- void
- nsSVGNumberPair::SetAnimValue(const float aValue[2], nsSVGElement *aSVGElement)
- {
- if (mIsAnimated && mAnimVal[0] == aValue[0] && mAnimVal[1] == aValue[1]) {
- return;
- }
- mAnimVal[0] = aValue[0];
- mAnimVal[1] = aValue[1];
- mIsAnimated = true;
- aSVGElement->DidAnimateNumberPair(mAttrEnum);
- }
- already_AddRefed<SVGAnimatedNumber>
- nsSVGNumberPair::ToDOMAnimatedNumber(PairIndex aIndex,
- nsSVGElement* aSVGElement)
- {
- RefPtr<DOMAnimatedNumber> domAnimatedNumber =
- aIndex == eFirst ? sSVGFirstAnimatedNumberTearoffTable.GetTearoff(this) :
- sSVGSecondAnimatedNumberTearoffTable.GetTearoff(this);
- if (!domAnimatedNumber) {
- domAnimatedNumber = new DOMAnimatedNumber(this, aIndex, aSVGElement);
- if (aIndex == eFirst) {
- sSVGFirstAnimatedNumberTearoffTable.AddTearoff(this, domAnimatedNumber);
- } else {
- sSVGSecondAnimatedNumberTearoffTable.AddTearoff(this, domAnimatedNumber);
- }
- }
- return domAnimatedNumber.forget();
- }
- nsSVGNumberPair::DOMAnimatedNumber::~DOMAnimatedNumber()
- {
- if (mIndex == eFirst) {
- sSVGFirstAnimatedNumberTearoffTable.RemoveTearoff(mVal);
- } else {
- sSVGSecondAnimatedNumberTearoffTable.RemoveTearoff(mVal);
- }
- }
- nsISMILAttr*
- nsSVGNumberPair::ToSMILAttr(nsSVGElement *aSVGElement)
- {
- return new SMILNumberPair(this, aSVGElement);
- }
- nsresult
- nsSVGNumberPair::SMILNumberPair::ValueFromString(const nsAString& aStr,
- const dom::SVGAnimationElement* /*aSrcElement*/,
- nsSMILValue& aValue,
- bool& 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 = 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->mIsAnimated = false;
- mVal->mAnimVal[0] = mVal->mBaseVal[0];
- mVal->mAnimVal[1] = mVal->mBaseVal[1];
- mSVGElement->DidAnimateNumberPair(mVal->mAttrEnum);
- }
- }
- 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;
- }
|