void InvalidatableInterpolation::applyStack(const ActiveInterpolations& interpolations, InterpolationEnvironment& environment) { ASSERT(!interpolations.isEmpty()); size_t startingIndex = 0; // Compute the underlying value to composite onto. UnderlyingValue underlyingValue; const InvalidatableInterpolation& firstInterpolation = toInvalidatableInterpolation(*interpolations.at(startingIndex)); if (firstInterpolation.dependsOnUnderlyingValue()) { underlyingValue.set(firstInterpolation.maybeConvertUnderlyingValue(environment)); } else { const InterpolationValue* firstValue = firstInterpolation.ensureValidInterpolation(environment, UnderlyingValue()); // Fast path for replace interpolations that are the only one to apply. if (interpolations.size() == 1) { if (firstValue) { firstInterpolation.setFlagIfInheritUsed(environment); firstValue->type().apply(firstValue->interpolableValue(), firstValue->nonInterpolableValue(), environment); } return; } underlyingValue.set(firstValue); startingIndex++; } // Composite interpolations onto the underlying value. bool shouldApply = false; for (size_t i = startingIndex; i < interpolations.size(); i++) { const InvalidatableInterpolation& currentInterpolation = toInvalidatableInterpolation(*interpolations.at(i)); ASSERT(currentInterpolation.dependsOnUnderlyingValue()); const InterpolationValue* currentValue = currentInterpolation.ensureValidInterpolation(environment, underlyingValue); if (!currentValue) continue; shouldApply = true; currentInterpolation.setFlagIfInheritUsed(environment); double underlyingFraction = currentInterpolation.underlyingFraction(); if (underlyingFraction == 0 || !underlyingValue || underlyingValue->type() != currentValue->type()) underlyingValue.set(currentValue); else currentValue->type().composite(underlyingValue, underlyingFraction, *currentValue); } if (shouldApply && underlyingValue) underlyingValue->type().apply(underlyingValue->interpolableValue(), underlyingValue->nonInterpolableValue(), environment); }
void PathInterpolationFunctions::composite(UnderlyingValue& underlyingValue, double underlyingFraction, const InterpolationValue& value) { const InterpolableList& list = toInterpolableList(value.interpolableValue()); double neutralComponent = toInterpolableNumber(list.get(PathNeutralIndex))->value(); if (neutralComponent == 0) { underlyingValue.set(&value); return; } ASSERT(pathSegTypesMatch( toSVGPathNonInterpolableValue(underlyingValue->nonInterpolableValue())->pathSegTypes(), toSVGPathNonInterpolableValue(value.nonInterpolableValue())->pathSegTypes())); underlyingValue.mutableComponent().interpolableValue->scaleAndAdd(neutralComponent, value.interpolableValue()); underlyingValue.mutableComponent().nonInterpolableValue = const_cast<NonInterpolableValue*>(value.nonInterpolableValue()); // Take ref. }
void SVGTransformListInterpolationType::composite(UnderlyingValue& underlyingValue, double underlyingFraction, const InterpolationValue& value) const { // TODO(suzyh): Implement addition underlyingValue.set(&value); }
void CSSImageListInterpolationType::composite(UnderlyingValue& underlyingValue, double underlyingFraction, const InterpolationValue& value) const { underlyingValue.set(&value); }