OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/animation/SVGLengthInterpolationType.h" | 5 #include "core/animation/SVGLengthInterpolationType.h" |
6 | 6 |
7 #include "core/animation/InterpolationEnvironment.h" | 7 #include "core/animation/InterpolationEnvironment.h" |
8 #include "core/animation/StringKeyframe.h" | 8 #include "core/animation/StringKeyframe.h" |
9 #include "core/css/CSSHelper.h" | 9 #include "core/css/CSSHelper.h" |
10 #include "core/svg/SVGElement.h" | 10 #include "core/svg/SVGElement.h" |
11 #include "core/svg/SVGLength.h" | 11 #include "core/svg/SVGLength.h" |
12 #include "core/svg/SVGLengthContext.h" | 12 #include "core/svg/SVGLengthContext.h" |
13 #include <memory> | 13 #include <memory> |
14 | 14 |
15 namespace blink { | 15 namespace blink { |
16 | 16 |
17 namespace { | |
18 | |
19 enum LengthInterpolatedUnit { | |
20 LengthInterpolatedNumber, | |
21 LengthInterpolatedPercentage, | |
22 LengthInterpolatedEMS, | |
23 LengthInterpolatedEXS, | |
24 LengthInterpolatedREMS, | |
25 LengthInterpolatedCHS, | |
26 LengthInterpolatedViewportWidth, | |
27 LengthInterpolatedViewportHeight, | |
28 LengthInterpolatedViewportMin, | |
29 LengthInterpolatedViewportMax, | |
30 }; | |
31 | |
32 static const CSSPrimitiveValue::UnitType unitTypes[] = { | |
33 CSSPrimitiveValue::UnitType::UserUnits, | |
34 CSSPrimitiveValue::UnitType::Percentage, | |
35 CSSPrimitiveValue::UnitType::Ems, | |
36 CSSPrimitiveValue::UnitType::Exs, | |
37 CSSPrimitiveValue::UnitType::Rems, | |
38 CSSPrimitiveValue::UnitType::Chs, | |
39 CSSPrimitiveValue::UnitType::ViewportWidth, | |
40 CSSPrimitiveValue::UnitType::ViewportHeight, | |
41 CSSPrimitiveValue::UnitType::ViewportMin, | |
42 CSSPrimitiveValue::UnitType::ViewportMax, | |
43 }; | |
44 | |
45 const size_t numLengthInterpolatedUnits = WTF_ARRAY_LENGTH(unitTypes); | |
46 | |
47 LengthInterpolatedUnit convertToInterpolatedUnit(CSSPrimitiveValue::UnitType uni
tType, double& value) | |
48 { | |
49 switch (unitType) { | |
50 case CSSPrimitiveValue::UnitType::Unknown: | |
51 default: | |
52 NOTREACHED(); | |
53 case CSSPrimitiveValue::UnitType::Pixels: | |
54 case CSSPrimitiveValue::UnitType::Number: | |
55 case CSSPrimitiveValue::UnitType::UserUnits: | |
56 return LengthInterpolatedNumber; | |
57 case CSSPrimitiveValue::UnitType::Percentage: | |
58 return LengthInterpolatedPercentage; | |
59 case CSSPrimitiveValue::UnitType::Ems: | |
60 return LengthInterpolatedEMS; | |
61 case CSSPrimitiveValue::UnitType::Exs: | |
62 return LengthInterpolatedEXS; | |
63 case CSSPrimitiveValue::UnitType::Centimeters: | |
64 value *= cssPixelsPerCentimeter; | |
65 return LengthInterpolatedNumber; | |
66 case CSSPrimitiveValue::UnitType::Millimeters: | |
67 value *= cssPixelsPerMillimeter; | |
68 return LengthInterpolatedNumber; | |
69 case CSSPrimitiveValue::UnitType::Inches: | |
70 value *= cssPixelsPerInch; | |
71 return LengthInterpolatedNumber; | |
72 case CSSPrimitiveValue::UnitType::Points: | |
73 value *= cssPixelsPerPoint; | |
74 return LengthInterpolatedNumber; | |
75 case CSSPrimitiveValue::UnitType::Picas: | |
76 value *= cssPixelsPerPica; | |
77 return LengthInterpolatedNumber; | |
78 case CSSPrimitiveValue::UnitType::Rems: | |
79 return LengthInterpolatedREMS; | |
80 case CSSPrimitiveValue::UnitType::Chs: | |
81 return LengthInterpolatedCHS; | |
82 case CSSPrimitiveValue::UnitType::ViewportWidth: | |
83 return LengthInterpolatedViewportWidth; | |
84 case CSSPrimitiveValue::UnitType::ViewportHeight: | |
85 return LengthInterpolatedViewportHeight; | |
86 case CSSPrimitiveValue::UnitType::ViewportMin: | |
87 return LengthInterpolatedViewportMin; | |
88 case CSSPrimitiveValue::UnitType::ViewportMax: | |
89 return LengthInterpolatedViewportMax; | |
90 } | |
91 } | |
92 | |
93 } // namespace | |
94 | |
95 std::unique_ptr<InterpolableValue> SVGLengthInterpolationType::neutralInterpolab
leValue() | 17 std::unique_ptr<InterpolableValue> SVGLengthInterpolationType::neutralInterpolab
leValue() |
96 { | 18 { |
97 std::unique_ptr<InterpolableList> listOfValues = InterpolableList::create(nu
mLengthInterpolatedUnits); | 19 std::unique_ptr<InterpolableList> listOfValues = InterpolableList::create(CS
SPrimitiveValue::LengthUnitTypeCount); |
98 for (size_t i = 0; i < numLengthInterpolatedUnits; ++i) | 20 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i) |
99 listOfValues->set(i, InterpolableNumber::create(0)); | 21 listOfValues->set(i, InterpolableNumber::create(0)); |
100 | 22 |
101 return std::move(listOfValues); | 23 return std::move(listOfValues); |
102 } | 24 } |
103 | 25 |
104 InterpolationValue SVGLengthInterpolationType::convertSVGLength(const SVGLength&
length) | 26 InterpolationValue SVGLengthInterpolationType::convertSVGLength(const SVGLength&
length) |
105 { | 27 { |
106 double value = length.valueInSpecifiedUnits(); | 28 const CSSPrimitiveValue* primitiveValue = length.asCSSPrimitiveValue(); |
107 LengthInterpolatedUnit unitType = convertToInterpolatedUnit(length.typeWithC
alcResolved(), value); | |
108 | 29 |
109 double values[numLengthInterpolatedUnits] = { }; | 30 CSSLengthArray lengthArray; |
110 values[unitType] = value; | 31 primitiveValue->accumulateLengthArray(lengthArray); |
111 | 32 |
112 std::unique_ptr<InterpolableList> listOfValues = InterpolableList::create(nu
mLengthInterpolatedUnits); | 33 std::unique_ptr<InterpolableList> listOfValues = InterpolableList::create(CS
SPrimitiveValue::LengthUnitTypeCount); |
113 for (size_t i = 0; i < numLengthInterpolatedUnits; ++i) | 34 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i) |
114 listOfValues->set(i, InterpolableNumber::create(values[i])); | 35 listOfValues->set(i, InterpolableNumber::create(lengthArray.values[i])); |
115 | 36 |
116 return InterpolationValue(std::move(listOfValues)); | 37 return InterpolationValue(std::move(listOfValues)); |
117 } | 38 } |
118 | 39 |
119 SVGLength* SVGLengthInterpolationType::resolveInterpolableSVGLength(const Interp
olableValue& interpolableValue, const SVGLengthContext& lengthContext, SVGLength
Mode unitMode, bool negativeValuesForbidden) | 40 SVGLength* SVGLengthInterpolationType::resolveInterpolableSVGLength(const Interp
olableValue& interpolableValue, const SVGLengthContext& lengthContext, SVGLength
Mode unitMode, bool negativeValuesForbidden) |
120 { | 41 { |
121 const InterpolableList& listOfValues = toInterpolableList(interpolableValue)
; | 42 const InterpolableList& listOfValues = toInterpolableList(interpolableValue)
; |
122 | 43 |
123 double value = 0; | 44 double value = 0; |
124 CSSPrimitiveValue::UnitType unitType = CSSPrimitiveValue::UnitType::UserUnit
s; | 45 CSSPrimitiveValue::UnitType unitType = CSSPrimitiveValue::UnitType::UserUnit
s; |
125 unsigned unitTypeCount = 0; | 46 unsigned unitTypeCount = 0; |
126 // We optimise for the common case where only one unit type is involved. | 47 // We optimise for the common case where only one unit type is involved. |
127 for (size_t i = 0; i < numLengthInterpolatedUnits; i++) { | 48 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { |
128 double entry = toInterpolableNumber(listOfValues.get(i))->value(); | 49 double entry = toInterpolableNumber(listOfValues.get(i))->value(); |
129 if (!entry) | 50 if (!entry) |
130 continue; | 51 continue; |
131 unitTypeCount++; | 52 unitTypeCount++; |
132 if (unitTypeCount > 1) | 53 if (unitTypeCount > 1) |
133 break; | 54 break; |
134 | 55 |
135 value = entry; | 56 value = entry; |
136 unitType = unitTypes[i]; | 57 unitType = CSSPrimitiveValue::lengthUnitTypeToUnitType(static_cast<CSSPr
imitiveValue::LengthUnitType>(i)); |
137 } | 58 } |
138 | 59 |
139 if (unitTypeCount > 1) { | 60 if (unitTypeCount > 1) { |
140 value = 0; | 61 value = 0; |
141 unitType = CSSPrimitiveValue::UnitType::UserUnits; | 62 unitType = CSSPrimitiveValue::UnitType::UserUnits; |
142 | 63 |
143 // SVGLength does not support calc expressions, so we convert to canonic
al units. | 64 // SVGLength does not support calc expressions, so we convert to canonic
al units. |
144 for (size_t i = 0; i < numLengthInterpolatedUnits; i++) { | 65 for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) { |
145 double entry = toInterpolableNumber(listOfValues.get(i))->value(); | 66 double entry = toInterpolableNumber(listOfValues.get(i))->value(); |
146 if (entry) | 67 if (entry) |
147 value += lengthContext.convertValueToUserUnits(entry, unitMode,
unitTypes[i]); | 68 value += lengthContext.convertValueToUserUnits(entry, unitMode,
CSSPrimitiveValue::lengthUnitTypeToUnitType(static_cast<CSSPrimitiveValue::Lengt
hUnitType>(i))); |
148 } | 69 } |
149 } | 70 } |
150 | 71 |
151 if (negativeValuesForbidden && value < 0) | 72 if (negativeValuesForbidden && value < 0) |
152 value = 0; | 73 value = 0; |
153 | 74 |
154 SVGLength* result = SVGLength::create(unitMode); // defaults to the length 0 | 75 SVGLength* result = SVGLength::create(unitMode); // defaults to the length 0 |
155 result->newValueSpecifiedUnits(unitType, value); | 76 result->newValueSpecifiedUnits(unitType, value); |
156 return result; | 77 return result; |
157 } | 78 } |
(...skipping 19 matching lines...) Expand all Loading... |
177 } | 98 } |
178 | 99 |
179 void SVGLengthInterpolationType::apply(const InterpolableValue& interpolableValu
e, const NonInterpolableValue* nonInterpolableValue, InterpolationEnvironment& e
nvironment) const | 100 void SVGLengthInterpolationType::apply(const InterpolableValue& interpolableValu
e, const NonInterpolableValue* nonInterpolableValue, InterpolationEnvironment& e
nvironment) const |
180 { | 101 { |
181 SVGElement& element = environment.svgElement(); | 102 SVGElement& element = environment.svgElement(); |
182 SVGLengthContext lengthContext(&element); | 103 SVGLengthContext lengthContext(&element); |
183 element.setWebAnimatedAttribute(attribute(), resolveInterpolableSVGLength(in
terpolableValue, lengthContext, m_unitMode, m_negativeValuesForbidden)); | 104 element.setWebAnimatedAttribute(attribute(), resolveInterpolableSVGLength(in
terpolableValue, lengthContext, m_unitMode, m_negativeValuesForbidden)); |
184 } | 105 } |
185 | 106 |
186 } // namespace blink | 107 } // namespace blink |
OLD | NEW |