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/LengthInterpolationFunctions.h" | 5 #include "core/animation/LengthInterpolationFunctions.h" |
6 | 6 |
| 7 #include "core/css/CSSCalculationValue.h" |
7 #include "core/css/CSSPrimitiveValue.h" | 8 #include "core/css/CSSPrimitiveValue.h" |
8 #include "core/css/CSSToLengthConversionData.h" | 9 #include "core/css/CSSToLengthConversionData.h" |
9 #include "platform/CalculationValue.h" | 10 #include "platform/CalculationValue.h" |
10 | 11 |
11 namespace blink { | 12 namespace blink { |
12 | 13 |
13 // This class is implemented as a singleton whose instance represents the | 14 // This class is implemented as a singleton whose instance represents the |
14 // presence of percentages being used in a Length value while nullptr represents | 15 // presence of percentages being used in a Length value while nullptr represents |
15 // the absence of any percentages. | 16 // the absence of any percentages. |
16 class CSSLengthNonInterpolableValue : public NonInterpolableValue { | 17 class CSSLengthNonInterpolableValue : public NonInterpolableValue { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 value += 100; | 153 value += 100; |
153 toInterpolableNumber(*list.getMutable(i)).set(value); | 154 toInterpolableNumber(*list.getMutable(i)).set(value); |
154 } | 155 } |
155 result.nonInterpolableValue = CSSLengthNonInterpolableValue::create(true); | 156 result.nonInterpolableValue = CSSLengthNonInterpolableValue::create(true); |
156 } | 157 } |
157 | 158 |
158 static double clampToRange(double x, ValueRange range) { | 159 static double clampToRange(double x, ValueRange range) { |
159 return (range == ValueRangeNonNegative && x < 0) ? 0 : x; | 160 return (range == ValueRangeNonNegative && x < 0) ? 0 : x; |
160 } | 161 } |
161 | 162 |
| 163 CSSPrimitiveValue::UnitType indexToUnitType(size_t index) { |
| 164 return CSSPrimitiveValue::lengthUnitTypeToUnitType( |
| 165 static_cast<CSSPrimitiveValue::LengthUnitType>(index)); |
| 166 } |
| 167 |
162 Length LengthInterpolationFunctions::createLength( | 168 Length LengthInterpolationFunctions::createLength( |
163 const InterpolableValue& interpolableValue, | 169 const InterpolableValue& interpolableValue, |
164 const NonInterpolableValue* nonInterpolableValue, | 170 const NonInterpolableValue* nonInterpolableValue, |
165 const CSSToLengthConversionData& conversionData, | 171 const CSSToLengthConversionData& conversionData, |
166 ValueRange range) { | 172 ValueRange range) { |
167 const InterpolableList& interpolableList = | 173 const InterpolableList& interpolableList = |
168 toInterpolableList(interpolableValue); | 174 toInterpolableList(interpolableValue); |
169 bool hasPercentage = | 175 bool hasPercentage = |
170 CSSLengthNonInterpolableValue::hasPercentage(nonInterpolableValue); | 176 CSSLengthNonInterpolableValue::hasPercentage(nonInterpolableValue); |
171 double pixels = 0; | 177 double pixels = 0; |
172 double percentage = 0; | 178 double percentage = 0; |
173 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { | 179 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { |
174 double value = toInterpolableNumber(*interpolableList.get(i)).value(); | 180 double value = toInterpolableNumber(*interpolableList.get(i)).value(); |
175 if (value == 0) | 181 if (value == 0) |
176 continue; | 182 continue; |
177 if (i == CSSPrimitiveValue::UnitTypePercentage) { | 183 if (i == CSSPrimitiveValue::UnitTypePercentage) { |
178 percentage = value; | 184 percentage = value; |
179 } else { | 185 } else { |
180 CSSPrimitiveValue::UnitType type = | 186 pixels += conversionData.zoomedComputedPixels(value, indexToUnitType(i)); |
181 CSSPrimitiveValue::lengthUnitTypeToUnitType( | |
182 static_cast<CSSPrimitiveValue::LengthUnitType>(i)); | |
183 pixels += conversionData.zoomedComputedPixels(value, type); | |
184 } | 187 } |
185 } | 188 } |
186 | 189 |
187 if (percentage != 0) | 190 if (percentage != 0) |
188 hasPercentage = true; | 191 hasPercentage = true; |
189 if (pixels != 0 && hasPercentage) | 192 if (pixels != 0 && hasPercentage) |
190 return Length( | 193 return Length( |
191 CalculationValue::create(PixelsAndPercent(pixels, percentage), range)); | 194 CalculationValue::create(PixelsAndPercent(pixels, percentage), range)); |
192 if (hasPercentage) | 195 if (hasPercentage) |
193 return Length(clampToRange(percentage, range), Percent); | 196 return Length(clampToRange(percentage, range), Percent); |
194 return Length( | 197 return Length( |
195 CSSPrimitiveValue::clampToCSSLengthRange(clampToRange(pixels, range)), | 198 CSSPrimitiveValue::clampToCSSLengthRange(clampToRange(pixels, range)), |
196 Fixed); | 199 Fixed); |
197 } | 200 } |
198 | 201 |
| 202 const CSSValue* LengthInterpolationFunctions::createCSSValue( |
| 203 const InterpolableValue& interpolableValue, |
| 204 const NonInterpolableValue* nonInterpolableValue, |
| 205 ValueRange range) { |
| 206 const InterpolableList& interpolableList = |
| 207 toInterpolableList(interpolableValue); |
| 208 bool hasPercentage = |
| 209 CSSLengthNonInterpolableValue::hasPercentage(nonInterpolableValue); |
| 210 |
| 211 CSSCalcExpressionNode* rootNode = nullptr; |
| 212 CSSPrimitiveValue* firstValue = nullptr; |
| 213 |
| 214 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { |
| 215 double value = toInterpolableNumber(*interpolableList.get(i)).value(); |
| 216 if (value == 0 || |
| 217 (i == CSSPrimitiveValue::UnitTypePercentage && !hasPercentage)) { |
| 218 continue; |
| 219 } |
| 220 CSSPrimitiveValue* currentValue = |
| 221 CSSPrimitiveValue::create(value, indexToUnitType(i)); |
| 222 |
| 223 if (!firstValue) { |
| 224 DCHECK(!rootNode); |
| 225 firstValue = currentValue; |
| 226 continue; |
| 227 } |
| 228 CSSCalcExpressionNode* currentNode = |
| 229 CSSCalcValue::createExpressionNode(currentValue); |
| 230 if (!rootNode) { |
| 231 rootNode = CSSCalcValue::createExpressionNode(firstValue); |
| 232 } |
| 233 rootNode = |
| 234 CSSCalcValue::createExpressionNode(rootNode, currentNode, CalcAdd); |
| 235 } |
| 236 |
| 237 if (rootNode) { |
| 238 return CSSPrimitiveValue::create(CSSCalcValue::create(rootNode)); |
| 239 } |
| 240 if (firstValue) { |
| 241 return firstValue; |
| 242 } |
| 243 return CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::Pixels); |
| 244 } |
| 245 |
199 } // namespace blink | 246 } // namespace blink |
OLD | NEW |