bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSPrimitiveValue& primitiveValue)
{
    // FIXME: consider other types.
    if (primitiveValue.isNumber() || primitiveValue.isPercentage() || primitiveValue.isAngle() || primitiveValue.isRGBColor() || primitiveValue.isURI())
        return false;

    if (primitiveValue.isLength())
        return primitiveValue.isFontRelativeLength() || primitiveValue.isViewportPercentageLength();

    if (primitiveValue.isCalculated()) {
        CSSLengthArray lengthArray(CSSPrimitiveValue::LengthUnitTypeCount);
        primitiveValue.accumulateLengthArray(lengthArray);
        return lengthArray[CSSPrimitiveValue::UnitTypeFontSize] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeFontXSize] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeRootFontSize] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeZeroCharacterWidth] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportWidth] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportHeight] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportMin] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportMax] != 0;
    }

    CSSValueID id = primitiveValue.getValueID();
    bool isColor = ((id >= CSSValueAqua && id <= CSSValueTransparent)
        || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)
        || id == CSSValueGrey);
    return (id != CSSValueNone) && !isColor;
}
PassOwnPtr<InterpolableValue> LengthStyleInterpolation::lengthToInterpolableValue(CSSValue* value)
{
    OwnPtr<InterpolableList> result = InterpolableList::create(CSSPrimitiveValue::LengthUnitTypeCount);
    CSSPrimitiveValue* primitive = toCSSPrimitiveValue(value);

    CSSLengthArray array;
    for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++)
        array.append(0);
    primitive->accumulateLengthArray(array);

    for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++)
        result->set(i, InterpolableNumber::create(array.at(i)));

    return result.release();
}
static void verifyCSSCalc(String text, double value, bool valid, unsigned fontSize, unsigned viewportWidth, unsigned viewportHeight)
{
    CSSLengthArray lengthArray;
    initLengthArray(lengthArray);
    RawPtr<CSSValue> cssValue = CSSParser::parseSingleValue(CSSPropertyLeft, text);
    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(cssValue.get());
    if (primitiveValue)
        primitiveValue->accumulateLengthArray(lengthArray);
    else
        ASSERT_EQ(valid, false);
    float length = lengthArray.at(CSSPrimitiveValue::UnitTypePixels);
    length += lengthArray.at(CSSPrimitiveValue::UnitTypeFontSize) * fontSize;
    length += lengthArray.at(CSSPrimitiveValue::UnitTypeViewportWidth) * viewportWidth / 100.0;
    length += lengthArray.at(CSSPrimitiveValue::UnitTypeViewportHeight) * viewportHeight / 100.0;
    ASSERT_EQ(value, length);
}
bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSPrimitiveValue& primitiveValue)
{
    // FIXME: consider other types.
    if (primitiveValue.isNumber() || primitiveValue.isPercentage() || primitiveValue.isAngle() || primitiveValue.isRGBColor() || primitiveValue.isURI())
        return false;

    if (primitiveValue.isLength())
        return primitiveValue.isFontRelativeLength() || primitiveValue.isViewportPercentageLength();

    if (primitiveValue.isCalculated()) {
        CSSLengthArray lengthArray(CSSPrimitiveValue::LengthUnitTypeCount);
        primitiveValue.accumulateLengthArray(lengthArray);
        return lengthArray[CSSPrimitiveValue::UnitTypeFontSize] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeFontXSize] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeRootFontSize] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeZeroCharacterWidth] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportWidth] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportHeight] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportMin] != 0
            || lengthArray[CSSPrimitiveValue::UnitTypeViewportMax] != 0;
    }

    if (Pair* pair = primitiveValue.getPairValue()) {
        return interpolationRequiresStyleResolve(*pair->first())
            || interpolationRequiresStyleResolve(*pair->second());
    }

    if (Rect* rect = primitiveValue.getRectValue()) {
        return interpolationRequiresStyleResolve(*rect->top())
            || interpolationRequiresStyleResolve(*rect->right())
            || interpolationRequiresStyleResolve(*rect->bottom())
            || interpolationRequiresStyleResolve(*rect->left());
    }

    if (Quad* quad = primitiveValue.getQuadValue()) {
        return interpolationRequiresStyleResolve(*quad->top())
            || interpolationRequiresStyleResolve(*quad->right())
            || interpolationRequiresStyleResolve(*quad->bottom())
            || interpolationRequiresStyleResolve(*quad->left());
    }

    if (primitiveValue.isShape())
        return interpolationRequiresStyleResolve(*primitiveValue.getShapeValue());

    return (primitiveValue.getValueID() != CSSValueNone);
}