Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp

Issue 2283783002: Move static methods out of CSSLengthInterpolationType to LengthInterpolationFunctions (Closed)
Patch Set: Fix compile Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "core/animation/CSSLengthInterpolationType.h" 5 #include "core/animation/CSSLengthInterpolationType.h"
6 6
7 #include "core/animation/LengthInterpolationFunctions.h"
7 #include "core/animation/LengthPropertyFunctions.h" 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 "wtf/PtrUtil.h" 13 #include "wtf/PtrUtil.h"
13 #include <memory> 14 #include <memory>
14 15
15 namespace blink { 16 namespace blink {
16 17
17 // This class is implemented as a singleton whose instance represents the presen ce of percentages being used in a Length value
18 // while nullptr represents the absence of any percentages.
19 class CSSLengthNonInterpolableValue : public NonInterpolableValue {
20 public:
21 ~CSSLengthNonInterpolableValue() final { NOTREACHED(); }
22 static PassRefPtr<CSSLengthNonInterpolableValue> create(bool hasPercentage)
23 {
24 DEFINE_STATIC_REF(CSSLengthNonInterpolableValue, singleton, adoptRef(new CSSLengthNonInterpolableValue()));
25 DCHECK(singleton);
26 return hasPercentage ? singleton : nullptr;
27 }
28 static PassRefPtr<CSSLengthNonInterpolableValue> merge(const NonInterpolable Value* a, const NonInterpolableValue* b)
29 {
30 return create(hasPercentage(a) || hasPercentage(b));
31 }
32 static bool hasPercentage(const NonInterpolableValue*);
33
34 DECLARE_NON_INTERPOLABLE_VALUE_TYPE();
35
36 private:
37 CSSLengthNonInterpolableValue() { }
38 };
39
40 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSLengthNonInterpolableValue);
41 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSLengthNonInterpolableValue);
42
43 bool CSSLengthNonInterpolableValue::hasPercentage(const NonInterpolableValue* no nInterpolableValue)
44 {
45 DCHECK(isCSSLengthNonInterpolableValue(nonInterpolableValue));
46 return static_cast<bool>(nonInterpolableValue);
47 }
48
49 CSSLengthInterpolationType::CSSLengthInterpolationType(CSSPropertyID property) 18 CSSLengthInterpolationType::CSSLengthInterpolationType(CSSPropertyID property)
50 : CSSInterpolationType(property) 19 : CSSInterpolationType(property)
51 , m_valueRange(LengthPropertyFunctions::getValueRange(property)) 20 , m_valueRange(LengthPropertyFunctions::getValueRange(property))
52 { } 21 { }
53 22
54 float CSSLengthInterpolationType::effectiveZoom(const ComputedStyle& style) cons t 23 float CSSLengthInterpolationType::effectiveZoom(const ComputedStyle& style) cons t
55 { 24 {
56 return LengthPropertyFunctions::isZoomedLength(cssProperty()) ? style.effect iveZoom() : 1; 25 return LengthPropertyFunctions::isZoomedLength(cssProperty()) ? style.effect iveZoom() : 1;
57 } 26 }
58 27
59 std::unique_ptr<InterpolableValue> CSSLengthInterpolationType::createInterpolabl ePixels(double pixels)
60 {
61 std::unique_ptr<InterpolableList> interpolableList = createNeutralInterpolab leValue();
62 interpolableList->set(CSSPrimitiveValue::UnitTypePixels, InterpolableNumber: :create(pixels));
63 return std::move(interpolableList);
64 }
65
66 InterpolationValue CSSLengthInterpolationType::createInterpolablePercent(double percent)
67 {
68 std::unique_ptr<InterpolableList> interpolableList = createNeutralInterpolab leValue();
69 interpolableList->set(CSSPrimitiveValue::UnitTypePercentage, InterpolableNum ber::create(percent));
70 return InterpolationValue(std::move(interpolableList), CSSLengthNonInterpola bleValue::create(true));
71 }
72
73 InterpolationValue CSSLengthInterpolationType::maybeConvertLength(const Length& length, float zoom)
74 {
75 if (!length.isSpecified())
76 return nullptr;
77
78 PixelsAndPercent pixelsAndPercent = length.getPixelsAndPercent();
79 std::unique_ptr<InterpolableList> values = createNeutralInterpolableValue();
80 values->set(CSSPrimitiveValue::UnitTypePixels, InterpolableNumber::create(pi xelsAndPercent.pixels / zoom));
81 values->set(CSSPrimitiveValue::UnitTypePercentage, InterpolableNumber::creat e(pixelsAndPercent.percent));
82
83 return InterpolationValue(std::move(values), CSSLengthNonInterpolableValue:: create(length.isPercentOrCalc()));
84 }
85
86 std::unique_ptr<InterpolableList> CSSLengthInterpolationType::createNeutralInter polableValue()
87 {
88 const size_t length = CSSPrimitiveValue::LengthUnitTypeCount;
89 std::unique_ptr<InterpolableList> values = InterpolableList::create(length);
90 for (size_t i = 0; i < length; i++)
91 values->set(i, InterpolableNumber::create(0));
92 return values;
93 }
94
95 PairwiseInterpolationValue CSSLengthInterpolationType::staticMergeSingleConversi ons(InterpolationValue&& start, InterpolationValue&& end)
96 {
97 return PairwiseInterpolationValue(
98 std::move(start.interpolableValue),
99 std::move(end.interpolableValue),
100 CSSLengthNonInterpolableValue::merge(start.nonInterpolableValue.get(), e nd.nonInterpolableValue.get()));
101 }
102
103 bool CSSLengthInterpolationType::nonInterpolableValuesAreCompatible(const NonInt erpolableValue* a, const NonInterpolableValue* b)
104 {
105 DCHECK(isCSSLengthNonInterpolableValue(a));
106 DCHECK(isCSSLengthNonInterpolableValue(b));
107 return true;
108 }
109
110 void CSSLengthInterpolationType::composite(
111 std::unique_ptr<InterpolableValue>& underlyingInterpolableValue,
112 RefPtr<NonInterpolableValue>& underlyingNonInterpolableValue,
113 double underlyingFraction,
114 const InterpolableValue& interpolableValue,
115 const NonInterpolableValue* nonInterpolableValue)
116 {
117 underlyingInterpolableValue->scaleAndAdd(underlyingFraction, interpolableVal ue);
118 underlyingNonInterpolableValue = CSSLengthNonInterpolableValue::merge(underl yingNonInterpolableValue.get(), nonInterpolableValue);
119 }
120
121 void CSSLengthInterpolationType::subtractFromOneHundredPercent(InterpolationValu e& result)
122 {
123 InterpolableList& list = toInterpolableList(*result.interpolableValue);
124 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) {
125 double value = -toInterpolableNumber(*list.get(i)).value();
126 if (i == CSSPrimitiveValue::UnitTypePercentage)
127 value += 100;
128 toInterpolableNumber(*list.getMutable(i)).set(value);
129 }
130 result.nonInterpolableValue = CSSLengthNonInterpolableValue::create(true);
131 }
132
133 InterpolationValue CSSLengthInterpolationType::maybeConvertCSSValue(const CSSVal ue& value)
134 {
135 if (!value.isPrimitiveValue())
136 return nullptr;
137
138 const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value);
139 if (!primitiveValue.isLength() && !primitiveValue.isPercentage() && !primiti veValue.isCalculatedPercentageWithLength())
140 return nullptr;
141
142 CSSLengthArray lengthArray;
143 primitiveValue.accumulateLengthArray(lengthArray);
144
145 std::unique_ptr<InterpolableList> values = InterpolableList::create(CSSPrimi tiveValue::LengthUnitTypeCount);
146 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++)
147 values->set(i, InterpolableNumber::create(lengthArray.values[i]));
148
149 bool hasPercentage = lengthArray.typeFlags.get(CSSPrimitiveValue::UnitTypePe rcentage);
150 return InterpolationValue(std::move(values), CSSLengthNonInterpolableValue:: create(hasPercentage));
151 }
152
153 class ParentLengthChecker : public InterpolationType::ConversionChecker { 28 class ParentLengthChecker : public InterpolationType::ConversionChecker {
154 public: 29 public:
155 static std::unique_ptr<ParentLengthChecker> create(CSSPropertyID property, c onst Length& length) 30 static std::unique_ptr<ParentLengthChecker> create(CSSPropertyID property, c onst Length& length)
156 { 31 {
157 return wrapUnique(new ParentLengthChecker(property, length)); 32 return wrapUnique(new ParentLengthChecker(property, length));
158 } 33 }
159 34
160 private: 35 private:
161 ParentLengthChecker(CSSPropertyID property, const Length& length) 36 ParentLengthChecker(CSSPropertyID property, const Length& length)
162 : m_property(property) 37 : m_property(property)
163 , m_length(length) 38 , m_length(length)
164 { } 39 { }
165 40
166 bool isValid(const InterpolationEnvironment& environment, const Interpolatio nValue& underlying) const final 41 bool isValid(const InterpolationEnvironment& environment, const Interpolatio nValue& underlying) const final
167 { 42 {
168 Length parentLength; 43 Length parentLength;
169 if (!LengthPropertyFunctions::getLength(m_property, *environment.state() .parentStyle(), parentLength)) 44 if (!LengthPropertyFunctions::getLength(m_property, *environment.state() .parentStyle(), parentLength))
170 return false; 45 return false;
171 return parentLength == m_length; 46 return parentLength == m_length;
172 } 47 }
173 48
174 const CSSPropertyID m_property; 49 const CSSPropertyID m_property;
175 const Length m_length; 50 const Length m_length;
176 }; 51 };
177 52
178 InterpolationValue CSSLengthInterpolationType::maybeConvertNeutral(const Interpo lationValue&, ConversionCheckers&) const 53 InterpolationValue CSSLengthInterpolationType::maybeConvertNeutral(const Interpo lationValue&, ConversionCheckers&) const
179 { 54 {
180 return InterpolationValue(createNeutralInterpolableValue()); 55 return InterpolationValue(LengthInterpolationFunctions::createNeutralInterpo lableValue());
181 } 56 }
182 57
183 InterpolationValue CSSLengthInterpolationType::maybeConvertInitial(const StyleRe solverState&, ConversionCheckers& conversionCheckers) const 58 InterpolationValue CSSLengthInterpolationType::maybeConvertInitial(const StyleRe solverState&, ConversionCheckers& conversionCheckers) const
184 { 59 {
185 Length initialLength; 60 Length initialLength;
186 if (!LengthPropertyFunctions::getInitialLength(cssProperty(), initialLength) ) 61 if (!LengthPropertyFunctions::getInitialLength(cssProperty(), initialLength) )
187 return nullptr; 62 return nullptr;
188 return maybeConvertLength(initialLength, 1); 63 return LengthInterpolationFunctions::maybeConvertLength(initialLength, 1);
189 } 64 }
190 65
191 InterpolationValue CSSLengthInterpolationType::maybeConvertInherit(const StyleRe solverState& state, ConversionCheckers& conversionCheckers) const 66 InterpolationValue CSSLengthInterpolationType::maybeConvertInherit(const StyleRe solverState& state, ConversionCheckers& conversionCheckers) const
192 { 67 {
193 if (!state.parentStyle()) 68 if (!state.parentStyle())
194 return nullptr; 69 return nullptr;
195 Length inheritedLength; 70 Length inheritedLength;
196 if (!LengthPropertyFunctions::getLength(cssProperty(), *state.parentStyle(), inheritedLength)) 71 if (!LengthPropertyFunctions::getLength(cssProperty(), *state.parentStyle(), inheritedLength))
197 return nullptr; 72 return nullptr;
198 conversionCheckers.append(ParentLengthChecker::create(cssProperty(), inherit edLength)); 73 conversionCheckers.append(ParentLengthChecker::create(cssProperty(), inherit edLength));
199 return maybeConvertLength(inheritedLength, effectiveZoom(*state.parentStyle( ))); 74 return LengthInterpolationFunctions::maybeConvertLength(inheritedLength, eff ectiveZoom(*state.parentStyle()));
200 } 75 }
201 76
202 InterpolationValue CSSLengthInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers& conversionCheckers) const 77 InterpolationValue CSSLengthInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers& conversionCheckers) const
203 { 78 {
204 if (value.isPrimitiveValue() && toCSSPrimitiveValue(value).isValueID()) { 79 if (value.isPrimitiveValue() && toCSSPrimitiveValue(value).isValueID()) {
205 CSSValueID valueID = toCSSPrimitiveValue(value).getValueID(); 80 CSSValueID valueID = toCSSPrimitiveValue(value).getValueID();
206 double pixels; 81 double pixels;
207 if (!LengthPropertyFunctions::getPixelsForKeyword(cssProperty(), valueID , pixels)) 82 if (!LengthPropertyFunctions::getPixelsForKeyword(cssProperty(), valueID , pixels))
208 return nullptr; 83 return nullptr;
209 return InterpolationValue(createInterpolablePixels(pixels)); 84 return InterpolationValue(LengthInterpolationFunctions::createInterpolab lePixels(pixels));
210 } 85 }
211 86
212 return maybeConvertCSSValue(value); 87 return LengthInterpolationFunctions::maybeConvertCSSValue(value);
88 }
89
90 PairwiseInterpolationValue CSSLengthInterpolationType::maybeMergeSingles(Interpo lationValue&& start, InterpolationValue&& end) const
91 {
92 return LengthInterpolationFunctions::mergeSingles(std::move(start), std::mov e(end));
213 } 93 }
214 94
215 InterpolationValue CSSLengthInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const 95 InterpolationValue CSSLengthInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
216 { 96 {
217 Length underlyingLength; 97 Length underlyingLength;
218 if (!LengthPropertyFunctions::getLength(cssProperty(), *environment.state(). style(), underlyingLength)) 98 if (!LengthPropertyFunctions::getLength(cssProperty(), *environment.state(). style(), underlyingLength))
219 return nullptr; 99 return nullptr;
220 return maybeConvertLength(underlyingLength, effectiveZoom(*environment.state ().style())); 100 return LengthInterpolationFunctions::maybeConvertLength(underlyingLength, ef fectiveZoom(*environment.state().style()));
221 } 101 }
222 102
223 void CSSLengthInterpolationType::composite(UnderlyingValueOwner& underlyingValue Owner, double underlyingFraction, const InterpolationValue& value, double interp olationFraction) const 103 void CSSLengthInterpolationType::composite(UnderlyingValueOwner& underlyingValue Owner, double underlyingFraction, const InterpolationValue& value, double interp olationFraction) const
224 { 104 {
225 InterpolationValue& underlying = underlyingValueOwner.mutableValue(); 105 InterpolationValue& underlying = underlyingValueOwner.mutableValue();
226 composite(underlying.interpolableValue, underlying.nonInterpolableValue, 106 LengthInterpolationFunctions::composite(underlying.interpolableValue, underl ying.nonInterpolableValue,
227 underlyingFraction, *value.interpolableValue, value.nonInterpolableValue .get()); 107 underlyingFraction, *value.interpolableValue, value.nonInterpolableValue .get());
228 } 108 }
229 109
230 // TODO(alancutter): Move this to Length.h.
231 static double clampToRange(double x, ValueRange range)
232 {
233 return (range == ValueRangeNonNegative && x < 0) ? 0 : x;
234 }
235
236 Length CSSLengthInterpolationType::createLength(const InterpolableValue& interpo lableValue, const NonInterpolableValue* nonInterpolableValue, const CSSToLengthC onversionData& conversionData, ValueRange range)
237 {
238 const InterpolableList& interpolableList = toInterpolableList(interpolableVa lue);
239 bool hasPercentage = CSSLengthNonInterpolableValue::hasPercentage(nonInterpo lableValue);
240 double pixels = 0;
241 double percentage = 0;
242 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) {
243 double value = toInterpolableNumber(*interpolableList.get(i)).value();
244 if (i == CSSPrimitiveValue::UnitTypePercentage) {
245 percentage = value;
246 } else {
247 CSSPrimitiveValue::UnitType type = CSSPrimitiveValue::lengthUnitType ToUnitType(static_cast<CSSPrimitiveValue::LengthUnitType>(i));
248 pixels += conversionData.zoomedComputedPixels(value, type);
249 }
250 }
251 if (percentage != 0)
252 hasPercentage = true;
253 if (pixels != 0 && hasPercentage)
254 return Length(CalculationValue::create(PixelsAndPercent(pixels, percenta ge), range));
255 if (hasPercentage)
256 return Length(clampToRange(percentage, range), Percent);
257 return Length(CSSPrimitiveValue::clampToCSSLengthRange(clampToRange(pixels, range)), Fixed);
258 }
259
260 void CSSLengthInterpolationType::apply(const InterpolableValue& interpolableValu e, const NonInterpolableValue* nonInterpolableValue, InterpolationEnvironment& e nvironment) const 110 void CSSLengthInterpolationType::apply(const InterpolableValue& interpolableValu e, const NonInterpolableValue* nonInterpolableValue, InterpolationEnvironment& e nvironment) const
261 { 111 {
262 StyleResolverState& state = environment.state(); 112 StyleResolverState& state = environment.state();
263 ComputedStyle& style = *state.style(); 113 ComputedStyle& style = *state.style();
264 float zoom = effectiveZoom(style); 114 float zoom = effectiveZoom(style);
265 Length length = createLength(interpolableValue, nonInterpolableValue, state. cssToLengthConversionData(), m_valueRange); 115 Length length = LengthInterpolationFunctions::createLength(interpolableValue , nonInterpolableValue, state.cssToLengthConversionData(), m_valueRange);
266 if (LengthPropertyFunctions::setLength(cssProperty(), style, length)) { 116 if (LengthPropertyFunctions::setLength(cssProperty(), style, length)) {
267 #if DCHECK_IS_ON() 117 #if DCHECK_IS_ON()
268 // Assert that setting the length on ComputedStyle directly is identical to the StyleBuilder code path. 118 // Assert that setting the length on ComputedStyle directly is identical to the StyleBuilder code path.
269 // This check is useful for catching differences in clamping behaviour. 119 // This check is useful for catching differences in clamping behaviour.
270 Length before; 120 Length before;
271 Length after; 121 Length after;
272 DCHECK(LengthPropertyFunctions::getLength(cssProperty(), style, before)) ; 122 DCHECK(LengthPropertyFunctions::getLength(cssProperty(), style, before)) ;
273 StyleBuilder::applyProperty(cssProperty(), state, *CSSPrimitiveValue::cr eate(length, zoom)); 123 StyleBuilder::applyProperty(cssProperty(), state, *CSSPrimitiveValue::cr eate(length, zoom));
274 DCHECK(LengthPropertyFunctions::getLength(cssProperty(), style, after)); 124 DCHECK(LengthPropertyFunctions::getLength(cssProperty(), style, after));
275 DCHECK(before == after); 125 DCHECK(before == after);
276 #endif 126 #endif
277 return; 127 return;
278 } 128 }
279 StyleBuilder::applyProperty(cssProperty(), state, *CSSPrimitiveValue::create (length, zoom)); 129 StyleBuilder::applyProperty(cssProperty(), state, *CSSPrimitiveValue::create (length, zoom));
280 } 130 }
281 131
282 } // namespace blink 132 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698