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