1d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// found in the LICENSE file. 4d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 5d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "config.h" 6c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/animation/LengthStyleInterpolation.h" 7d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 8d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/css/CSSCalculationValue.h" 9d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/css/resolver/StyleBuilder.h" 10d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 11c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 12d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 13d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)bool LengthStyleInterpolation::canCreateFrom(const CSSValue& value) 14d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 15d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (value.isPrimitiveValue()) { 16c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) const CSSPrimitiveValue& primitiveValue = blink::toCSSPrimitiveValue(value); 17d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (primitiveValue.cssCalcValue()) 18d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return true; 19d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 20d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) CSSPrimitiveValue::LengthUnitType type; 21d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Only returns true if the type is a primitive length unit. 22d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return CSSPrimitiveValue::unitTypeToLengthUnitType(primitiveValue.primitiveType(), type); 23d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 24d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return value.isCalcValue(); 25d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 26d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 27d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)PassOwnPtrWillBeRawPtr<InterpolableValue> LengthStyleInterpolation::lengthToInterpolableValue(CSSValue* value) 28d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 29d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(CSSPrimitiveValue::LengthUnitTypeCount); 30d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) CSSPrimitiveValue* primitive = toCSSPrimitiveValue(value); 31d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 32d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) CSSLengthArray array; 33d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) 34d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) array.append(0); 35d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) primitive->accumulateLengthArray(array); 36d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 37d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) 38d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) result->set(i, InterpolableNumber::create(array.at(i))); 39d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 40d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return result.release(); 41d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 42d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 43d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)namespace { 44d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 45d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType) 46d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 47d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return static_cast<CSSPrimitiveValue::UnitType>(CSSPrimitiveValue::lengthUnitTypeToUnitType(static_cast<CSSPrimitiveValue::LengthUnitType>(lengthUnitType))); 48d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 49d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 50d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> constructCalcExpression(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> previous, InterpolableList* list, size_t position) 51d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 52d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) while (position != CSSPrimitiveValue::LengthUnitTypeCount) { 53d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const InterpolableNumber *subValue = toInterpolableNumber(list->get(position)); 54d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (subValue->value()) { 55d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<CSSCalcExpressionNode> next; 56d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (previous) 57d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) next = CSSCalcValue::createExpressionNode(previous, CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(subValue->value(), toUnitType(position))), CalcAdd); 58d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else 59d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) next = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(subValue->value(), toUnitType(position))); 60d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return constructCalcExpression(next, list, position + 1); 61d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 62d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) position++; 63d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 64d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return previous; 65d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 67d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 68d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 69d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)PassRefPtrWillBeRawPtr<CSSValue> LengthStyleInterpolation::interpolableValueToLength(InterpolableValue* value, ValueRange range) 70d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 71d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) InterpolableList* listValue = toInterpolableList(value); 72d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned unitCount = 0; 73d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { 74d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const InterpolableNumber* subValue = toInterpolableNumber(listValue->get(i)); 75d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (subValue->value()) { 76d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unitCount++; 77d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 78d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 79d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 80d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) switch (unitCount) { 81d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) case 0: 82d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX); 83d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) case 1: 84d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { 85d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const InterpolableNumber* subValue = toInterpolableNumber(listValue->get(i)); 86d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) double value = subValue->value(); 87d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (value) { 88d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (range == ValueRangeNonNegative && value < 0) 89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) value = 0; 90d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return CSSPrimitiveValue::create(value, toUnitType(i)); 91d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 92d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ASSERT_NOT_REACHED(); 94d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) default: 95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return CSSPrimitiveValue::create(CSSCalcValue::create(constructCalcExpression(nullptr, listValue, 0), range)); 96d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 97d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 98d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 99d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void LengthStyleInterpolation::apply(StyleResolverState& state) const 100d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 101d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) StyleBuilder::applyProperty(m_id, state, interpolableValueToLength(m_cachedValue.get(), m_range).get()); 102d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 103d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void LengthStyleInterpolation::trace(Visitor* visitor) 105d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 106d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) StyleInterpolation::trace(visitor); 107d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 108d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 109d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 110