PassRefPtr<CSSValue> LengthStyleInterpolation::interpolableValueToLength(InterpolableValue* value, ValueRange range) { InterpolableList* listValue = toInterpolableList(value); unsigned unitCount = 0; for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { const InterpolableNumber* subValue = toInterpolableNumber(listValue->get(i)); if (subValue->value()) { unitCount++; } } switch (unitCount) { case 0: return CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX); case 1: for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { const InterpolableNumber* subValue = toInterpolableNumber(listValue->get(i)); double value = subValue->value(); if (value) { if (range == ValueRangeNonNegative && value < 0) value = 0; return CSSPrimitiveValue::create(value, toUnitType(i)); } } ASSERT_NOT_REACHED(); default: return CSSPrimitiveValue::create(CSSCalcValue::create(constructCalcExpression(nullptr, listValue, 0), range)); } }
static PassRefPtrWillBeRawPtr<CSSValue> createCSSValue(const InterpolableList& values, bool hasPercentage, ValueRange range) { RefPtrWillBeRawPtr<CSSPrimitiveValue> result; size_t firstUnitIndex = CSSPrimitiveValue::LengthUnitTypeCount; size_t unitTypeCount = 0; for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { if ((hasPercentage && i == CSSPrimitiveValue::UnitTypePercentage) || toInterpolableNumber(values.get(i))->value()) { unitTypeCount++; if (unitTypeCount == 1) firstUnitIndex = i; } } switch (unitTypeCount) { case 0: return CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::Pixels); case 1: { double value = clampToRange(toInterpolableNumber(values.get(firstUnitIndex))->value(), range); return CSSPrimitiveValue::create(value, toUnitType(firstUnitIndex)); } default: return CSSPrimitiveValue::create(CSSCalcValue::create(createCalcExpression(values, hasPercentage), range)); } }
static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createCalcExpression(const InterpolableList& values, bool hasPercentage) { RefPtrWillBeRawPtr<CSSCalcExpressionNode> result = nullptr; for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { double value = toInterpolableNumber(values.get(i))->value(); if (value || (i == CSSPrimitiveValue::UnitTypePercentage && hasPercentage)) { RefPtrWillBeRawPtr<CSSCalcExpressionNode> node = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(value, toUnitType(i))); result = result ? CSSCalcValue::createExpressionNode(result.release(), node.release(), CalcAdd) : node.release(); } } ASSERT(result); return result.release(); }