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

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

Issue 2696563006: Add "auto" handling to border-image-width animations (Closed)
Patch Set: default Created 3 years, 10 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
« no previous file with comments | « third_party/WebKit/LayoutTests/animations/interpolation/border-image-width-interpolation-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/CSSBorderImageLengthBoxInterpolationType.h" 5 #include "core/animation/CSSBorderImageLengthBoxInterpolationType.h"
6 6
7 #include <memory>
7 #include "core/animation/BorderImageLengthBoxPropertyFunctions.h" 8 #include "core/animation/BorderImageLengthBoxPropertyFunctions.h"
8 #include "core/animation/LengthInterpolationFunctions.h" 9 #include "core/animation/LengthInterpolationFunctions.h"
10 #include "core/css/CSSIdentifierValue.h"
9 #include "core/css/CSSQuadValue.h" 11 #include "core/css/CSSQuadValue.h"
10 #include "core/css/resolver/StyleResolverState.h" 12 #include "core/css/resolver/StyleResolverState.h"
11 #include "wtf/PtrUtil.h" 13 #include "wtf/PtrUtil.h"
12 #include <memory>
13 14
14 namespace blink { 15 namespace blink {
15 16
16 namespace { 17 namespace {
17 18
18 enum SideIndex : unsigned { 19 enum SideIndex : unsigned {
19 SideTop, 20 SideTop,
20 SideRight, 21 SideRight,
21 SideBottom, 22 SideBottom,
22 SideLeft, 23 SideLeft,
23 SideIndexCount, 24 SideIndexCount,
24 }; 25 };
25 26
26 struct SideNumbers { 27 enum class SideType {
27 explicit SideNumbers(const BorderImageLengthBox& box) { 28 Number,
28 isNumber[SideTop] = box.top().isNumber(); 29 Auto,
29 isNumber[SideRight] = box.right().isNumber(); 30 Length,
30 isNumber[SideBottom] = box.bottom().isNumber(); 31 };
31 isNumber[SideLeft] = box.left().isNumber(); 32
33 SideType getSideType(const BorderImageLength& side) {
34 if (side.isNumber()) {
35 return SideType::Number;
32 } 36 }
33 explicit SideNumbers(const CSSQuadValue& quad) { 37 if (side.length().isAuto()) {
34 isNumber[SideTop] = quad.top()->isPrimitiveValue() && 38 return SideType::Auto;
35 toCSSPrimitiveValue(quad.top())->isNumber(); 39 }
36 isNumber[SideRight] = quad.right()->isPrimitiveValue() && 40 DCHECK(side.length().isSpecified());
37 toCSSPrimitiveValue(quad.right())->isNumber(); 41 return SideType::Length;
38 isNumber[SideBottom] = quad.bottom()->isPrimitiveValue() && 42 }
39 toCSSPrimitiveValue(quad.bottom())->isNumber(); 43
40 isNumber[SideLeft] = quad.left()->isPrimitiveValue() && 44 SideType getSideType(const CSSValue& side) {
41 toCSSPrimitiveValue(quad.left())->isNumber(); 45 if (side.isPrimitiveValue() && toCSSPrimitiveValue(side).isNumber()) {
46 return SideType::Number;
47 }
48 if (side.isIdentifierValue() &&
49 toCSSIdentifierValue(side).getValueID() == CSSValueAuto) {
50 return SideType::Auto;
51 }
52 return SideType::Length;
53 }
54
55 struct SideTypes {
56 explicit SideTypes(const BorderImageLengthBox& box) {
57 type[SideTop] = getSideType(box.top());
58 type[SideRight] = getSideType(box.right());
59 type[SideBottom] = getSideType(box.bottom());
60 type[SideLeft] = getSideType(box.left());
61 }
62 explicit SideTypes(const CSSQuadValue& quad) {
63 type[SideTop] = getSideType(*quad.top());
64 type[SideRight] = getSideType(*quad.right());
65 type[SideBottom] = getSideType(*quad.bottom());
66 type[SideLeft] = getSideType(*quad.left());
42 } 67 }
43 68
44 bool operator==(const SideNumbers& other) const { 69 bool operator==(const SideTypes& other) const {
45 for (size_t i = 0; i < SideIndexCount; i++) { 70 for (size_t i = 0; i < SideIndexCount; i++) {
46 if (isNumber[i] != other.isNumber[i]) 71 if (type[i] != other.type[i])
47 return false; 72 return false;
48 } 73 }
49 return true; 74 return true;
50 } 75 }
51 bool operator!=(const SideNumbers& other) const { return !(*this == other); } 76 bool operator!=(const SideTypes& other) const { return !(*this == other); }
52 77
53 bool isNumber[SideIndexCount]; 78 SideType type[SideIndexCount];
54 }; 79 };
55 80
56 } // namespace 81 } // namespace
57 82
58 class CSSBorderImageLengthBoxNonInterpolableValue 83 class CSSBorderImageLengthBoxNonInterpolableValue
59 : public NonInterpolableValue { 84 : public NonInterpolableValue {
60 public: 85 public:
61 static PassRefPtr<CSSBorderImageLengthBoxNonInterpolableValue> create( 86 static PassRefPtr<CSSBorderImageLengthBoxNonInterpolableValue> create(
62 const SideNumbers& sideNumbers, 87 const SideTypes& sideTypes,
63 Vector<RefPtr<NonInterpolableValue>>&& sideNonInterpolableValues) { 88 Vector<RefPtr<NonInterpolableValue>>&& sideNonInterpolableValues) {
64 return adoptRef(new CSSBorderImageLengthBoxNonInterpolableValue( 89 return adoptRef(new CSSBorderImageLengthBoxNonInterpolableValue(
65 sideNumbers, std::move(sideNonInterpolableValues))); 90 sideTypes, std::move(sideNonInterpolableValues)));
66 } 91 }
67 92
68 const SideNumbers& sideNumbers() const { return m_sideNumbers; } 93 PassRefPtr<CSSBorderImageLengthBoxNonInterpolableValue> clone() {
94 return adoptRef(new CSSBorderImageLengthBoxNonInterpolableValue(
95 m_sideTypes,
96 Vector<RefPtr<NonInterpolableValue>>(m_sideNonInterpolableValues)));
97 }
98
99 const SideTypes& sideTypes() const { return m_sideTypes; }
69 const Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues() 100 const Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues()
70 const { 101 const {
71 return m_sideNonInterpolableValues; 102 return m_sideNonInterpolableValues;
72 } 103 }
73 Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues() { 104 Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues() {
74 return m_sideNonInterpolableValues; 105 return m_sideNonInterpolableValues;
75 } 106 }
76 107
77 DECLARE_NON_INTERPOLABLE_VALUE_TYPE(); 108 DECLARE_NON_INTERPOLABLE_VALUE_TYPE();
78 109
79 private: 110 private:
80 CSSBorderImageLengthBoxNonInterpolableValue( 111 CSSBorderImageLengthBoxNonInterpolableValue(
81 const SideNumbers& sideNumbers, 112 const SideTypes& sideTypes,
82 Vector<RefPtr<NonInterpolableValue>>&& sideNonInterpolableValues) 113 Vector<RefPtr<NonInterpolableValue>>&& sideNonInterpolableValues)
83 : m_sideNumbers(sideNumbers), 114 : m_sideTypes(sideTypes),
84 m_sideNonInterpolableValues(sideNonInterpolableValues) { 115 m_sideNonInterpolableValues(sideNonInterpolableValues) {
85 DCHECK_EQ(m_sideNonInterpolableValues.size(), SideIndexCount); 116 DCHECK_EQ(m_sideNonInterpolableValues.size(), SideIndexCount);
86 } 117 }
87 118
88 const SideNumbers m_sideNumbers; 119 const SideTypes m_sideTypes;
89 Vector<RefPtr<NonInterpolableValue>> m_sideNonInterpolableValues; 120 Vector<RefPtr<NonInterpolableValue>> m_sideNonInterpolableValues;
90 }; 121 };
91 122
92 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSBorderImageLengthBoxNonInterpolableValue); 123 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSBorderImageLengthBoxNonInterpolableValue);
93 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS( 124 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(
94 CSSBorderImageLengthBoxNonInterpolableValue); 125 CSSBorderImageLengthBoxNonInterpolableValue);
95 126
96 namespace { 127 namespace {
97 128
98 class UnderlyingSideNumbersChecker 129 class UnderlyingSideTypesChecker : public InterpolationType::ConversionChecker {
99 : public InterpolationType::ConversionChecker {
100 public: 130 public:
101 static std::unique_ptr<UnderlyingSideNumbersChecker> create( 131 static std::unique_ptr<UnderlyingSideTypesChecker> create(
102 const SideNumbers& underlyingSideNumbers) { 132 const SideTypes& underlyingSideTypes) {
103 return WTF::wrapUnique( 133 return WTF::wrapUnique(new UnderlyingSideTypesChecker(underlyingSideTypes));
104 new UnderlyingSideNumbersChecker(underlyingSideNumbers));
105 } 134 }
106 135
107 static SideNumbers getUnderlyingSideNumbers( 136 static SideTypes getUnderlyingSideTypes(
108 const InterpolationValue& underlying) { 137 const InterpolationValue& underlying) {
109 return toCSSBorderImageLengthBoxNonInterpolableValue( 138 return toCSSBorderImageLengthBoxNonInterpolableValue(
110 *underlying.nonInterpolableValue) 139 *underlying.nonInterpolableValue)
111 .sideNumbers(); 140 .sideTypes();
112 } 141 }
113 142
114 private: 143 private:
115 UnderlyingSideNumbersChecker(const SideNumbers& underlyingSideNumbers) 144 UnderlyingSideTypesChecker(const SideTypes& underlyingSideTypes)
116 : m_underlyingSideNumbers(underlyingSideNumbers) {} 145 : m_underlyingSideTypes(underlyingSideTypes) {}
117 146
118 bool isValid(const InterpolationEnvironment&, 147 bool isValid(const InterpolationEnvironment&,
119 const InterpolationValue& underlying) const final { 148 const InterpolationValue& underlying) const final {
120 return m_underlyingSideNumbers == getUnderlyingSideNumbers(underlying); 149 return m_underlyingSideTypes == getUnderlyingSideTypes(underlying);
121 } 150 }
122 151
123 const SideNumbers m_underlyingSideNumbers; 152 const SideTypes m_underlyingSideTypes;
124 }; 153 };
125 154
126 class InheritedSideNumbersChecker 155 class InheritedSideTypesChecker : public InterpolationType::ConversionChecker {
127 : public InterpolationType::ConversionChecker {
128 public: 156 public:
129 static std::unique_ptr<InheritedSideNumbersChecker> create( 157 static std::unique_ptr<InheritedSideTypesChecker> create(
130 CSSPropertyID property, 158 CSSPropertyID property,
131 const SideNumbers& inheritedSideNumbers) { 159 const SideTypes& inheritedSideTypes) {
132 return WTF::wrapUnique( 160 return WTF::wrapUnique(
133 new InheritedSideNumbersChecker(property, inheritedSideNumbers)); 161 new InheritedSideTypesChecker(property, inheritedSideTypes));
134 } 162 }
135 163
136 private: 164 private:
137 InheritedSideNumbersChecker(CSSPropertyID property, 165 InheritedSideTypesChecker(CSSPropertyID property,
138 const SideNumbers& inheritedSideNumbers) 166 const SideTypes& inheritedSideTypes)
139 : m_property(property), m_inheritedSideNumbers(inheritedSideNumbers) {} 167 : m_property(property), m_inheritedSideTypes(inheritedSideTypes) {}
140 168
141 bool isValid(const InterpolationEnvironment& environment, 169 bool isValid(const InterpolationEnvironment& environment,
142 const InterpolationValue& underlying) const final { 170 const InterpolationValue& underlying) const final {
143 return m_inheritedSideNumbers == 171 return m_inheritedSideTypes ==
144 SideNumbers( 172 SideTypes(
145 BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox( 173 BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox(
146 m_property, *environment.state().parentStyle())); 174 m_property, *environment.state().parentStyle()));
147 } 175 }
148 176
149 const CSSPropertyID m_property; 177 const CSSPropertyID m_property;
150 const SideNumbers m_inheritedSideNumbers; 178 const SideTypes m_inheritedSideTypes;
151 }; 179 };
152 180
153 InterpolationValue convertBorderImageLengthBox(const BorderImageLengthBox& box, 181 InterpolationValue convertBorderImageLengthBox(const BorderImageLengthBox& box,
154 double zoom) { 182 double zoom) {
155 std::unique_ptr<InterpolableList> list = 183 std::unique_ptr<InterpolableList> list =
156 InterpolableList::create(SideIndexCount); 184 InterpolableList::create(SideIndexCount);
157 Vector<RefPtr<NonInterpolableValue>> nonInterpolableValues(SideIndexCount); 185 Vector<RefPtr<NonInterpolableValue>> nonInterpolableValues(SideIndexCount);
158 const BorderImageLength* sides[SideIndexCount] = {}; 186 const BorderImageLength* sides[SideIndexCount] = {};
159 sides[SideTop] = &box.top(); 187 sides[SideTop] = &box.top();
160 sides[SideRight] = &box.right(); 188 sides[SideRight] = &box.right();
161 sides[SideBottom] = &box.bottom(); 189 sides[SideBottom] = &box.bottom();
162 sides[SideLeft] = &box.left(); 190 sides[SideLeft] = &box.left();
163 191
164 for (size_t i = 0; i < SideIndexCount; i++) { 192 for (size_t i = 0; i < SideIndexCount; i++) {
165 const BorderImageLength& side = *sides[i]; 193 const BorderImageLength& side = *sides[i];
166 if (side.isNumber()) { 194 if (side.isNumber()) {
167 list->set(i, InterpolableNumber::create(side.number())); 195 list->set(i, InterpolableNumber::create(side.number()));
196 } else if (side.length().isAuto()) {
197 list->set(i, InterpolableList::create(0));
168 } else { 198 } else {
169 InterpolationValue convertedSide = 199 InterpolationValue convertedSide =
170 LengthInterpolationFunctions::maybeConvertLength(side.length(), zoom); 200 LengthInterpolationFunctions::maybeConvertLength(side.length(), zoom);
171 if (!convertedSide) 201 if (!convertedSide)
172 return nullptr; 202 return nullptr;
173 list->set(i, std::move(convertedSide.interpolableValue)); 203 list->set(i, std::move(convertedSide.interpolableValue));
174 nonInterpolableValues[i] = std::move(convertedSide.nonInterpolableValue); 204 nonInterpolableValues[i] = std::move(convertedSide.nonInterpolableValue);
175 } 205 }
176 } 206 }
177 207
178 return InterpolationValue( 208 return InterpolationValue(
179 std::move(list), CSSBorderImageLengthBoxNonInterpolableValue::create( 209 std::move(list), CSSBorderImageLengthBoxNonInterpolableValue::create(
180 SideNumbers(box), std::move(nonInterpolableValues))); 210 SideTypes(box), std::move(nonInterpolableValues)));
181 } 211 }
182 212
183 } // namespace 213 } // namespace
184 214
185 InterpolationValue 215 InterpolationValue
186 CSSBorderImageLengthBoxInterpolationType::maybeConvertNeutral( 216 CSSBorderImageLengthBoxInterpolationType::maybeConvertNeutral(
187 const InterpolationValue& underlying, 217 const InterpolationValue& underlying,
188 ConversionCheckers& conversionCheckers) const { 218 ConversionCheckers& conversionCheckers) const {
189 SideNumbers underlyingSideNumbers = 219 SideTypes underlyingSideTypes =
190 UnderlyingSideNumbersChecker::getUnderlyingSideNumbers(underlying); 220 UnderlyingSideTypesChecker::getUnderlyingSideTypes(underlying);
191 conversionCheckers.push_back( 221 conversionCheckers.push_back(
192 UnderlyingSideNumbersChecker::create(underlyingSideNumbers)); 222 UnderlyingSideTypesChecker::create(underlyingSideTypes));
193 const auto& zero = [&underlyingSideNumbers](size_t index) { 223 return InterpolationValue(underlying.interpolableValue->cloneAndZero(),
194 return underlyingSideNumbers.isNumber[index] 224 toCSSBorderImageLengthBoxNonInterpolableValue(
195 ? BorderImageLength(0) 225 *underlying.nonInterpolableValue)
196 : BorderImageLength(Length(0, Fixed)); 226 .clone());
197 };
198 BorderImageLengthBox zeroBox(zero(SideTop), zero(SideRight), zero(SideBottom),
199 zero(SideLeft));
200 return convertBorderImageLengthBox(zeroBox, 1);
201 } 227 }
202 228
203 InterpolationValue 229 InterpolationValue
204 CSSBorderImageLengthBoxInterpolationType::maybeConvertInitial( 230 CSSBorderImageLengthBoxInterpolationType::maybeConvertInitial(
205 const StyleResolverState&, 231 const StyleResolverState&,
206 ConversionCheckers&) const { 232 ConversionCheckers&) const {
207 return convertBorderImageLengthBox( 233 return convertBorderImageLengthBox(
208 BorderImageLengthBoxPropertyFunctions::getInitialBorderImageLengthBox( 234 BorderImageLengthBoxPropertyFunctions::getInitialBorderImageLengthBox(
209 cssProperty()), 235 cssProperty()),
210 1); 236 1);
211 } 237 }
212 238
213 InterpolationValue 239 InterpolationValue
214 CSSBorderImageLengthBoxInterpolationType::maybeConvertInherit( 240 CSSBorderImageLengthBoxInterpolationType::maybeConvertInherit(
215 const StyleResolverState& state, 241 const StyleResolverState& state,
216 ConversionCheckers& conversionCheckers) const { 242 ConversionCheckers& conversionCheckers) const {
217 const BorderImageLengthBox& inherited = 243 const BorderImageLengthBox& inherited =
218 BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox( 244 BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox(
219 cssProperty(), *state.parentStyle()); 245 cssProperty(), *state.parentStyle());
220 conversionCheckers.push_back(InheritedSideNumbersChecker::create( 246 conversionCheckers.push_back(
221 cssProperty(), SideNumbers(inherited))); 247 InheritedSideTypesChecker::create(cssProperty(), SideTypes(inherited)));
222 return convertBorderImageLengthBox(inherited, 248 return convertBorderImageLengthBox(inherited,
223 state.parentStyle()->effectiveZoom()); 249 state.parentStyle()->effectiveZoom());
224 } 250 }
225 251
226 InterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeConvertValue( 252 InterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeConvertValue(
227 const CSSValue& value, 253 const CSSValue& value,
228 const StyleResolverState*, 254 const StyleResolverState*,
229 ConversionCheckers&) const { 255 ConversionCheckers&) const {
230 if (!value.isQuadValue()) 256 if (!value.isQuadValue())
231 return nullptr; 257 return nullptr;
232 258
233 const CSSQuadValue& quad = toCSSQuadValue(value); 259 const CSSQuadValue& quad = toCSSQuadValue(value);
234 std::unique_ptr<InterpolableList> list = 260 std::unique_ptr<InterpolableList> list =
235 InterpolableList::create(SideIndexCount); 261 InterpolableList::create(SideIndexCount);
236 Vector<RefPtr<NonInterpolableValue>> nonInterpolableValues(SideIndexCount); 262 Vector<RefPtr<NonInterpolableValue>> nonInterpolableValues(SideIndexCount);
237 const CSSValue* sides[SideIndexCount] = {}; 263 const CSSValue* sides[SideIndexCount] = {};
238 sides[SideTop] = quad.top(); 264 sides[SideTop] = quad.top();
239 sides[SideRight] = quad.right(); 265 sides[SideRight] = quad.right();
240 sides[SideBottom] = quad.bottom(); 266 sides[SideBottom] = quad.bottom();
241 sides[SideLeft] = quad.left(); 267 sides[SideLeft] = quad.left();
242 268
243 for (size_t i = 0; i < SideIndexCount; i++) { 269 for (size_t i = 0; i < SideIndexCount; i++) {
244 const CSSValue& side = *sides[i]; 270 const CSSValue& side = *sides[i];
245 if (side.isPrimitiveValue() && toCSSPrimitiveValue(side).isNumber()) { 271 if (side.isPrimitiveValue() && toCSSPrimitiveValue(side).isNumber()) {
246 list->set(i, InterpolableNumber::create( 272 list->set(i, InterpolableNumber::create(
247 toCSSPrimitiveValue(side).getDoubleValue())); 273 toCSSPrimitiveValue(side).getDoubleValue()));
274 } else if (side.isIdentifierValue() &&
275 toCSSIdentifierValue(side).getValueID() == CSSValueAuto) {
276 list->set(i, InterpolableList::create(0));
248 } else { 277 } else {
249 InterpolationValue convertedSide = 278 InterpolationValue convertedSide =
250 LengthInterpolationFunctions::maybeConvertCSSValue(side); 279 LengthInterpolationFunctions::maybeConvertCSSValue(side);
251 if (!convertedSide) 280 if (!convertedSide)
252 return nullptr; 281 return nullptr;
253 list->set(i, std::move(convertedSide.interpolableValue)); 282 list->set(i, std::move(convertedSide.interpolableValue));
254 nonInterpolableValues[i] = std::move(convertedSide.nonInterpolableValue); 283 nonInterpolableValues[i] = std::move(convertedSide.nonInterpolableValue);
255 } 284 }
256 } 285 }
257 286
258 return InterpolationValue( 287 return InterpolationValue(
259 std::move(list), 288 std::move(list), CSSBorderImageLengthBoxNonInterpolableValue::create(
260 CSSBorderImageLengthBoxNonInterpolableValue::create( 289 SideTypes(quad), std::move(nonInterpolableValues)));
261 SideNumbers(quad), std::move(nonInterpolableValues)));
262 } 290 }
263 291
264 InterpolationValue CSSBorderImageLengthBoxInterpolationType:: 292 InterpolationValue CSSBorderImageLengthBoxInterpolationType::
265 maybeConvertStandardPropertyUnderlyingValue( 293 maybeConvertStandardPropertyUnderlyingValue(
266 const ComputedStyle& style) const { 294 const ComputedStyle& style) const {
267 return convertBorderImageLengthBox( 295 return convertBorderImageLengthBox(
268 BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox( 296 BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox(
269 cssProperty(), style), 297 cssProperty(), style),
270 style.effectiveZoom()); 298 style.effectiveZoom());
271 } 299 }
272 300
273 PairwiseInterpolationValue 301 PairwiseInterpolationValue
274 CSSBorderImageLengthBoxInterpolationType::maybeMergeSingles( 302 CSSBorderImageLengthBoxInterpolationType::maybeMergeSingles(
275 InterpolationValue&& start, 303 InterpolationValue&& start,
276 InterpolationValue&& end) const { 304 InterpolationValue&& end) const {
277 const SideNumbers& startSideNumbers = 305 const SideTypes& startSideTypes =
278 toCSSBorderImageLengthBoxNonInterpolableValue(*start.nonInterpolableValue) 306 toCSSBorderImageLengthBoxNonInterpolableValue(*start.nonInterpolableValue)
279 .sideNumbers(); 307 .sideTypes();
280 const SideNumbers& endSideNumbers = 308 const SideTypes& endSideTypes =
281 toCSSBorderImageLengthBoxNonInterpolableValue(*end.nonInterpolableValue) 309 toCSSBorderImageLengthBoxNonInterpolableValue(*end.nonInterpolableValue)
282 .sideNumbers(); 310 .sideTypes();
283 311 if (startSideTypes != endSideTypes)
284 if (startSideNumbers != endSideNumbers)
285 return nullptr; 312 return nullptr;
286 313
287 return PairwiseInterpolationValue(std::move(start.interpolableValue), 314 return PairwiseInterpolationValue(std::move(start.interpolableValue),
288 std::move(end.interpolableValue), 315 std::move(end.interpolableValue),
289 std::move(start.nonInterpolableValue)); 316 std::move(start.nonInterpolableValue));
290 } 317 }
291 318
292 void CSSBorderImageLengthBoxInterpolationType::composite( 319 void CSSBorderImageLengthBoxInterpolationType::composite(
293 UnderlyingValueOwner& underlyingValueOwner, 320 UnderlyingValueOwner& underlyingValueOwner,
294 double underlyingFraction, 321 double underlyingFraction,
295 const InterpolationValue& value, 322 const InterpolationValue& value,
296 double interpolationFraction) const { 323 double interpolationFraction) const {
297 const SideNumbers& underlyingSideNumbers = 324 const SideTypes& underlyingSideTypes =
298 toCSSBorderImageLengthBoxNonInterpolableValue( 325 toCSSBorderImageLengthBoxNonInterpolableValue(
299 *underlyingValueOwner.value().nonInterpolableValue) 326 *underlyingValueOwner.value().nonInterpolableValue)
300 .sideNumbers(); 327 .sideTypes();
301 const auto& nonInterpolableValue = 328 const auto& nonInterpolableValue =
302 toCSSBorderImageLengthBoxNonInterpolableValue( 329 toCSSBorderImageLengthBoxNonInterpolableValue(
303 *value.nonInterpolableValue); 330 *value.nonInterpolableValue);
304 const SideNumbers& sideNumbers = nonInterpolableValue.sideNumbers(); 331 const SideTypes& sideTypes = nonInterpolableValue.sideTypes();
305 332
306 if (underlyingSideNumbers != sideNumbers) { 333 if (underlyingSideTypes != sideTypes) {
307 underlyingValueOwner.set(*this, value); 334 underlyingValueOwner.set(*this, value);
308 return; 335 return;
309 } 336 }
310 337
311 InterpolationValue& underlyingValue = underlyingValueOwner.mutableValue(); 338 InterpolationValue& underlyingValue = underlyingValueOwner.mutableValue();
312 InterpolableList& underlyingList = 339 InterpolableList& underlyingList =
313 toInterpolableList(*underlyingValue.interpolableValue); 340 toInterpolableList(*underlyingValue.interpolableValue);
314 Vector<RefPtr<NonInterpolableValue>>& underlyingSideNonInterpolableValues = 341 Vector<RefPtr<NonInterpolableValue>>& underlyingSideNonInterpolableValues =
315 toCSSBorderImageLengthBoxNonInterpolableValue( 342 toCSSBorderImageLengthBoxNonInterpolableValue(
316 *underlyingValue.nonInterpolableValue) 343 *underlyingValue.nonInterpolableValue)
317 .sideNonInterpolableValues(); 344 .sideNonInterpolableValues();
318 const InterpolableList& list = toInterpolableList(*value.interpolableValue); 345 const InterpolableList& list = toInterpolableList(*value.interpolableValue);
319 const Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues = 346 const Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues =
320 nonInterpolableValue.sideNonInterpolableValues(); 347 nonInterpolableValue.sideNonInterpolableValues();
321 348
322 for (size_t i = 0; i < SideIndexCount; i++) { 349 for (size_t i = 0; i < SideIndexCount; i++) {
323 if (sideNumbers.isNumber[i]) 350 switch (sideTypes.type[i]) {
324 underlyingList.getMutable(i)->scaleAndAdd(underlyingFraction, 351 case SideType::Number:
325 *list.get(i)); 352 underlyingList.getMutable(i)->scaleAndAdd(underlyingFraction,
326 else 353 *list.get(i));
327 LengthInterpolationFunctions::composite( 354 break;
328 underlyingList.getMutable(i), underlyingSideNonInterpolableValues[i], 355 case SideType::Length:
329 underlyingFraction, *list.get(i), sideNonInterpolableValues[i].get()); 356 LengthInterpolationFunctions::composite(
357 underlyingList.getMutable(i),
358 underlyingSideNonInterpolableValues[i], underlyingFraction,
359 *list.get(i), sideNonInterpolableValues[i].get());
360 break;
361 case SideType::Auto:
362 break;
363 default:
364 NOTREACHED();
365 break;
366 }
330 } 367 }
331 } 368 }
332 369
333 void CSSBorderImageLengthBoxInterpolationType::applyStandardPropertyValue( 370 void CSSBorderImageLengthBoxInterpolationType::applyStandardPropertyValue(
334 const InterpolableValue& interpolableValue, 371 const InterpolableValue& interpolableValue,
335 const NonInterpolableValue* nonInterpolableValue, 372 const NonInterpolableValue* nonInterpolableValue,
336 StyleResolverState& state) const { 373 StyleResolverState& state) const {
337 const SideNumbers& sideNumbers = 374 const SideTypes& sideTypes =
338 toCSSBorderImageLengthBoxNonInterpolableValue(nonInterpolableValue) 375 toCSSBorderImageLengthBoxNonInterpolableValue(nonInterpolableValue)
339 ->sideNumbers(); 376 ->sideTypes();
340 const Vector<RefPtr<NonInterpolableValue>>& nonInterpolableValues = 377 const Vector<RefPtr<NonInterpolableValue>>& nonInterpolableValues =
341 toCSSBorderImageLengthBoxNonInterpolableValue(nonInterpolableValue) 378 toCSSBorderImageLengthBoxNonInterpolableValue(nonInterpolableValue)
342 ->sideNonInterpolableValues(); 379 ->sideNonInterpolableValues();
343 const InterpolableList& list = toInterpolableList(interpolableValue); 380 const InterpolableList& list = toInterpolableList(interpolableValue);
344 const auto& convertSide = 381 const auto& convertSide = [&sideTypes, &list, &state, &nonInterpolableValues](
345 [&sideNumbers, &list, &state, 382 size_t index) -> BorderImageLength {
346 &nonInterpolableValues](size_t index) -> BorderImageLength { 383 switch (sideTypes.type[index]) {
347 if (sideNumbers.isNumber[index]) 384 case SideType::Number:
348 return clampTo<double>(toInterpolableNumber(list.get(index))->value(), 0); 385 return clampTo<double>(toInterpolableNumber(list.get(index))->value(),
349 return LengthInterpolationFunctions::createLength( 386 0);
350 *list.get(index), nonInterpolableValues[index].get(), 387 case SideType::Auto:
351 state.cssToLengthConversionData(), ValueRangeNonNegative); 388 return Length(Auto);
389 case SideType::Length:
390 return LengthInterpolationFunctions::createLength(
391 *list.get(index), nonInterpolableValues[index].get(),
392 state.cssToLengthConversionData(), ValueRangeNonNegative);
393 default:
394 NOTREACHED();
395 return Length(Auto);
396 }
352 }; 397 };
353 BorderImageLengthBox box(convertSide(SideTop), convertSide(SideRight), 398 BorderImageLengthBox box(convertSide(SideTop), convertSide(SideRight),
354 convertSide(SideBottom), convertSide(SideLeft)); 399 convertSide(SideBottom), convertSide(SideLeft));
355 BorderImageLengthBoxPropertyFunctions::setBorderImageLengthBox( 400 BorderImageLengthBoxPropertyFunctions::setBorderImageLengthBox(
356 cssProperty(), *state.style(), box); 401 cssProperty(), *state.style(), box);
357 } 402 }
358 403
359 } // namespace blink 404 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/animations/interpolation/border-image-width-interpolation-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698