OLD | NEW |
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 |
OLD | NEW |