PRInt8 nsSMILAnimationFunction::CompareTo(const nsSMILAnimationFunction* aOther) const { NS_ENSURE_TRUE(aOther, 0); NS_ASSERTION(aOther != this, "Trying to compare to self"); // Inactive animations sort first if (!IsActiveOrFrozen() && aOther->IsActiveOrFrozen()) return -1; if (IsActiveOrFrozen() && !aOther->IsActiveOrFrozen()) return 1; // Sort based on begin time if (mBeginTime != aOther->GetBeginTime()) return mBeginTime > aOther->GetBeginTime() ? 1 : -1; // Next sort based on syncbase dependencies: the dependent element sorts after // its syncbase const nsSMILTimedElement& thisTimedElement = mAnimationElement->TimedElement(); const nsSMILTimedElement& otherTimedElement = aOther->mAnimationElement->TimedElement(); if (thisTimedElement.IsTimeDependent(otherTimedElement)) return 1; if (otherTimedElement.IsTimeDependent(thisTimedElement)) return -1; // Animations that appear later in the document sort after those earlier in // the document nsIContent& thisContent = mAnimationElement->AsElement(); nsIContent& otherContent = aOther->mAnimationElement->AsElement(); NS_ABORT_IF_FALSE(&thisContent != &otherContent, "Two animations cannot have the same animation content element!"); return (nsContentUtils::PositionIsBefore(&thisContent, &otherContent)) ? -1 : 1; }
void nsSMILAnimationFunction::ComposeResult(const nsISMILAttr& aSMILAttr, nsSMILValue& aResult) { mHasChanged = PR_FALSE; // Skip animations that are inactive or in error if (!IsActiveOrFrozen() || mErrorFlags != 0) return; // Get the animation values nsSMILValueArray values; nsresult rv = GetValues(aSMILAttr, values); if (NS_FAILED(rv)) return; // Check that we have the right number of keySplines and keyTimes CheckValueListDependentAttrs(values.Length()); if (mErrorFlags != 0) return; // If this interval is active, we must have a non-negative mSampleTime NS_ABORT_IF_FALSE(mSampleTime >= 0 || !mIsActive, "Negative sample time for active animation"); NS_ABORT_IF_FALSE(mSimpleDuration.IsResolved() || mSimpleDuration.IsIndefinite() || mLastValue, "Unresolved simple duration for active or frozen animation"); nsSMILValue result(aResult.mType); if (mSimpleDuration.IsIndefinite() || (values.Length() == 1 && TreatSingleValueAsStatic())) { // Indefinite duration or only one value set: Always set the first value result = values[0]; } else if (mLastValue) { // Sampling last value const nsSMILValue& last = values[values.Length() - 1]; result = last; // See comment in AccumulateResult: to-animation does not accumulate if (!IsToAnimation() && GetAccumulate() && mRepeatIteration) { // If the target attribute type doesn't support addition Add will // fail leaving result = last result.Add(last, mRepeatIteration); } } else if (!mFrozenValue.IsNull() && !mHasChanged) { // Frozen to animation result = mFrozenValue; } else { // Interpolation if (NS_FAILED(InterpolateResult(values, result, aResult))) return; if (NS_FAILED(AccumulateResult(values, result))) return; if (IsToAnimation() && mIsFrozen) { mFrozenValue = result; } } // If additive animation isn't required or isn't supported, set the value. if (!IsAdditive() || NS_FAILED(aResult.SandwichAdd(result))) { aResult.Swap(result); // Note: The old value of aResult is now in |result|, and it will get // cleaned up when |result| goes out of scope, when this function returns. } }
void nsSMILAnimationFunction::ComposeResult(const nsISMILAttr& aSMILAttr, nsSMILValue& aResult) { mHasChanged = false; mPrevSampleWasSingleValueAnimation = false; mWasSkippedInPrevSample = false; // Skip animations that are inactive or in error if (!IsActiveOrFrozen() || mErrorFlags != 0) return; // Get the animation values nsSMILValueArray values; nsresult rv = GetValues(aSMILAttr, values); if (NS_FAILED(rv)) return; // Check that we have the right number of keySplines and keyTimes CheckValueListDependentAttrs(values.Length()); if (mErrorFlags != 0) return; // If this interval is active, we must have a non-negative mSampleTime NS_ABORT_IF_FALSE(mSampleTime >= 0 || !mIsActive, "Negative sample time for active animation"); NS_ABORT_IF_FALSE(mSimpleDuration.IsResolved() || mLastValue, "Unresolved simple duration for active or frozen animation"); // If we want to add but don't have a base value then just fail outright. // This can happen when we skipped getting the base value because there's an // animation function in the sandwich that should replace it but that function // failed unexpectedly. bool isAdditive = IsAdditive(); if (isAdditive && aResult.IsNull()) return; nsSMILValue result; if (values.Length() == 1 && !IsToAnimation()) { // Single-valued animation result = values[0]; mPrevSampleWasSingleValueAnimation = true; } else if (mLastValue) { // Sampling last value const nsSMILValue& last = values[values.Length() - 1]; result = last; // See comment in AccumulateResult: to-animation does not accumulate if (!IsToAnimation() && GetAccumulate() && mRepeatIteration) { // If the target attribute type doesn't support addition Add will // fail leaving result = last result.Add(last, mRepeatIteration); } } else { // Interpolation if (NS_FAILED(InterpolateResult(values, result, aResult))) return; if (NS_FAILED(AccumulateResult(values, result))) return; } // If additive animation isn't required or isn't supported, set the value. if (!isAdditive || NS_FAILED(aResult.SandwichAdd(result))) { aResult.Swap(result); // Note: The old value of aResult is now in |result|, and it will get // cleaned up when |result| goes out of scope, when this function returns. } }