bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValue& value)
{
    // FIXME: should not require resolving styles for inherit/initial/unset.
    if (value.isCSSWideKeyword())
        return true;
    if (value.isBasicShapeCircleValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapeCircleValue(value));
    if (value.isBasicShapeEllipseValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapeEllipseValue(value));
    if (value.isBasicShapePolygonValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapePolygonValue(value));
    if (value.isBasicShapeInsetValue())
        return interpolationRequiresStyleResolve(toCSSBasicShapeInsetValue(value));
    if (value.isPrimitiveValue())
        return interpolationRequiresStyleResolve(toCSSPrimitiveValue(value));
    if (value.isQuadValue())
        return interpolationRequiresStyleResolve(toCSSQuadValue(value));
    if (value.isValueList())
        return interpolationRequiresStyleResolve(toCSSValueList(value));
    if (value.isValuePair())
        return interpolationRequiresStyleResolve(toCSSValuePair(value));
    if (value.isImageValue())
        return interpolationRequiresStyleResolve(toCSSImageValue(value));
    if (value.isShadowValue())
        return interpolationRequiresStyleResolve(toCSSShadowValue(value));
    if (value.isSVGDocumentValue())
        return interpolationRequiresStyleResolve(toCSSSVGDocumentValue(value));
    // FIXME: consider other custom types.
    return true;
}
PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const CSSValue& basicShapeValue)
{
    RefPtr<BasicShape> basicShape;

    if (basicShapeValue.isBasicShapeCircleValue()) {
        const CSSBasicShapeCircleValue& circleValue = toCSSBasicShapeCircleValue(basicShapeValue);
        RefPtr<BasicShapeCircle> circle = BasicShapeCircle::create();

        circle->setCenterX(convertToCenterCoordinate(state, circleValue.centerX()));
        circle->setCenterY(convertToCenterCoordinate(state, circleValue.centerY()));
        circle->setRadius(cssValueToBasicShapeRadius(state, circleValue.radius()));

        basicShape = circle.release();
    } else if (basicShapeValue.isBasicShapeEllipseValue()) {
        const CSSBasicShapeEllipseValue& ellipseValue = toCSSBasicShapeEllipseValue(basicShapeValue);
        RefPtr<BasicShapeEllipse> ellipse = BasicShapeEllipse::create();

        ellipse->setCenterX(convertToCenterCoordinate(state, ellipseValue.centerX()));
        ellipse->setCenterY(convertToCenterCoordinate(state, ellipseValue.centerY()));
        ellipse->setRadiusX(cssValueToBasicShapeRadius(state, ellipseValue.radiusX()));
        ellipse->setRadiusY(cssValueToBasicShapeRadius(state, ellipseValue.radiusY()));

        basicShape = ellipse.release();
    } else if (basicShapeValue.isBasicShapePolygonValue()) {
        const CSSBasicShapePolygonValue& polygonValue = toCSSBasicShapePolygonValue(basicShapeValue);
        RefPtr<BasicShapePolygon> polygon = BasicShapePolygon::create();

        polygon->setWindRule(polygonValue.getWindRule());
        const HeapVector<Member<CSSPrimitiveValue>>& values = polygonValue.values();
        for (unsigned i = 0; i < values.size(); i += 2)
            polygon->appendPoint(convertToLength(state, values.at(i).get()), convertToLength(state, values.at(i + 1).get()));

        basicShape = polygon.release();
    } else if (basicShapeValue.isBasicShapeInsetValue()) {
        const CSSBasicShapeInsetValue& rectValue = toCSSBasicShapeInsetValue(basicShapeValue);
        RefPtr<BasicShapeInset> rect = BasicShapeInset::create();

        rect->setTop(convertToLength(state, rectValue.top()));
        rect->setRight(convertToLength(state, rectValue.right()));
        rect->setBottom(convertToLength(state, rectValue.bottom()));
        rect->setLeft(convertToLength(state, rectValue.left()));

        rect->setTopLeftRadius(convertToLengthSize(state, rectValue.topLeftRadius()));
        rect->setTopRightRadius(convertToLengthSize(state, rectValue.topRightRadius()));
        rect->setBottomRightRadius(convertToLengthSize(state, rectValue.bottomRightRadius()));
        rect->setBottomLeftRadius(convertToLengthSize(state, rectValue.bottomLeftRadius()));

        basicShape = rect.release();
    } else {
        ASSERT_NOT_REACHED();
    }

    return basicShape.release();
}