| 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 |