nsresult SVGPathSegListSMILType::Add(SMILValue& aDest, const SMILValue& aValueToAdd, uint32_t aCount) const { MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type"); SVGPathDataAndInfo& dest = *static_cast<SVGPathDataAndInfo*>(aDest.mU.mPtr); const SVGPathDataAndInfo& valueToAdd = *static_cast<const SVGPathDataAndInfo*>(aValueToAdd.mU.mPtr); if (valueToAdd.IsIdentity()) { // Adding identity value - no-op return NS_OK; } if (!dest.IsIdentity()) { // Neither value is identity; make sure they're compatible. MOZ_ASSERT(dest.Element() == valueToAdd.Element(), "adding values from different elements...?"); PathInterpolationResult check = CanInterpolate(dest, valueToAdd); if (check == eCannotInterpolate) { // SVGContentUtils::ReportToConsole - can't add path segment lists with // different numbers of segments, with arcs that have different flag // values, or with incompatible segment types. return NS_ERROR_FAILURE; } if (check == eRequiresConversion) { // Convert dest, in-place, to match the types in valueToAdd: ConvertAllPathSegmentData(dest.begin(), dest.end(), valueToAdd.begin(), valueToAdd.end(), dest.begin()); } } return AddWeightedPathSegLists(1.0, dest, aCount, valueToAdd, dest); }
double TLinear::Interpolate(const uint64& Tm) const { AssertR(CanInterpolate(Tm), "TLinear::Interpolate: Time not in the desired interval!"); const TUInt64FltPr& PrevRec = Buff.GetOldest(); if (Tm == PrevRec.Val1) { return PrevRec.Val2; } const TUInt64FltPr& NextRec = Buff.GetOldest(1); // don't need to check if the times of the previous rec and next rec are equal since if // that is true Tm will be equal to PrevRec.Tm and the correct result will be returned const double Result = PrevRec.Val2 + ((double) (Tm - PrevRec.Val1) / (NextRec.Val1 - PrevRec.Val1)) * (NextRec.Val2 - PrevRec.Val2); EAssertR(!TFlt::IsNan(Result), "TLinear: result of interpolation is NaN!"); return Result; }
void TCurrentPoint::SetNextInterpTm(const uint64& Tm) { // at least one past (or current time) record needs to be in the buffer bool Change = false; while (Buff.Len() >= 2 && Buff.GetOldest(1).Val1 <= Tm) { Buff.DelOldest(); Change = true; } if (Change) { EAssertR(CanInterpolate(Tm), "WTF!? Current point interpolator cannot intrpolate after setting new time!"); } // when the loop finishes we have at least 1 record in the buffer // with a timestamp <= Tm }
nsresult SVGPathSegListSMILType::Interpolate(const SMILValue& aStartVal, const SMILValue& aEndVal, double aUnitDistance, SMILValue& aResult) const { MOZ_ASSERT(aStartVal.mType == aEndVal.mType, "Trying to interpolate different types"); MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const SVGPathDataAndInfo& start = *static_cast<const SVGPathDataAndInfo*>(aStartVal.mU.mPtr); const SVGPathDataAndInfo& end = *static_cast<const SVGPathDataAndInfo*>(aEndVal.mU.mPtr); SVGPathDataAndInfo& result = *static_cast<SVGPathDataAndInfo*>(aResult.mU.mPtr); MOZ_ASSERT(result.IsIdentity(), "expecting outparam to start out as identity"); PathInterpolationResult check = CanInterpolate(start, end); if (check == eCannotInterpolate) { // SVGContentUtils::ReportToConsole - can't interpolate path segment lists // with different numbers of segments, with arcs with different flag values, // or with incompatible segment types. return NS_ERROR_FAILURE; } const SVGPathDataAndInfo* startListToUse = &start; if (check == eRequiresConversion) { // Can't convert |start| in-place, since it's const. Instead, we copy it // into |result|, converting the types as we go, and use that as our start. if (!result.SetLength(end.Length())) { return NS_ERROR_OUT_OF_MEMORY; } result.SetElement(end.Element()); // propagate target element info! ConvertAllPathSegmentData(start.begin(), start.end(), end.begin(), end.end(), result.begin()); startListToUse = &result; } return AddWeightedPathSegLists(1.0 - aUnitDistance, *startListToUse, aUnitDistance, end, result); }
double TCurrentPoint::Interpolate(const uint64& Tm) const { IAssertR(CanInterpolate(Tm), "TCurrentPoint::Interpolate: Time not in the desired interval!"); return Buff.GetOldest().Val2; }