Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: third_party/WebKit/Source/core/animation/LengthSVGInterpolation.cpp

Issue 1535523002: Web Animations: Add SVGLengthListInterpolationType (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/animation/LengthSVGInterpolation.h"
7
8 #include "core/css/CSSHelper.h"
9 #include "core/svg/SVGAnimatedLength.h"
10 #include "core/svg/SVGAnimatedLengthList.h"
11 #include "core/svg/SVGElement.h"
12 #include "core/svg/SVGLengthContext.h"
13 #include "wtf/StdLibExtras.h"
14
15 namespace blink {
16
17 PassRefPtrWillBeRawPtr<SVGLengthList> LengthSVGInterpolation::createList(const S VGAnimatedPropertyBase& attribute)
18 {
19 ASSERT(attribute.type() == AnimatedLengthList);
20 const SVGAnimatedLengthList& animatedLengthList = static_cast<const SVGAnima tedLengthList&>(attribute);
21 return SVGLengthList::create(animatedLengthList.currentValue()->unitMode());
22 }
23
24 PassRefPtr<LengthSVGInterpolation> LengthSVGInterpolation::create(SVGPropertyBas e* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute)
25 {
26 NonInterpolableType modeData;
27 OwnPtr<InterpolableValue> startValue = toInterpolableValue(toSVGLength(start ), attribute.get(), &modeData);
28 OwnPtr<InterpolableValue> endValue = toInterpolableValue(toSVGLength(end), a ttribute.get(), nullptr);
29 return adoptRef(new LengthSVGInterpolation(startValue.release(), endValue.re lease(), attribute, modeData));
30 }
31
32 namespace {
33
34 void populateModeData(const SVGAnimatedPropertyBase* attribute, LengthSVGInterpo lation::NonInterpolableType* ptrModeData)
35 {
36 switch (attribute->type()) {
37 case AnimatedLength: {
38 const SVGAnimatedLength& animatedLength = static_cast<const SVGAnimatedL ength&>(*attribute);
39 ptrModeData->unitMode = animatedLength.currentValue()->unitMode();
40 break;
41 }
42 case AnimatedLengthList: {
43 const SVGAnimatedLengthList& animatedLengthList = static_cast<const SVGA nimatedLengthList&>(*attribute);
44 ptrModeData->unitMode = animatedLengthList.currentValue()->unitMode();
45 break;
46 }
47 default:
48 ASSERT_NOT_REACHED();
49 }
50 }
51
52 enum LengthInterpolatedUnit {
53 LengthInterpolatedNumber,
54 LengthInterpolatedPercentage,
55 LengthInterpolatedEMS,
56 LengthInterpolatedEXS,
57 LengthInterpolatedREMS,
58 LengthInterpolatedCHS,
59 };
60
61 static const CSSPrimitiveValue::UnitType unitTypes[] = {
62 CSSPrimitiveValue::UnitType::UserUnits,
63 CSSPrimitiveValue::UnitType::Percentage,
64 CSSPrimitiveValue::UnitType::Ems,
65 CSSPrimitiveValue::UnitType::Exs,
66 CSSPrimitiveValue::UnitType::Rems,
67 CSSPrimitiveValue::UnitType::Chs
68 };
69
70 const size_t numLengthInterpolatedUnits = WTF_ARRAY_LENGTH(unitTypes);
71
72 LengthInterpolatedUnit convertToInterpolatedUnit(CSSPrimitiveValue::UnitType uni tType, double& value)
73 {
74 switch (unitType) {
75 case CSSPrimitiveValue::UnitType::Unknown:
76 default:
77 ASSERT_NOT_REACHED();
78 case CSSPrimitiveValue::UnitType::Pixels:
79 case CSSPrimitiveValue::UnitType::Number:
80 return LengthInterpolatedNumber;
81 case CSSPrimitiveValue::UnitType::Percentage:
82 return LengthInterpolatedPercentage;
83 case CSSPrimitiveValue::UnitType::Ems:
84 return LengthInterpolatedEMS;
85 case CSSPrimitiveValue::UnitType::Exs:
86 return LengthInterpolatedEXS;
87 case CSSPrimitiveValue::UnitType::Centimeters:
88 value *= cssPixelsPerCentimeter;
89 return LengthInterpolatedNumber;
90 case CSSPrimitiveValue::UnitType::Millimeters:
91 value *= cssPixelsPerMillimeter;
92 return LengthInterpolatedNumber;
93 case CSSPrimitiveValue::UnitType::Inches:
94 value *= cssPixelsPerInch;
95 return LengthInterpolatedNumber;
96 case CSSPrimitiveValue::UnitType::Points:
97 value *= cssPixelsPerPoint;
98 return LengthInterpolatedNumber;
99 case CSSPrimitiveValue::UnitType::Picas:
100 value *= cssPixelsPerPica;
101 return LengthInterpolatedNumber;
102 case CSSPrimitiveValue::UnitType::UserUnits:
103 return LengthInterpolatedNumber;
104 case CSSPrimitiveValue::UnitType::Rems:
105 return LengthInterpolatedREMS;
106 case CSSPrimitiveValue::UnitType::Chs:
107 return LengthInterpolatedCHS;
108 }
109 }
110
111 } // namespace
112
113 PassOwnPtr<InterpolableValue> LengthSVGInterpolation::toInterpolableValue(SVGLen gth* length, const SVGAnimatedPropertyBase* attribute, NonInterpolableType* ptrM odeData)
114 {
115 if (ptrModeData)
116 populateModeData(attribute, ptrModeData);
117
118 double value = length->valueInSpecifiedUnits();
119 LengthInterpolatedUnit unitType = convertToInterpolatedUnit(length->typeWith CalcResolved(), value);
120
121 double values[numLengthInterpolatedUnits] = { };
122 values[unitType] = value;
123
124 OwnPtr<InterpolableList> listOfValues = InterpolableList::create(numLengthIn terpolatedUnits);
125 for (size_t i = 0; i < numLengthInterpolatedUnits; ++i)
126 listOfValues->set(i, InterpolableNumber::create(values[i]));
127 return listOfValues.release();
128 }
129
130 PassRefPtrWillBeRawPtr<SVGLength> LengthSVGInterpolation::fromInterpolableValue( const InterpolableValue& interpolableValue, const NonInterpolableType& modeData, const SVGElement* element, const QualifiedName& attributeName)
131 {
132 const InterpolableList& listOfValues = toInterpolableList(interpolableValue) ;
133 ASSERT(element);
134
135 double value = 0;
136 CSSPrimitiveValue::UnitType unitType = CSSPrimitiveValue::UnitType::UserUnit s;
137 unsigned unitTypeCount = 0;
138 // We optimise for the common case where only one unit type is involved.
139 for (size_t i = 0; i < numLengthInterpolatedUnits; i++) {
140 double entry = toInterpolableNumber(listOfValues.get(i))->value();
141 if (!entry)
142 continue;
143 unitTypeCount++;
144 if (unitTypeCount > 1)
145 break;
146
147 value = entry;
148 unitType = unitTypes[i];
149 }
150
151 if (unitTypeCount > 1) {
152 value = 0;
153 unitType = CSSPrimitiveValue::UnitType::UserUnits;
154
155 // SVGLength does not support calc expressions, so we convert to canonic al units.
156 SVGLengthContext lengthContext(element);
157 for (size_t i = 0; i < numLengthInterpolatedUnits; i++) {
158 double entry = toInterpolableNumber(listOfValues.get(i))->value();
159 if (entry)
160 value += lengthContext.convertValueToUserUnits(entry, modeData.u nitMode, unitTypes[i]);
161 }
162 }
163
164 if (SVGLength::negativeValuesForbiddenForAnimatedLengthAttribute(attributeNa me) && value < 0)
165 value = 0;
166
167 RefPtrWillBeRawPtr<SVGLength> result = SVGLength::create(modeData.unitMode); // defaults to the length 0
168 result->newValueSpecifiedUnits(unitType, value);
169 return result.release();
170 }
171
172 PassRefPtrWillBeRawPtr<SVGPropertyBase> LengthSVGInterpolation::interpolatedValu e(SVGElement& targetElement) const
173 {
174 return fromInterpolableValue(*m_cachedValue, m_modeData, &targetElement, att ributeName());
175 }
176
177 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698