コード例 #1
0
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.
    }
}