void PathInterpolationFunctions::composite( UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationType& type, const InterpolationValue& value) { const InterpolableList& list = toInterpolableList(*value.interpolableValue); double neutralComponent = toInterpolableNumber(list.get(PathNeutralIndex))->value(); if (neutralComponent == 0) { underlyingValueOwner.set(type, value); return; } DCHECK(pathSegTypesMatch( toSVGPathNonInterpolableValue( *underlyingValueOwner.value().nonInterpolableValue) .pathSegTypes(), toSVGPathNonInterpolableValue(*value.nonInterpolableValue) .pathSegTypes())); underlyingValueOwner.mutableValue().interpolableValue->scaleAndAdd( neutralComponent, *value.interpolableValue); underlyingValueOwner.mutableValue().nonInterpolableValue = value.nonInterpolableValue.get(); }
void CSSFilterListInterpolationType::composite( UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { const NonInterpolableList& underlyingNonInterpolableList = toNonInterpolableList(*underlyingValueOwner.value().nonInterpolableValue); const NonInterpolableList& nonInterpolableList = toNonInterpolableList(*value.nonInterpolableValue); size_t underlyingLength = underlyingNonInterpolableList.length(); size_t length = nonInterpolableList.length(); for (size_t i = 0; i < underlyingLength && i < length; i++) { if (!FilterInterpolationFunctions::filtersAreCompatible( *underlyingNonInterpolableList.get(i), *nonInterpolableList.get(i))) { underlyingValueOwner.set(*this, value); return; } } InterpolableList& underlyingInterpolableList = toInterpolableList( *underlyingValueOwner.mutableValue().interpolableValue); const InterpolableList& interpolableList = toInterpolableList(*value.interpolableValue); DCHECK_EQ(underlyingLength, underlyingInterpolableList.length()); DCHECK_EQ(length, interpolableList.length()); for (size_t i = 0; i < length && i < underlyingLength; i++) underlyingInterpolableList.getMutable(i)->scaleAndAdd( underlyingFraction, *interpolableList.get(i)); if (length <= underlyingLength) return; std::unique_ptr<InterpolableList> extendedInterpolableList = InterpolableList::create(length); for (size_t i = 0; i < length; i++) { if (i < underlyingLength) extendedInterpolableList->set( i, std::move(underlyingInterpolableList.getMutable(i))); else extendedInterpolableList->set(i, interpolableList.get(i)->clone()); } underlyingValueOwner.mutableValue().interpolableValue = std::move(extendedInterpolableList); // const_cast to take a ref. underlyingValueOwner.mutableValue().nonInterpolableValue = const_cast<NonInterpolableValue*>(value.nonInterpolableValue.get()); }
void CSSMotionRotationInterpolationType::composite(UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value) const { const MotionRotationType& underlyingType = toCSSMotionRotationNonInterpolableValue(*underlyingValueOwner.value().nonInterpolableValue).rotationType(); const MotionRotationType& rotationType = toCSSMotionRotationNonInterpolableValue(*value.nonInterpolableValue).rotationType(); if (underlyingType == rotationType) underlyingValueOwner.mutableValue().interpolableValue->scaleAndAdd(underlyingFraction, *value.interpolableValue); else underlyingValueOwner.set(*this, value); }
void CSSClipInterpolationType::composite(UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { const ClipAutos& underlyingAutos = toCSSClipNonInterpolableValue(*underlyingValueOwner.value().nonInterpolableValue).clipAutos(); const ClipAutos& autos = toCSSClipNonInterpolableValue(*value.nonInterpolableValue).clipAutos(); if (underlyingAutos == autos) underlyingValueOwner.mutableValue().interpolableValue->scaleAndAdd(underlyingFraction, *value.interpolableValue); else underlyingValueOwner.set(*this, value); }
void CSSBasicShapeInterpolationType::composite(UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { if (!BasicShapeInterpolationFunctions::shapesAreCompatible(*underlyingValueOwner.value().nonInterpolableValue, *value.nonInterpolableValue)) { underlyingValueOwner.set(*this, value); return; } underlyingValueOwner.mutableValue().interpolableValue->scaleAndAdd(underlyingFraction, *value.interpolableValue); }
void CSSImageSliceInterpolationType::composite(UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { const SliceTypes& underlyingTypes = toCSSImageSliceNonInterpolableValue(*underlyingValueOwner.value().nonInterpolableValue).types(); const SliceTypes& types = toCSSImageSliceNonInterpolableValue(*value.nonInterpolableValue).types(); if (underlyingTypes == types) underlyingValueOwner.mutableValue().interpolableValue->scaleAndAdd(underlyingFraction, *value.interpolableValue); else underlyingValueOwner.set(*this, value); }
void ListInterpolationFunctions::composite(UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationType& type, const InterpolationValue& value, NonInterpolableValuesAreCompatibleCallback nonInterpolableValuesAreCompatible, CompositeItemCallback compositeItem) { size_t underlyingLength = toInterpolableList(*underlyingValueOwner.value().interpolableValue).length(); if (underlyingLength == 0) { ASSERT(!underlyingValueOwner.value().nonInterpolableValue); underlyingValueOwner.set(type, value); return; } const InterpolableList& interpolableList = toInterpolableList(*value.interpolableValue); size_t valueLength = interpolableList.length(); if (valueLength == 0) { ASSERT(!value.nonInterpolableValue); underlyingValueOwner.mutableValue().interpolableValue->scale(underlyingFraction); return; } const NonInterpolableList& nonInterpolableList = toNonInterpolableList(*value.nonInterpolableValue); size_t newLength = lowestCommonMultiple(underlyingLength, valueLength); if (!nonInterpolableListsAreCompatible(toNonInterpolableList(*underlyingValueOwner.value().nonInterpolableValue), nonInterpolableList, newLength, nonInterpolableValuesAreCompatible)) { underlyingValueOwner.set(type, value); return; } InterpolationValue& underlyingValue = underlyingValueOwner.mutableValue(); if (underlyingLength < newLength) repeatToLength(underlyingValue, newLength); InterpolableList& underlyingInterpolableList = toInterpolableList(*underlyingValue.interpolableValue); NonInterpolableList& underlyingNonInterpolableList = toNonInterpolableList(*underlyingValue.nonInterpolableValue); for (size_t i = 0; i < newLength; i++) { compositeItem( underlyingInterpolableList.getMutable(i), underlyingNonInterpolableList.getMutable(i), underlyingFraction, *interpolableList.get(i % valueLength), nonInterpolableList.get(i % valueLength)); } }
void SVGNumberListInterpolationType::composite( UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { const InterpolableList& list = toInterpolableList(*value.interpolableValue); if (toInterpolableList(*underlyingValueOwner.value().interpolableValue) .length() <= list.length()) padWithZeroes(underlyingValueOwner.mutableValue().interpolableValue, list.length()); InterpolableList& underlyingList = toInterpolableList( *underlyingValueOwner.mutableValue().interpolableValue); DCHECK_GE(underlyingList.length(), list.length()); size_t i = 0; for (; i < list.length(); i++) underlyingList.getMutable(i)->scaleAndAdd(underlyingFraction, *list.get(i)); for (; i < underlyingList.length(); i++) underlyingList.getMutable(i)->scale(underlyingFraction); }
void CSSRotateInterpolationType::composite( UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { CSSRotateNonInterpolableValue& underlyingNonInterpolableValue = toCSSRotateNonInterpolableValue( *underlyingValueOwner.value().nonInterpolableValue); const CSSRotateNonInterpolableValue& nonInterpolableValue = toCSSRotateNonInterpolableValue(*value.nonInterpolableValue); double progress = toInterpolableNumber(*value.interpolableValue).value(); underlyingValueOwner.mutableValue().nonInterpolableValue = underlyingNonInterpolableValue.composite(nonInterpolableValue, progress); }
void CSSScaleInterpolationType::composite( UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { const CSSScaleNonInterpolableValue& metadata = toCSSScaleNonInterpolableValue(*value.nonInterpolableValue); DCHECK(metadata.isStartAdditive() || metadata.isEndAdditive()); InterpolableList& underlyingList = toInterpolableList( *underlyingValueOwner.mutableValue().interpolableValue); for (size_t i = 0; i < 3; i++) { InterpolableNumber& underlying = toInterpolableNumber(*underlyingList.getMutable(i)); double start = metadata.start().array[i] * (metadata.isStartAdditive() ? underlying.value() : 1); double end = metadata.end().array[i] * (metadata.isEndAdditive() ? underlying.value() : 1); underlying.set(blend(start, end, interpolationFraction)); } }
void CSSBorderImageLengthBoxInterpolationType::composite( UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const { const SideNumbers& underlyingSideNumbers = toCSSBorderImageLengthBoxNonInterpolableValue( *underlyingValueOwner.value().nonInterpolableValue) .sideNumbers(); const auto& nonInterpolableValue = toCSSBorderImageLengthBoxNonInterpolableValue( *value.nonInterpolableValue); const SideNumbers& sideNumbers = nonInterpolableValue.sideNumbers(); if (underlyingSideNumbers != sideNumbers) { underlyingValueOwner.set(*this, value); return; } InterpolationValue& underlyingValue = underlyingValueOwner.mutableValue(); InterpolableList& underlyingList = toInterpolableList(*underlyingValue.interpolableValue); Vector<RefPtr<NonInterpolableValue>>& underlyingSideNonInterpolableValues = toCSSBorderImageLengthBoxNonInterpolableValue( *underlyingValue.nonInterpolableValue) .sideNonInterpolableValues(); const InterpolableList& list = toInterpolableList(*value.interpolableValue); const Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues = nonInterpolableValue.sideNonInterpolableValues(); for (size_t i = 0; i < SideIndexCount; i++) { if (sideNumbers.isNumber[i]) underlyingList.getMutable(i)->scaleAndAdd(underlyingFraction, *list.get(i)); else LengthInterpolationFunctions::composite( underlyingList.getMutable(i), underlyingSideNonInterpolableValues[i], underlyingFraction, *list.get(i), sideNonInterpolableValues[i].get()); } }