| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 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. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 #include "core/animation/AnimatableNumber.h" | |
| 33 | |
| 34 #include "core/css/CSSPrimitiveValueMappings.h" | |
| 35 #include "core/platform/CalculationValue.h" | |
| 36 #include "core/platform/Length.h" | |
| 37 #include "wtf/MathExtras.h" | |
| 38 | |
| 39 namespace WebCore { | |
| 40 | |
| 41 PassRefPtr<AnimatableNumber> AnimatableNumber::create(CSSValue* value) | |
| 42 { | |
| 43 ASSERT(canCreateFrom(value)); | |
| 44 if (value->isPrimitiveValue()) { | |
| 45 CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(value); | |
| 46 const CSSCalcValue* calcValue = primitiveValue->cssCalcValue(); | |
| 47 if (calcValue) | |
| 48 return create(calcValue->expressionNode(), primitiveValue); | |
| 49 NumberUnitType unitType = primitiveUnitToNumberType(primitiveValue->prim
itiveType()); | |
| 50 ASSERT(unitType != UnitTypeInvalid); | |
| 51 const double scale = CSSPrimitiveValue::conversionToCanonicalUnitsScaleF
actor(primitiveValue->primitiveType()); | |
| 52 return create(primitiveValue->getDoubleValue() * scale, unitType, primit
iveValue); | |
| 53 } | |
| 54 | |
| 55 if (value->isCalcValue()) | |
| 56 return create(toCSSCalcValue(value)->expressionNode()); | |
| 57 | |
| 58 ASSERT_NOT_REACHED(); | |
| 59 return 0; | |
| 60 } | |
| 61 | |
| 62 PassRefPtr<AnimatableNumber> AnimatableNumber::create(const AnimatableNumber* le
ftAddend, const AnimatableNumber* rightAddend) | |
| 63 { | |
| 64 ASSERT(leftAddend); | |
| 65 ASSERT(rightAddend); | |
| 66 | |
| 67 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); | |
| 69 return create(CSSCalcValue::createExpressionNode(leftAddend->toCSSCalcExpres
sionNode(), rightAddend->toCSSCalcExpressionNode(), CalcAdd)); | |
| 70 } | |
| 71 | |
| 72 bool AnimatableNumber::canCreateFrom(const CSSValue* value) | |
| 73 { | |
| 74 ASSERT(value); | |
| 75 if (value->isPrimitiveValue()) { | |
| 76 const CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(v
alue); | |
| 77 if (primitiveValue->cssCalcValue()) | |
| 78 return true; | |
| 79 return primitiveUnitToNumberType(primitiveValue->primitiveType()) != Uni
tTypeInvalid; | |
| 80 } | |
| 81 return value->isCalcValue(); | |
| 82 } | |
| 83 | |
| 84 PassRefPtr<CSSValue> AnimatableNumber::toCSSValue(NumberRange range) const | |
| 85 { | |
| 86 return toCSSPrimitiveValue(range); | |
| 87 } | |
| 88 | |
| 89 double AnimatableNumber::toDouble() 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 { | |
| 97 if (!m_isCalc) { | |
| 98 // Avoid creating a CSSValue in the common cases | |
| 99 if (m_unitType == UnitTypeLength) | |
| 100 return Length(clampedNumber(range) * zoom, Fixed); | |
| 101 if (m_unitType == UnitTypePercentage) | |
| 102 return Length(clampedNumber(range), Percent); | |
| 103 } | |
| 104 return toCSSPrimitiveValue(range)->convertToLength<AnyConversion>(style, roo
tStyle, zoom); | |
| 105 } | |
| 106 | |
| 107 PassRefPtr<AnimatableValue> AnimatableNumber::interpolateTo(const AnimatableValu
e* value, double fraction) const | |
| 108 { | |
| 109 const AnimatableNumber* number = toAnimatableNumber(value); | |
| 110 return AnimatableNumber::create(scale(1 - fraction).get(), number->scale(fra
ction).get()); | |
| 111 } | |
| 112 | |
| 113 PassRefPtr<AnimatableValue> AnimatableNumber::addWith(const AnimatableValue* val
ue) const | |
| 114 { | |
| 115 // Optimization for adding with 0. | |
| 116 if (!m_isCalc && !m_number) | |
| 117 return takeConstRef(value); | |
| 118 const AnimatableNumber* number = toAnimatableNumber(value); | |
| 119 if (!number->m_isCalc && !number->m_number) | |
| 120 return takeConstRef(this); | |
| 121 | |
| 122 return AnimatableNumber::create(this, number); | |
| 123 } | |
| 124 | |
| 125 PassRefPtr<CSSCalcExpressionNode> AnimatableNumber::toCSSCalcExpressionNode() co
nst | |
| 126 { | |
| 127 if (m_isCalc) | |
| 128 return m_calcExpression; | |
| 129 return CSSCalcValue::createExpressionNode(toCSSPrimitiveValue(AllValues), m_
number == trunc(m_number)); | |
| 130 } | |
| 131 | |
| 132 static bool isCompatibleWithRange(const CSSPrimitiveValue* primitiveValue, Numbe
rRange range) | |
| 133 { | |
| 134 ASSERT(primitiveValue); | |
| 135 if (range == AllValues) | |
| 136 return true; | |
| 137 if (primitiveValue->isCalculated()) | |
| 138 return primitiveValue->cssCalcValue()->permittedValueRange() == Calculat
ionRangeNonNegative; | |
| 139 return primitiveValue->getDoubleValue() >= 0; | |
| 140 } | |
| 141 | |
| 142 PassRefPtr<CSSPrimitiveValue> AnimatableNumber::toCSSPrimitiveValue(NumberRange
range) const | |
| 143 { | |
| 144 ASSERT(m_unitType != UnitTypeInvalid); | |
| 145 if (!m_cachedCSSPrimitiveValue || !isCompatibleWithRange(m_cachedCSSPrimitiv
eValue.get(), range)) { | |
| 146 if (m_isCalc) | |
| 147 m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(CSSCalcValue::
create(m_calcExpression, range == AllValues ? CalculationRangeAll : CalculationR
angeNonNegative)); | |
| 148 else | |
| 149 m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(clampedNumber(
range), static_cast<CSSPrimitiveValue::UnitTypes>(numberTypeToPrimitiveUnit(m_un
itType))); | |
| 150 } | |
| 151 return m_cachedCSSPrimitiveValue; | |
| 152 } | |
| 153 | |
| 154 PassRefPtr<AnimatableNumber> AnimatableNumber::scale(double factor) const | |
| 155 { | |
| 156 if (m_isCalc) { | |
| 157 return AnimatableNumber::create(CSSCalcValue::createExpressionNode( | |
| 158 m_calcExpression, | |
| 159 CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(factor,
CSSPrimitiveValue::CSS_NUMBER)), | |
| 160 CalcMultiply)); | |
| 161 } | |
| 162 return AnimatableNumber::create(m_number * factor, m_unitType); | |
| 163 } | |
| 164 | |
| 165 AnimatableNumber::NumberUnitType AnimatableNumber::primitiveUnitToNumberType(uns
igned short primitiveUnit) | |
| 166 { | |
| 167 switch (primitiveUnit) { | |
| 168 case CSSPrimitiveValue::CSS_NUMBER: | |
| 169 return UnitTypeNumber; | |
| 170 case CSSPrimitiveValue::CSS_PX: | |
| 171 case CSSPrimitiveValue::CSS_CM: | |
| 172 case CSSPrimitiveValue::CSS_MM: | |
| 173 case CSSPrimitiveValue::CSS_IN: | |
| 174 case CSSPrimitiveValue::CSS_PT: | |
| 175 case CSSPrimitiveValue::CSS_PC: | |
| 176 return UnitTypeLength; | |
| 177 case CSSPrimitiveValue::CSS_EMS: | |
| 178 return UnitTypeFontSize; | |
| 179 case CSSPrimitiveValue::CSS_EXS: | |
| 180 return UnitTypeFontXSize; | |
| 181 case CSSPrimitiveValue::CSS_REMS: | |
| 182 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: | |
| 189 return UnitTypePercentage; | |
| 190 case CSSPrimitiveValue::CSS_VW: | |
| 191 return UnitTypeViewportWidth; | |
| 192 case CSSPrimitiveValue::CSS_VH: | |
| 193 return UnitTypeViewportHeight; | |
| 194 case CSSPrimitiveValue::CSS_VMIN: | |
| 195 return UnitTypeViewportMin; | |
| 196 case CSSPrimitiveValue::CSS_VMAX: | |
| 197 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: | |
| 209 return UnitTypeInvalid; | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 unsigned short AnimatableNumber::numberTypeToPrimitiveUnit(NumberUnitType number
Type) | |
| 214 { | |
| 215 switch (numberType) { | |
| 216 case UnitTypeNumber: | |
| 217 return CSSPrimitiveValue::CSS_NUMBER; | |
| 218 case UnitTypeLength: | |
| 219 return CSSPrimitiveValue::CSS_PX; | |
| 220 case UnitTypeFontSize: | |
| 221 return CSSPrimitiveValue::CSS_EMS; | |
| 222 case UnitTypeFontXSize: | |
| 223 return CSSPrimitiveValue::CSS_EXS; | |
| 224 case UnitTypeRootFontSize: | |
| 225 return CSSPrimitiveValue::CSS_REMS; | |
| 226 case UnitTypePercentage: | |
| 227 return CSSPrimitiveValue::CSS_PERCENTAGE; | |
| 228 case UnitTypeViewportWidth: | |
| 229 return CSSPrimitiveValue::CSS_VW; | |
| 230 case UnitTypeViewportHeight: | |
| 231 return CSSPrimitiveValue::CSS_VH; | |
| 232 case UnitTypeViewportMin: | |
| 233 return CSSPrimitiveValue::CSS_VMIN; | |
| 234 case UnitTypeViewportMax: | |
| 235 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: | |
| 245 return CSSPrimitiveValue::CSS_UNKNOWN; | |
| 246 } | |
| 247 ASSERT_NOT_REACHED(); | |
| 248 return CSSPrimitiveValue::CSS_UNKNOWN; | |
| 249 } | |
| 250 | |
| 251 } // namespace WebCore | |
| OLD | NEW |