| 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 == UnitTypeLength) |
| 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 UnitTypeLength; |
| 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: | |
| 217 return CSSPrimitiveValue::CSS_NUMBER; | |
| 218 case UnitTypeLength: | 191 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 |