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