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

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

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

Powered by Google App Engine
This is Rietveld 408576698