PairwiseInterpolationValue ListInterpolationFunctions::mergeSingleConversions(InterpolationValue& start, InterpolationValue& end, MergeSingleItemConversionsCallback mergeSingleItemConversions) { size_t startLength = toInterpolableList(*start.interpolableValue).length(); size_t endLength = toInterpolableList(*end.interpolableValue).length(); if (startLength == 0 && endLength == 0) { return PairwiseInterpolationValue( start.interpolableValue.release(), end.interpolableValue.release(), nullptr); } if (startLength == 0) { OwnPtr<InterpolableValue> startInterpolableValue = end.interpolableValue->cloneAndZero(); return PairwiseInterpolationValue( startInterpolableValue.release(), end.interpolableValue.release(), end.nonInterpolableValue.release()); } if (endLength == 0) { OwnPtr<InterpolableValue> endInterpolableValue = start.interpolableValue->cloneAndZero(); return PairwiseInterpolationValue( start.interpolableValue.release(), endInterpolableValue.release(), start.nonInterpolableValue.release()); } size_t finalLength = lowestCommonMultiple(startLength, endLength); OwnPtr<InterpolableList> resultStartInterpolableList = InterpolableList::create(finalLength); OwnPtr<InterpolableList> resultEndInterpolableList = InterpolableList::create(finalLength); Vector<RefPtr<NonInterpolableValue>> resultNonInterpolableValues(finalLength); InterpolableList& startInterpolableList = toInterpolableList(*start.interpolableValue); InterpolableList& endInterpolableList = toInterpolableList(*end.interpolableValue); NonInterpolableList& startNonInterpolableList = toNonInterpolableList(*start.nonInterpolableValue); NonInterpolableList& endNonInterpolableList = toNonInterpolableList(*end.nonInterpolableValue); for (size_t i = 0; i < finalLength; i++) { InterpolationValue start(startInterpolableList.get(i % startLength)->clone(), startNonInterpolableList.get(i % startLength)); InterpolationValue end(endInterpolableList.get(i % endLength)->clone(), endNonInterpolableList.get(i % endLength)); PairwiseInterpolationValue result = mergeSingleItemConversions(start, end); if (!result) return nullptr; resultStartInterpolableList->set(i, result.startInterpolableValue.release()); resultEndInterpolableList->set(i, result.endInterpolableValue.release()); resultNonInterpolableValues[i] = result.nonInterpolableValue.release(); } return PairwiseInterpolationValue( resultStartInterpolableList.release(), resultEndInterpolableList.release(), NonInterpolableList::create(resultNonInterpolableValues)); }
PairwiseInterpolationValue CSSFilterListInterpolationType::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) const { NonInterpolableList& startNonInterpolableList = toNonInterpolableList(*start.nonInterpolableValue); NonInterpolableList& endNonInterpolableList = toNonInterpolableList(*end.nonInterpolableValue); size_t startLength = startNonInterpolableList.length(); size_t endLength = endNonInterpolableList.length(); for (size_t i = 0; i < startLength && i < endLength; i++) { if (!FilterInterpolationFunctions::filtersAreCompatible( *startNonInterpolableList.get(i), *endNonInterpolableList.get(i))) return nullptr; } if (startLength == endLength) return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), start.nonInterpolableValue.release()); // Extend the shorter InterpolableList with neutral values that are compatible // with corresponding filters in the longer list. InterpolationValue& shorter = startLength < endLength ? start : end; InterpolationValue& longer = startLength < endLength ? end : start; size_t shorterLength = toNonInterpolableList(*shorter.nonInterpolableValue).length(); size_t longerLength = toNonInterpolableList(*longer.nonInterpolableValue).length(); InterpolableList& shorterInterpolableList = toInterpolableList(*shorter.interpolableValue); const NonInterpolableList& longerNonInterpolableList = toNonInterpolableList(*longer.nonInterpolableValue); std::unique_ptr<InterpolableList> extendedInterpolableList = InterpolableList::create(longerLength); for (size_t i = 0; i < longerLength; i++) { if (i < shorterLength) extendedInterpolableList->set( i, std::move(shorterInterpolableList.getMutable(i))); else extendedInterpolableList->set( i, FilterInterpolationFunctions::createNoneValue( *longerNonInterpolableList.get(i))); } shorter.interpolableValue = std::move(extendedInterpolableList); return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), longer.nonInterpolableValue.release()); }
PairwiseInterpolationValue SVGTransformListInterpolationType::mergeSingleConversions(InterpolationValue& start, InterpolationValue& end) const { if (!transformTypesMatch(start, end)) return nullptr; return PairwiseInterpolationValue(start.interpolableValue.release(), end.interpolableValue.release(), end.nonInterpolableValue.release()); }
PairwiseInterpolationValue CSSClipInterpolationType::mergeSingleConversions(InterpolationValue&& start, InterpolationValue&& end) const { const ClipAutos& startAutos = toCSSClipNonInterpolableValue(*start.nonInterpolableValue).clipAutos(); const ClipAutos& endAutos = toCSSClipNonInterpolableValue(*end.nonInterpolableValue).clipAutos(); if (startAutos != endAutos) return nullptr; return PairwiseInterpolationValue(start.interpolableValue.release(), end.interpolableValue.release(), start.nonInterpolableValue.release()); }
PairwiseInterpolationValue LengthInterpolationFunctions::mergeSingles( InterpolationValue&& start, InterpolationValue&& end) { return PairwiseInterpolationValue( std::move(start.interpolableValue), std::move(end.interpolableValue), CSSLengthNonInterpolableValue::merge(start.nonInterpolableValue.get(), end.nonInterpolableValue.get())); }
PairwiseInterpolationValue CSSRotateInterpolationType::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) const { return PairwiseInterpolationValue( InterpolableNumber::create(0), InterpolableNumber::create(1), CSSRotateNonInterpolableValue::create( toCSSRotateNonInterpolableValue(*start.nonInterpolableValue), toCSSRotateNonInterpolableValue(*end.nonInterpolableValue))); }
PairwiseInterpolationValue CSSScaleInterpolationType::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) const { return PairwiseInterpolationValue( std::move(start.interpolableValue), std::move(end.interpolableValue), CSSScaleNonInterpolableValue::merge( toCSSScaleNonInterpolableValue(*start.nonInterpolableValue), toCSSScaleNonInterpolableValue(*end.nonInterpolableValue))); }
PairwiseInterpolationValue SVGTransformListInterpolationType::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) const { if (getTransformTypes(start) != getTransformTypes(end)) return nullptr; return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), end.nonInterpolableValue.release()); }
PairwiseInterpolationValue CSSImageSliceInterpolationType::maybeMergeSingles(InterpolationValue&& start, InterpolationValue&& end) const { const SliceTypes& startSliceTypes = toCSSImageSliceNonInterpolableValue(*start.nonInterpolableValue).types(); const SliceTypes& endSliceTypes = toCSSImageSliceNonInterpolableValue(*end.nonInterpolableValue).types(); if (startSliceTypes != endSliceTypes) return nullptr; return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), start.nonInterpolableValue.release()); }
PairwiseInterpolationValue SizeInterpolationFunctions::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) { if (!nonInterpolableValuesAreCompatible(start.nonInterpolableValue.get(), end.nonInterpolableValue.get())) return nullptr; return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), start.nonInterpolableValue.release()); }
PairwiseInterpolationValue CSSBasicShapeInterpolationType::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) const { if (!BasicShapeInterpolationFunctions::shapesAreCompatible( *start.nonInterpolableValue, *end.nonInterpolableValue)) return nullptr; return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), start.nonInterpolableValue.release()); }
PairwiseInterpolationValue CSSMotionRotationInterpolationType::mergeSingleConversions(InterpolationValue& start, InterpolationValue& end) const { const MotionRotationType& startType = toCSSMotionRotationNonInterpolableValue(*start.nonInterpolableValue).rotationType(); const MotionRotationType& endType = toCSSMotionRotationNonInterpolableValue(*end.nonInterpolableValue).rotationType(); if (startType != endType) return nullptr; return PairwiseInterpolationValue( start.interpolableValue.release(), end.interpolableValue.release(), start.nonInterpolableValue.release()); }
PairwiseInterpolationValue CSSTransformInterpolationType::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) const { return PairwiseInterpolationValue( InterpolableNumber::create(0), InterpolableNumber::create(1), CSSTransformNonInterpolableValue::create( std::move( toCSSTransformNonInterpolableValue(*start.nonInterpolableValue)), std::move( toCSSTransformNonInterpolableValue(*end.nonInterpolableValue)))); }
PairwiseInterpolationValue CSSImageInterpolationType::staticMergeSingleConversions( InterpolationValue&& start, InterpolationValue&& end) { if (!toCSSImageNonInterpolableValue(*start.nonInterpolableValue).isSingle() || !toCSSImageNonInterpolableValue(*end.nonInterpolableValue).isSingle()) { return nullptr; } return PairwiseInterpolationValue( InterpolableNumber::create(0), InterpolableNumber::create(1), CSSImageNonInterpolableValue::merge(start.nonInterpolableValue, end.nonInterpolableValue)); }
PairwiseInterpolationValue PathInterpolationFunctions::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) { const Vector<SVGPathSegType>& startTypes = toSVGPathNonInterpolableValue(*start.nonInterpolableValue).pathSegTypes(); const Vector<SVGPathSegType>& endTypes = toSVGPathNonInterpolableValue(*end.nonInterpolableValue).pathSegTypes(); if (!pathSegTypesMatch(startTypes, endTypes)) return nullptr; return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), end.nonInterpolableValue.release()); }
PairwiseInterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeMergeSingles( InterpolationValue&& start, InterpolationValue&& end) const { const SideNumbers& startSideNumbers = toCSSBorderImageLengthBoxNonInterpolableValue(*start.nonInterpolableValue) .sideNumbers(); const SideNumbers& endSideNumbers = toCSSBorderImageLengthBoxNonInterpolableValue(*end.nonInterpolableValue) .sideNumbers(); if (startSideNumbers != endSideNumbers) return nullptr; return PairwiseInterpolationValue(std::move(start.interpolableValue), std::move(end.interpolableValue), start.nonInterpolableValue.release()); }