PassRefPtr<AnimatableValue> AnimatableFilterOperations::interpolateTo(const AnimatableValue* value, double fraction) const
{
    if (usesDefaultInterpolationWith(value))
        return defaultInterpolateTo(this, value, fraction);

    const AnimatableFilterOperations* target = toAnimatableFilterOperations(value);
    FilterOperations result;
    size_t fromSize = operations().size();
    size_t toSize = target->operations().size();
    size_t size = std::max(fromSize, toSize);
    for (size_t i = 0; i < size; i++) {
#if ENABLE(OILPAN)
        FilterOperation* from = (i < fromSize) ? m_operationWrapper->operations().operations()[i].get() : 0;
        FilterOperation* to = (i < toSize) ? target->m_operationWrapper->operations().operations()[i].get() : 0;
#else
        FilterOperation* from = (i < fromSize) ? m_operations.operations()[i].get() : 0;
        FilterOperation* to = (i < toSize) ? target->m_operations.operations()[i].get() : 0;
#endif
        RefPtrWillBeRawPtr<FilterOperation> blendedOp = FilterOperation::blend(from, to, fraction);
        if (blendedOp)
            result.operations().append(blendedOp);
        else
            ASSERT_NOT_REACHED();
    }
    return AnimatableFilterOperations::create(result);
}
PassRefPtr<AnimatableValue> AnimatableStrokeDasharrayList::interpolateTo(const AnimatableValue* value, double fraction) const
{
    if (usesDefaultInterpolationWith(value))
        return defaultInterpolateTo(this, value, fraction);

    Vector<RefPtr<AnimatableValue>> from = m_values;
    Vector<RefPtr<AnimatableValue>> to = toAnimatableStrokeDasharrayList(value)->m_values;

    // The spec states that if the sum of all values is zero, this should be
    // treated like a value of 'none', which means that a solid line is drawn.
    // Since we animate to and from values of zero, treat a value of 'none' the
    // same. If both the two and from values are 'none', we return 'none'
    // rather than '0 0'.
    if (from.isEmpty() && to.isEmpty())
        return takeConstRef(this);
    if (from.isEmpty() || to.isEmpty()) {
        DEFINE_STATIC_REF(AnimatableLength, zeroPixels, (AnimatableLength::create(Length(Fixed), 1)));
        if (from.isEmpty()) {
            from.append(zeroPixels);
            from.append(zeroPixels);
        }
        if (to.isEmpty()) {
            to.append(zeroPixels);
            to.append(zeroPixels);
        }
    }

    Vector<RefPtr<AnimatableValue>> interpolatedValues;
    bool success = interpolateLists(from, to, fraction, interpolatedValues);
    ASSERT_UNUSED(success, success);
    return adoptRef(new AnimatableStrokeDasharrayList(interpolatedValues));
}
PassRefPtr<AnimatableValue> AnimatableLengthBoxAndBool::interpolateTo(const AnimatableValue* value, double fraction) const
{
    const AnimatableLengthBoxAndBool* lengthBoxAndBool = toAnimatableLengthBoxAndBool(value);
    if (usesDefaultInterpolationWith(lengthBoxAndBool))
        return defaultInterpolateTo(this, value, fraction);
    return AnimatableLengthBoxAndBool::create(
        AnimatableValue::interpolate(box(), lengthBoxAndBool->box(), fraction),
        flag());
}
PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableShapeValue::interpolateTo(const AnimatableValue* value, double fraction) const
{
    if (usesDefaultInterpolationWith(value))
        return defaultInterpolateTo(this, value, fraction);

    const AnimatableShapeValue* shapeValue = toAnimatableShapeValue(value);
    const BasicShape* fromShape = this->m_shape->shape();
    const BasicShape* toShape = shapeValue->m_shape->shape();
    return AnimatableShapeValue::create(ShapeValue::createShapeValue(toShape->blend(fromShape, fraction), shapeValue->m_shape->cssBox()).get());
}
PassRefPtr<AnimatableValue> AnimatableImage::interpolateTo(const AnimatableValue* value, double fraction) const
{
    if (fraction <= 0 || fraction >= 1 || usesDefaultInterpolationWith(value))
        return defaultInterpolateTo(this, value, fraction);

    CSSValue* fromValue = toCSSValue();
    CSSValue* toValue = toAnimatableImage(value)->toCSSValue();

    return create(CSSCrossfadeValue::create(fromValue, toValue, CSSPrimitiveValue::create(fraction, CSSPrimitiveValue::UnitType::Number)));
}
PassRefPtr<AnimatableValue> AnimatableSVGPaint::interpolateTo(const AnimatableValue* value, double fraction) const
{
    if (usesDefaultInterpolationWith(value))
        return defaultInterpolateTo(this, value, fraction);

    const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
    RefPtr<AnimatableColor> color = toAnimatableColor(AnimatableValue::interpolate(m_color.get(), svgPaint->m_color.get(), fraction).get());
    if (fraction < 0.5)
        return create(paintType(), visitedLinkPaintType(), color, uri(), visitedLinkURI());
    return create(svgPaint->paintType(), svgPaint->visitedLinkPaintType(), color, svgPaint->uri(), svgPaint->visitedLinkURI());
}
PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableImage::interpolateTo(const AnimatableValue* value, double fraction) const
{
    if (fraction <= 0 || fraction >= 1 || usesDefaultInterpolationWith(value))
        return defaultInterpolateTo(this, value, fraction);

    CSSValue* fromValue = toCSSValue();
    CSSValue* toValue = toAnimatableImage(value)->toCSSValue();

    RefPtrWillBeRawPtr<CSSCrossfadeValue> crossfadeValue = CSSCrossfadeValue::create(fromValue, toValue);
    crossfadeValue->setPercentage(CSSPrimitiveValue::create(fraction, CSSPrimitiveValue::CSS_NUMBER));
    return create(crossfadeValue);
}
PassRefPtr<AnimatableValue> AnimatablePath::interpolateTo(const AnimatableValue* value, double fraction) const
{
    if (usesDefaultInterpolationWith(value))
        return defaultInterpolateTo(this, value, fraction);

    std::unique_ptr<SVGPathByteStream> byteStream = SVGPathByteStream::create();
    SVGPathByteStreamBuilder builder(*byteStream);

    SVGPathByteStreamSource fromSource(path()->byteStream());
    SVGPathByteStreamSource toSource(toAnimatablePath(value)->path()->byteStream());

    SVGPathBlender blender(&fromSource, &toSource, &builder);
    bool ok = blender.blendAnimatedPath(fraction);
    ASSERT_UNUSED(ok, ok);
    return AnimatablePath::create(StylePath::create(std::move(byteStream)));
}