OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/animation/LengthStyleInterpolation.h" | 6 #include "core/animation/LengthStyleInterpolation.h" |
7 | 7 |
| 8 #include "core/animation/LengthPropertyFunctions.h" |
8 #include "core/animation/css/CSSAnimatableValueFactory.h" | 9 #include "core/animation/css/CSSAnimatableValueFactory.h" |
9 #include "core/css/CSSCalculationValue.h" | 10 #include "core/css/CSSCalculationValue.h" |
10 #include "core/css/resolver/StyleBuilder.h" | 11 #include "core/css/resolver/StyleBuilder.h" |
11 #include "core/css/resolver/StyleResolverState.h" | 12 #include "core/css/resolver/StyleResolverState.h" |
12 #include "platform/CalculationValue.h" | 13 #include "platform/CalculationValue.h" |
13 | 14 |
14 namespace blink { | 15 namespace blink { |
15 | 16 |
16 namespace { | |
17 | |
18 bool pixelsForKeyword(CSSPropertyID property, CSSValueID valueID, double& result
) | |
19 { | |
20 switch (property) { | |
21 case CSSPropertyBorderBottomWidth: | |
22 case CSSPropertyBorderLeftWidth: | |
23 case CSSPropertyBorderRightWidth: | |
24 case CSSPropertyBorderTopWidth: | |
25 case CSSPropertyWebkitColumnRuleWidth: | |
26 case CSSPropertyOutlineWidth: | |
27 if (valueID == CSSValueThin) { | |
28 result = 1; | |
29 return true; | |
30 } | |
31 if (valueID == CSSValueMedium) { | |
32 result = 3; | |
33 return true; | |
34 } | |
35 if (valueID == CSSValueThick) { | |
36 result = 5; | |
37 return true; | |
38 } | |
39 return false; | |
40 case CSSPropertyLetterSpacing: | |
41 case CSSPropertyWordSpacing: | |
42 if (valueID == CSSValueNormal) { | |
43 result = 0; | |
44 return true; | |
45 } | |
46 return false; | |
47 default: | |
48 return false; | |
49 } | |
50 } | |
51 | |
52 } // namespace | |
53 | |
54 bool LengthStyleInterpolation::canCreateFrom(const CSSValue& value, CSSPropertyI
D property) | 17 bool LengthStyleInterpolation::canCreateFrom(const CSSValue& value, CSSPropertyI
D property) |
55 { | 18 { |
56 if (!value.isPrimitiveValue()) | 19 if (!value.isPrimitiveValue()) |
57 return false; | 20 return false; |
58 | 21 |
59 const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value); | 22 const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value); |
60 if (primitiveValue.isCalculated()) | |
61 return true; | |
62 | |
63 if (primitiveValue.isValueID()) { | |
64 CSSValueID valueID = primitiveValue.getValueID(); | |
65 double pixels; | |
66 return pixelsForKeyword(property, valueID, pixels); | |
67 } | |
68 | |
69 return primitiveValue.isLength() || primitiveValue.isPercentage() || primiti
veValue.isCalculatedPercentageWithLength(); | 23 return primitiveValue.isLength() || primitiveValue.isPercentage() || primiti
veValue.isCalculatedPercentageWithLength(); |
70 } | 24 } |
71 | 25 |
72 PassOwnPtr<InterpolableValue> LengthStyleInterpolation::toInterpolableValue(cons
t CSSValue& value, CSSPropertyID id) | 26 PassOwnPtr<InterpolableValue> LengthStyleInterpolation::toInterpolableValue(cons
t CSSValue& value, CSSPropertyID id) |
73 { | 27 { |
74 ASSERT(canCreateFrom(value, id)); | 28 ASSERT(canCreateFrom(value, id)); |
75 OwnPtr<InterpolableList> listOfValuesAndTypes = InterpolableList::create(2); | 29 OwnPtr<InterpolableList> listOfValuesAndTypes = InterpolableList::create(2); |
76 OwnPtr<InterpolableList> listOfValues = InterpolableList::create(CSSPrimitiv
eValue::LengthUnitTypeCount); | 30 OwnPtr<InterpolableList> listOfValues = InterpolableList::create(CSSPrimitiv
eValue::LengthUnitTypeCount); |
77 OwnPtr<InterpolableList> listOfTypes = InterpolableList::create(CSSPrimitive
Value::LengthUnitTypeCount); | 31 OwnPtr<InterpolableList> listOfTypes = InterpolableList::create(CSSPrimitive
Value::LengthUnitTypeCount); |
78 | 32 |
79 const CSSPrimitiveValue& primitive = toCSSPrimitiveValue(value); | 33 const CSSPrimitiveValue& primitive = toCSSPrimitiveValue(value); |
80 | 34 |
81 CSSLengthArray arrayOfValues; | 35 CSSLengthArray arrayOfValues; |
82 CSSPrimitiveValue::CSSLengthTypeArray arrayOfTypes; | 36 CSSPrimitiveValue::CSSLengthTypeArray arrayOfTypes; |
83 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) | 37 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) |
84 arrayOfValues.append(0); | 38 arrayOfValues.append(0); |
85 | |
86 arrayOfTypes.ensureSize(CSSPrimitiveValue::LengthUnitTypeCount); | 39 arrayOfTypes.ensureSize(CSSPrimitiveValue::LengthUnitTypeCount); |
87 if (primitive.isValueID()) { | 40 primitive.accumulateLengthArray(arrayOfValues, arrayOfTypes); |
88 CSSValueID valueID = primitive.getValueID(); | |
89 double pixels; | |
90 pixelsForKeyword(id, valueID, pixels); | |
91 arrayOfTypes.set(CSSPrimitiveValue::UnitTypePixels); | |
92 arrayOfValues[CSSPrimitiveValue::UnitTypePixels] = pixels; | |
93 } else { | |
94 primitive.accumulateLengthArray(arrayOfValues, arrayOfTypes); | |
95 } | |
96 | 41 |
97 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { | 42 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { |
98 listOfValues->set(i, InterpolableNumber::create(arrayOfValues.at(i))); | 43 listOfValues->set(i, InterpolableNumber::create(arrayOfValues.at(i))); |
99 listOfTypes->set(i, InterpolableNumber::create(arrayOfTypes.get(i))); | 44 listOfTypes->set(i, InterpolableNumber::create(arrayOfTypes.get(i))); |
100 } | 45 } |
101 | 46 |
102 listOfValuesAndTypes->set(0, listOfValues.release()); | 47 listOfValuesAndTypes->set(0, listOfValues.release()); |
103 listOfValuesAndTypes->set(1, listOfTypes.release()); | 48 listOfValuesAndTypes->set(1, listOfTypes.release()); |
104 | 49 |
105 return listOfValuesAndTypes.release(); | 50 return listOfValuesAndTypes.release(); |
106 } | 51 } |
107 | 52 |
108 bool LengthStyleInterpolation::isPixelsOrPercentOnly(const InterpolableValue& va
lue) | 53 namespace { |
| 54 |
| 55 bool isPixelsOrPercentOnly(const InterpolableValue& value) |
109 { | 56 { |
110 const InterpolableList& types = *toInterpolableList(toInterpolableList(value
).get(1)); | 57 const InterpolableList& types = *toInterpolableList(toInterpolableList(value
).get(1)); |
111 bool result = false; | 58 bool result = false; |
112 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { | 59 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { |
113 bool typeIsPresent = toInterpolableNumber(types.get(i))->value(); | 60 bool typeIsPresent = toInterpolableNumber(types.get(i))->value(); |
114 if (i == CSSPrimitiveValue::UnitTypePixels) | 61 if (i == CSSPrimitiveValue::UnitTypePixels) |
115 result |= typeIsPresent; | 62 result |= typeIsPresent; |
116 else if (i == CSSPrimitiveValue::UnitTypePercentage) | 63 else if (i == CSSPrimitiveValue::UnitTypePercentage) |
117 result |= typeIsPresent; | 64 result |= typeIsPresent; |
118 else if (typeIsPresent) | 65 else if (typeIsPresent) |
119 return false; | 66 return false; |
120 } | 67 } |
121 return result; | 68 return result; |
122 } | 69 } |
123 | 70 |
124 LengthStyleInterpolation::LengthSetter LengthStyleInterpolation::lengthSetterFor
Property(CSSPropertyID property) | |
125 { | |
126 switch (property) { | |
127 case CSSPropertyBottom: | |
128 return &ComputedStyle::setBottom; | |
129 case CSSPropertyCx: | |
130 return &ComputedStyle::setCx; | |
131 case CSSPropertyCy: | |
132 return &ComputedStyle::setCy; | |
133 case CSSPropertyFlexBasis: | |
134 return &ComputedStyle::setFlexBasis; | |
135 case CSSPropertyHeight: | |
136 return &ComputedStyle::setHeight; | |
137 case CSSPropertyLeft: | |
138 return &ComputedStyle::setLeft; | |
139 case CSSPropertyLineHeight: | |
140 return &ComputedStyle::setLineHeight; | |
141 case CSSPropertyMarginBottom: | |
142 return &ComputedStyle::setMarginBottom; | |
143 case CSSPropertyMarginLeft: | |
144 return &ComputedStyle::setMarginLeft; | |
145 case CSSPropertyMarginRight: | |
146 return &ComputedStyle::setMarginRight; | |
147 case CSSPropertyMarginTop: | |
148 return &ComputedStyle::setMarginTop; | |
149 case CSSPropertyMaxHeight: | |
150 return &ComputedStyle::setMaxHeight; | |
151 case CSSPropertyMaxWidth: | |
152 return &ComputedStyle::setMaxWidth; | |
153 case CSSPropertyMinHeight: | |
154 return &ComputedStyle::setMinHeight; | |
155 case CSSPropertyMinWidth: | |
156 return &ComputedStyle::setMinWidth; | |
157 case CSSPropertyMotionOffset: | |
158 return &ComputedStyle::setMotionOffset; | |
159 case CSSPropertyPaddingBottom: | |
160 return &ComputedStyle::setPaddingBottom; | |
161 case CSSPropertyPaddingLeft: | |
162 return &ComputedStyle::setPaddingLeft; | |
163 case CSSPropertyPaddingRight: | |
164 return &ComputedStyle::setPaddingRight; | |
165 case CSSPropertyPaddingTop: | |
166 return &ComputedStyle::setPaddingTop; | |
167 case CSSPropertyR: | |
168 return &ComputedStyle::setR; | |
169 case CSSPropertyRx: | |
170 return &ComputedStyle::setRx; | |
171 case CSSPropertyRy: | |
172 return &ComputedStyle::setRy; | |
173 case CSSPropertyRight: | |
174 return &ComputedStyle::setRight; | |
175 case CSSPropertyShapeMargin: | |
176 return &ComputedStyle::setShapeMargin; | |
177 case CSSPropertyStrokeDashoffset: | |
178 return &ComputedStyle::setStrokeDashOffset; | |
179 case CSSPropertyTop: | |
180 return &ComputedStyle::setTop; | |
181 case CSSPropertyWidth: | |
182 return &ComputedStyle::setWidth; | |
183 case CSSPropertyWebkitPerspectiveOriginX: | |
184 return &ComputedStyle::setPerspectiveOriginX; | |
185 case CSSPropertyWebkitPerspectiveOriginY: | |
186 return &ComputedStyle::setPerspectiveOriginY; | |
187 case CSSPropertyWebkitTransformOriginX: | |
188 return &ComputedStyle::setTransformOriginX; | |
189 case CSSPropertyWebkitTransformOriginY: | |
190 return &ComputedStyle::setTransformOriginY; | |
191 case CSSPropertyX: | |
192 return &ComputedStyle::setX; | |
193 case CSSPropertyY: | |
194 return &ComputedStyle::setY; | |
195 // These properties don't have a ComputedStyle setter with the signature voi
d(*)(const Length&). | |
196 case CSSPropertyBaselineShift: | |
197 case CSSPropertyBorderBottomWidth: | |
198 case CSSPropertyBorderLeftWidth: | |
199 case CSSPropertyBorderRightWidth: | |
200 case CSSPropertyBorderTopWidth: | |
201 case CSSPropertyFontSize: | |
202 case CSSPropertyLetterSpacing: | |
203 case CSSPropertyOutlineOffset: | |
204 case CSSPropertyOutlineWidth: | |
205 case CSSPropertyPerspective: | |
206 case CSSPropertyStrokeWidth: | |
207 case CSSPropertyVerticalAlign: | |
208 case CSSPropertyWebkitBorderHorizontalSpacing: | |
209 case CSSPropertyWebkitBorderVerticalSpacing: | |
210 case CSSPropertyWebkitColumnGap: | |
211 case CSSPropertyWebkitColumnRuleWidth: | |
212 case CSSPropertyWebkitColumnWidth: | |
213 case CSSPropertyWebkitTransformOriginZ: | |
214 case CSSPropertyWordSpacing: | |
215 return nullptr; | |
216 default: | |
217 ASSERT_NOT_REACHED(); | |
218 return nullptr; | |
219 } | |
220 } | |
221 | |
222 namespace { | |
223 | |
224 static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType) | 71 static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType) |
225 { | 72 { |
226 return static_cast<CSSPrimitiveValue::UnitType>(CSSPrimitiveValue::lengthUni
tTypeToUnitType(static_cast<CSSPrimitiveValue::LengthUnitType>(lengthUnitType)))
; | 73 return static_cast<CSSPrimitiveValue::UnitType>(CSSPrimitiveValue::lengthUni
tTypeToUnitType(static_cast<CSSPrimitiveValue::LengthUnitType>(lengthUnitType)))
; |
227 } | 74 } |
228 | 75 |
229 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> constructCalcExpression(con
st InterpolableList* list) | 76 static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> constructCalcExpression(con
st InterpolableList* list) |
230 { | 77 { |
231 const InterpolableList* listOfValues = toInterpolableList(list->get(0)); | 78 const InterpolableList* listOfValues = toInterpolableList(list->get(0)); |
232 const InterpolableList* listOfTypes = toInterpolableList(list->get(1)); | 79 const InterpolableList* listOfTypes = toInterpolableList(list->get(1)); |
233 RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = nullptr; | 80 RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = nullptr; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 return CSSPrimitiveValue::create(value, toUnitType(i)); | 150 return CSSPrimitiveValue::create(value, toUnitType(i)); |
304 } | 151 } |
305 } | 152 } |
306 ASSERT_NOT_REACHED(); | 153 ASSERT_NOT_REACHED(); |
307 default: | 154 default: |
308 ValueRange valueRange = (range == RangeNonNegative) ? ValueRangeNonNegat
ive : ValueRangeAll; | 155 ValueRange valueRange = (range == RangeNonNegative) ? ValueRangeNonNegat
ive : ValueRangeAll; |
309 return CSSPrimitiveValue::create(CSSCalcValue::create(constructCalcExpre
ssion(listOfValuesAndTypes), valueRange)); | 156 return CSSPrimitiveValue::create(CSSCalcValue::create(constructCalcExpre
ssion(listOfValuesAndTypes), valueRange)); |
310 } | 157 } |
311 } | 158 } |
312 | 159 |
313 void LengthStyleInterpolation::applyInterpolableValue(CSSPropertyID property, co
nst InterpolableValue& value, InterpolationRange range, StyleResolverState& stat
e, LengthSetter lengthSetter) | 160 void LengthStyleInterpolation::applyInterpolableValue(CSSPropertyID property, co
nst InterpolableValue& value, InterpolationRange range, StyleResolverState& stat
e) |
314 { | 161 { |
315 if (lengthSetter && isPixelsOrPercentOnly(value)) { | 162 if (isPixelsOrPercentOnly(value)) { |
316 (state.style()->*lengthSetter)(lengthFromInterpolableValue(value, range,
state.style()->effectiveZoom())); | 163 Length length = lengthFromInterpolableValue(value, range, state.style()-
>effectiveZoom()); |
| 164 if (LengthPropertyFunctions::setLength(property, *state.style(), length)
) { |
317 #if ENABLE(ASSERT) | 165 #if ENABLE(ASSERT) |
318 RefPtr<AnimatableValue> before = CSSAnimatableValueFactory::create(prope
rty, *state.style()); | 166 // Assert that setting the length on ComputedStyle directly is ident
ical to the AnimatableValue code path. |
319 StyleBuilder::applyProperty(property, state, fromInterpolableValue(value
, range).get()); | 167 RefPtr<AnimatableValue> before = CSSAnimatableValueFactory::create(p
roperty, *state.style()); |
320 RefPtr<AnimatableValue> after = CSSAnimatableValueFactory::create(proper
ty, *state.style()); | 168 StyleBuilder::applyProperty(property, state, fromInterpolableValue(v
alue, range).get()); |
321 ASSERT(before->equals(*after)); | 169 RefPtr<AnimatableValue> after = CSSAnimatableValueFactory::create(pr
operty, *state.style()); |
| 170 ASSERT(before->equals(*after)); |
322 #endif | 171 #endif |
323 } else { | 172 return; |
324 StyleBuilder::applyProperty(property, state, fromInterpolableValue(value
, range).get()); | 173 } |
325 } | 174 } |
| 175 StyleBuilder::applyProperty(property, state, fromInterpolableValue(value, ra
nge).get()); |
326 } | 176 } |
327 | 177 |
328 void LengthStyleInterpolation::apply(StyleResolverState& state) const | 178 void LengthStyleInterpolation::apply(StyleResolverState& state) const |
329 { | 179 { |
330 applyInterpolableValue(m_id, *m_cachedValue, m_range, state, m_lengthSetter)
; | 180 applyInterpolableValue(m_id, *m_cachedValue, m_range, state); |
331 } | 181 } |
332 | 182 |
333 } | 183 } |
OLD | NEW |