OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 11 matching lines...) Expand all Loading... |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "core/animation/AnimatableNumber.h" | 32 #include "core/animation/AnimatableLength.h" |
33 | 33 |
34 #include "core/css/CSSPrimitiveValueMappings.h" | 34 #include "core/css/CSSPrimitiveValueMappings.h" |
35 #include "core/platform/CalculationValue.h" | 35 #include "core/platform/CalculationValue.h" |
36 #include "core/platform/Length.h" | |
37 #include "wtf/MathExtras.h" | |
38 | 36 |
39 namespace WebCore { | 37 namespace WebCore { |
40 | 38 |
41 PassRefPtr<AnimatableNumber> AnimatableNumber::create(CSSValue* value) | 39 PassRefPtr<AnimatableLength> AnimatableLength::create(CSSValue* value) |
42 { | 40 { |
43 ASSERT(canCreateFrom(value)); | 41 ASSERT(canCreateFrom(value)); |
44 if (value->isPrimitiveValue()) { | 42 if (value->isPrimitiveValue()) { |
45 CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(value); | 43 CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(value); |
46 const CSSCalcValue* calcValue = primitiveValue->cssCalcValue(); | 44 const CSSCalcValue* calcValue = primitiveValue->cssCalcValue(); |
47 if (calcValue) | 45 if (calcValue) |
48 return create(calcValue->expressionNode(), primitiveValue); | 46 return create(calcValue->expressionNode(), primitiveValue); |
49 NumberUnitType unitType = primitiveUnitToNumberType(primitiveValue->prim
itiveType()); | 47 NumberUnitType unitType = primitiveUnitToNumberType(primitiveValue->prim
itiveType()); |
50 ASSERT(unitType != UnitTypeInvalid); | 48 ASSERT(unitType != UnitTypeInvalid); |
51 const double scale = CSSPrimitiveValue::conversionToCanonicalUnitsScaleF
actor(primitiveValue->primitiveType()); | 49 const double scale = CSSPrimitiveValue::conversionToCanonicalUnitsScaleF
actor(primitiveValue->primitiveType()); |
52 return create(primitiveValue->getDoubleValue() * scale, unitType, primit
iveValue); | 50 return create(primitiveValue->getDoubleValue() * scale, unitType, primit
iveValue); |
53 } | 51 } |
54 | 52 |
55 if (value->isCalcValue()) | 53 if (value->isCalcValue()) |
56 return create(toCSSCalcValue(value)->expressionNode()); | 54 return create(toCSSCalcValue(value)->expressionNode()); |
57 | 55 |
58 ASSERT_NOT_REACHED(); | 56 ASSERT_NOT_REACHED(); |
59 return 0; | 57 return 0; |
60 } | 58 } |
61 | 59 |
62 PassRefPtr<AnimatableNumber> AnimatableNumber::create(const AnimatableNumber* le
ftAddend, const AnimatableNumber* rightAddend) | 60 PassRefPtr<AnimatableLength> AnimatableLength::create(const AnimatableLength* le
ftAddend, const AnimatableLength* rightAddend) |
63 { | 61 { |
64 ASSERT(leftAddend); | 62 ASSERT(leftAddend); |
65 ASSERT(rightAddend); | 63 ASSERT(rightAddend); |
66 | 64 |
67 if (!leftAddend->m_isCalc && !rightAddend->m_isCalc && leftAddend->m_unitTyp
e == rightAddend->m_unitType) | 65 if (!leftAddend->m_isCalc && !rightAddend->m_isCalc && leftAddend->m_unitTyp
e == rightAddend->m_unitType) |
68 return create(leftAddend->m_number + rightAddend->m_number, leftAddend->
m_unitType); | 66 return create(leftAddend->m_number + rightAddend->m_number, leftAddend->
m_unitType); |
69 return create(CSSCalcValue::createExpressionNode(leftAddend->toCSSCalcExpres
sionNode(), rightAddend->toCSSCalcExpressionNode(), CalcAdd)); | 67 return create(CSSCalcValue::createExpressionNode(leftAddend->toCSSCalcExpres
sionNode(), rightAddend->toCSSCalcExpressionNode(), CalcAdd)); |
70 } | 68 } |
71 | 69 |
72 bool AnimatableNumber::canCreateFrom(const CSSValue* value) | 70 bool AnimatableLength::canCreateFrom(const CSSValue* value) |
73 { | 71 { |
74 ASSERT(value); | 72 ASSERT(value); |
75 if (value->isPrimitiveValue()) { | 73 if (value->isPrimitiveValue()) { |
76 const CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(v
alue); | 74 const CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(v
alue); |
77 if (primitiveValue->cssCalcValue()) | 75 if (primitiveValue->cssCalcValue()) |
78 return true; | 76 return true; |
79 return primitiveUnitToNumberType(primitiveValue->primitiveType()) != Uni
tTypeInvalid; | 77 return primitiveUnitToNumberType(primitiveValue->primitiveType()) != Uni
tTypeInvalid; |
80 } | 78 } |
81 return value->isCalcValue(); | 79 return value->isCalcValue(); |
82 } | 80 } |
83 | 81 |
84 PassRefPtr<CSSValue> AnimatableNumber::toCSSValue(NumberRange range) const | 82 PassRefPtr<CSSValue> AnimatableLength::toCSSValue(NumberRange range) const |
85 { | 83 { |
86 return toCSSPrimitiveValue(range); | 84 return toCSSPrimitiveValue(range); |
87 } | 85 } |
88 | 86 |
89 double AnimatableNumber::toDouble() const | 87 Length AnimatableLength::toLength(const RenderStyle* style, const RenderStyle* r
ootStyle, double zoom, NumberRange range) const |
90 { | |
91 ASSERT(m_unitType == UnitTypeNumber); | |
92 return m_number; | |
93 } | |
94 | |
95 Length AnimatableNumber::toLength(const RenderStyle* style, const RenderStyle* r
ootStyle, double zoom, NumberRange range) const | |
96 { | 88 { |
97 if (!m_isCalc) { | 89 if (!m_isCalc) { |
98 // Avoid creating a CSSValue in the common cases | 90 // Avoid creating a CSSValue in the common cases |
99 if (m_unitType == UnitTypeLength) | 91 if (m_unitType == UnitTypePixels) |
100 return Length(clampedNumber(range) * zoom, Fixed); | 92 return Length(clampedNumber(range) * zoom, Fixed); |
101 if (m_unitType == UnitTypePercentage) | 93 if (m_unitType == UnitTypePercentage) |
102 return Length(clampedNumber(range), Percent); | 94 return Length(clampedNumber(range), Percent); |
103 } | 95 } |
104 return toCSSPrimitiveValue(range)->convertToLength<AnyConversion>(style, roo
tStyle, zoom); | 96 return toCSSPrimitiveValue(range)->convertToLength<AnyConversion>(style, roo
tStyle, zoom); |
105 } | 97 } |
106 | 98 |
107 PassRefPtr<AnimatableValue> AnimatableNumber::interpolateTo(const AnimatableValu
e* value, double fraction) const | 99 PassRefPtr<AnimatableValue> AnimatableLength::interpolateTo(const AnimatableValu
e* value, double fraction) const |
108 { | 100 { |
109 const AnimatableNumber* number = toAnimatableNumber(value); | 101 const AnimatableLength* number = toAnimatableLength(value); |
110 return AnimatableNumber::create(scale(1 - fraction).get(), number->scale(fra
ction).get()); | 102 return AnimatableLength::create(scale(1 - fraction).get(), number->scale(fra
ction).get()); |
111 } | 103 } |
112 | 104 |
113 PassRefPtr<AnimatableValue> AnimatableNumber::addWith(const AnimatableValue* val
ue) const | 105 PassRefPtr<AnimatableValue> AnimatableLength::addWith(const AnimatableValue* val
ue) const |
114 { | 106 { |
115 // Optimization for adding with 0. | 107 // Optimization for adding with 0. |
116 if (!m_isCalc && !m_number) | 108 if (!m_isCalc && !m_number) |
117 return takeConstRef(value); | 109 return takeConstRef(value); |
118 const AnimatableNumber* number = toAnimatableNumber(value); | 110 const AnimatableLength* number = toAnimatableLength(value); |
119 if (!number->m_isCalc && !number->m_number) | 111 if (!number->m_isCalc && !number->m_number) |
120 return takeConstRef(this); | 112 return takeConstRef(this); |
121 | 113 |
122 return AnimatableNumber::create(this, number); | 114 return AnimatableLength::create(this, number); |
123 } | 115 } |
124 | 116 |
125 PassRefPtr<CSSCalcExpressionNode> AnimatableNumber::toCSSCalcExpressionNode() co
nst | 117 PassRefPtr<CSSCalcExpressionNode> AnimatableLength::toCSSCalcExpressionNode() co
nst |
126 { | 118 { |
127 if (m_isCalc) | 119 if (m_isCalc) |
128 return m_calcExpression; | 120 return m_calcExpression; |
129 return CSSCalcValue::createExpressionNode(toCSSPrimitiveValue(AllValues), m_
number == trunc(m_number)); | 121 return CSSCalcValue::createExpressionNode(toCSSPrimitiveValue(AllValues), m_
number == trunc(m_number)); |
130 } | 122 } |
131 | 123 |
132 static bool isCompatibleWithRange(const CSSPrimitiveValue* primitiveValue, Numbe
rRange range) | 124 static bool isCompatibleWithRange(const CSSPrimitiveValue* primitiveValue, Numbe
rRange range) |
133 { | 125 { |
134 ASSERT(primitiveValue); | 126 ASSERT(primitiveValue); |
135 if (range == AllValues) | 127 if (range == AllValues) |
136 return true; | 128 return true; |
137 if (primitiveValue->isCalculated()) | 129 if (primitiveValue->isCalculated()) |
138 return primitiveValue->cssCalcValue()->permittedValueRange() == Calculat
ionRangeNonNegative; | 130 return primitiveValue->cssCalcValue()->permittedValueRange() == Calculat
ionRangeNonNegative; |
139 return primitiveValue->getDoubleValue() >= 0; | 131 return primitiveValue->getDoubleValue() >= 0; |
140 } | 132 } |
141 | 133 |
142 PassRefPtr<CSSPrimitiveValue> AnimatableNumber::toCSSPrimitiveValue(NumberRange
range) const | 134 PassRefPtr<CSSPrimitiveValue> AnimatableLength::toCSSPrimitiveValue(NumberRange
range) const |
143 { | 135 { |
144 ASSERT(m_unitType != UnitTypeInvalid); | 136 ASSERT(m_unitType != UnitTypeInvalid); |
145 if (!m_cachedCSSPrimitiveValue || !isCompatibleWithRange(m_cachedCSSPrimitiv
eValue.get(), range)) { | 137 if (!m_cachedCSSPrimitiveValue || !isCompatibleWithRange(m_cachedCSSPrimitiv
eValue.get(), range)) { |
146 if (m_isCalc) | 138 if (m_isCalc) |
147 m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(CSSCalcValue::
create(m_calcExpression, range == AllValues ? CalculationRangeAll : CalculationR
angeNonNegative)); | 139 m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(CSSCalcValue::
create(m_calcExpression, range == AllValues ? CalculationRangeAll : CalculationR
angeNonNegative)); |
148 else | 140 else |
149 m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(clampedNumber(
range), static_cast<CSSPrimitiveValue::UnitTypes>(numberTypeToPrimitiveUnit(m_un
itType))); | 141 m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(clampedNumber(
range), static_cast<CSSPrimitiveValue::UnitTypes>(numberTypeToPrimitiveUnit(m_un
itType))); |
150 } | 142 } |
151 return m_cachedCSSPrimitiveValue; | 143 return m_cachedCSSPrimitiveValue; |
152 } | 144 } |
153 | 145 |
154 PassRefPtr<AnimatableNumber> AnimatableNumber::scale(double factor) const | 146 PassRefPtr<AnimatableLength> AnimatableLength::scale(double factor) const |
155 { | 147 { |
156 if (m_isCalc) { | 148 if (m_isCalc) { |
157 return AnimatableNumber::create(CSSCalcValue::createExpressionNode( | 149 return AnimatableLength::create(CSSCalcValue::createExpressionNode( |
158 m_calcExpression, | 150 m_calcExpression, |
159 CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(factor,
CSSPrimitiveValue::CSS_NUMBER)), | 151 CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(factor,
CSSPrimitiveValue::CSS_NUMBER)), |
160 CalcMultiply)); | 152 CalcMultiply)); |
161 } | 153 } |
162 return AnimatableNumber::create(m_number * factor, m_unitType); | 154 return AnimatableLength::create(m_number * factor, m_unitType); |
163 } | 155 } |
164 | 156 |
165 AnimatableNumber::NumberUnitType AnimatableNumber::primitiveUnitToNumberType(uns
igned short primitiveUnit) | 157 AnimatableLength::NumberUnitType AnimatableLength::primitiveUnitToNumberType(uns
igned short primitiveUnit) |
166 { | 158 { |
167 switch (primitiveUnit) { | 159 switch (primitiveUnit) { |
168 case CSSPrimitiveValue::CSS_NUMBER: | |
169 return UnitTypeNumber; | |
170 case CSSPrimitiveValue::CSS_PX: | 160 case CSSPrimitiveValue::CSS_PX: |
171 case CSSPrimitiveValue::CSS_CM: | 161 case CSSPrimitiveValue::CSS_CM: |
172 case CSSPrimitiveValue::CSS_MM: | 162 case CSSPrimitiveValue::CSS_MM: |
173 case CSSPrimitiveValue::CSS_IN: | 163 case CSSPrimitiveValue::CSS_IN: |
174 case CSSPrimitiveValue::CSS_PT: | 164 case CSSPrimitiveValue::CSS_PT: |
175 case CSSPrimitiveValue::CSS_PC: | 165 case CSSPrimitiveValue::CSS_PC: |
176 return UnitTypeLength; | 166 return UnitTypePixels; |
177 case CSSPrimitiveValue::CSS_EMS: | 167 case CSSPrimitiveValue::CSS_EMS: |
178 return UnitTypeFontSize; | 168 return UnitTypeFontSize; |
179 case CSSPrimitiveValue::CSS_EXS: | 169 case CSSPrimitiveValue::CSS_EXS: |
180 return UnitTypeFontXSize; | 170 return UnitTypeFontXSize; |
181 case CSSPrimitiveValue::CSS_REMS: | 171 case CSSPrimitiveValue::CSS_REMS: |
182 return UnitTypeRootFontSize; | 172 return UnitTypeRootFontSize; |
183 case CSSPrimitiveValue::CSS_DEG: | |
184 case CSSPrimitiveValue::CSS_RAD: | |
185 case CSSPrimitiveValue::CSS_GRAD: | |
186 case CSSPrimitiveValue::CSS_TURN: | |
187 return UnitTypeAngle; | |
188 case CSSPrimitiveValue::CSS_PERCENTAGE: | 173 case CSSPrimitiveValue::CSS_PERCENTAGE: |
189 return UnitTypePercentage; | 174 return UnitTypePercentage; |
190 case CSSPrimitiveValue::CSS_VW: | 175 case CSSPrimitiveValue::CSS_VW: |
191 return UnitTypeViewportWidth; | 176 return UnitTypeViewportWidth; |
192 case CSSPrimitiveValue::CSS_VH: | 177 case CSSPrimitiveValue::CSS_VH: |
193 return UnitTypeViewportHeight; | 178 return UnitTypeViewportHeight; |
194 case CSSPrimitiveValue::CSS_VMIN: | 179 case CSSPrimitiveValue::CSS_VMIN: |
195 return UnitTypeViewportMin; | 180 return UnitTypeViewportMin; |
196 case CSSPrimitiveValue::CSS_VMAX: | 181 case CSSPrimitiveValue::CSS_VMAX: |
197 return UnitTypeViewportMax; | 182 return UnitTypeViewportMax; |
198 case CSSPrimitiveValue::CSS_MS: | |
199 case CSSPrimitiveValue::CSS_S: | |
200 return UnitTypeTime; | |
201 case CSSPrimitiveValue::CSS_HZ: | |
202 case CSSPrimitiveValue::CSS_KHZ: | |
203 return UnitTypeFrequency; | |
204 case CSSPrimitiveValue::CSS_DPPX: | |
205 case CSSPrimitiveValue::CSS_DPI: | |
206 case CSSPrimitiveValue::CSS_DPCM: | |
207 return UnitTypeResolution; | |
208 default: | 183 default: |
209 return UnitTypeInvalid; | 184 return UnitTypeInvalid; |
210 } | 185 } |
211 } | 186 } |
212 | 187 |
213 unsigned short AnimatableNumber::numberTypeToPrimitiveUnit(NumberUnitType number
Type) | 188 unsigned short AnimatableLength::numberTypeToPrimitiveUnit(NumberUnitType number
Type) |
214 { | 189 { |
215 switch (numberType) { | 190 switch (numberType) { |
216 case UnitTypeNumber: | 191 case UnitTypePixels: |
217 return CSSPrimitiveValue::CSS_NUMBER; | |
218 case UnitTypeLength: | |
219 return CSSPrimitiveValue::CSS_PX; | 192 return CSSPrimitiveValue::CSS_PX; |
220 case UnitTypeFontSize: | 193 case UnitTypeFontSize: |
221 return CSSPrimitiveValue::CSS_EMS; | 194 return CSSPrimitiveValue::CSS_EMS; |
222 case UnitTypeFontXSize: | 195 case UnitTypeFontXSize: |
223 return CSSPrimitiveValue::CSS_EXS; | 196 return CSSPrimitiveValue::CSS_EXS; |
224 case UnitTypeRootFontSize: | 197 case UnitTypeRootFontSize: |
225 return CSSPrimitiveValue::CSS_REMS; | 198 return CSSPrimitiveValue::CSS_REMS; |
226 case UnitTypePercentage: | 199 case UnitTypePercentage: |
227 return CSSPrimitiveValue::CSS_PERCENTAGE; | 200 return CSSPrimitiveValue::CSS_PERCENTAGE; |
228 case UnitTypeViewportWidth: | 201 case UnitTypeViewportWidth: |
229 return CSSPrimitiveValue::CSS_VW; | 202 return CSSPrimitiveValue::CSS_VW; |
230 case UnitTypeViewportHeight: | 203 case UnitTypeViewportHeight: |
231 return CSSPrimitiveValue::CSS_VH; | 204 return CSSPrimitiveValue::CSS_VH; |
232 case UnitTypeViewportMin: | 205 case UnitTypeViewportMin: |
233 return CSSPrimitiveValue::CSS_VMIN; | 206 return CSSPrimitiveValue::CSS_VMIN; |
234 case UnitTypeViewportMax: | 207 case UnitTypeViewportMax: |
235 return CSSPrimitiveValue::CSS_VMAX; | 208 return CSSPrimitiveValue::CSS_VMAX; |
236 case UnitTypeTime: | |
237 return CSSPrimitiveValue::CSS_MS; | |
238 case UnitTypeAngle: | |
239 return CSSPrimitiveValue::CSS_DEG; | |
240 case UnitTypeFrequency: | |
241 return CSSPrimitiveValue::CSS_HZ; | |
242 case UnitTypeResolution: | |
243 return CSSPrimitiveValue::CSS_DPPX; | |
244 case UnitTypeInvalid: | 209 case UnitTypeInvalid: |
245 return CSSPrimitiveValue::CSS_UNKNOWN; | 210 return CSSPrimitiveValue::CSS_UNKNOWN; |
246 } | 211 } |
247 ASSERT_NOT_REACHED(); | 212 ASSERT_NOT_REACHED(); |
248 return CSSPrimitiveValue::CSS_UNKNOWN; | 213 return CSSPrimitiveValue::CSS_UNKNOWN; |
249 } | 214 } |
250 | 215 |
251 } // namespace WebCore | 216 } // namespace WebCore |
OLD | NEW |