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

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

Issue 1408143004: Use PathSegmentData+SVGPath{Consumer,Source} in PathSVGInterpolation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: InterpolatedPathSource Created 5 years, 2 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
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 "config.h" 5 #include "config.h"
6 #include "core/animation/PathSVGInterpolation.h" 6 #include "core/animation/PathSVGInterpolation.h"
7 7
8 #include "core/svg/SVGPathByteStreamBuilder.h"
9 #include "core/svg/SVGPathByteStreamSource.h"
8 #include "core/svg/SVGPathElement.h" 10 #include "core/svg/SVGPathElement.h"
9 #include "core/svg/SVGPathSegArcAbs.h" 11 #include "core/svg/SVGPathParser.h"
10 #include "core/svg/SVGPathSegArcRel.h"
11 #include "core/svg/SVGPathSegClosePath.h"
12 #include "core/svg/SVGPathSegCurvetoCubicAbs.h"
13 #include "core/svg/SVGPathSegCurvetoCubicRel.h"
14 #include "core/svg/SVGPathSegCurvetoCubicSmoothAbs.h"
15 #include "core/svg/SVGPathSegCurvetoCubicSmoothRel.h"
16 #include "core/svg/SVGPathSegCurvetoQuadraticAbs.h"
17 #include "core/svg/SVGPathSegCurvetoQuadraticRel.h"
18 #include "core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h"
19 #include "core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h"
20 #include "core/svg/SVGPathSegLinetoAbs.h"
21 #include "core/svg/SVGPathSegLinetoHorizontalAbs.h"
22 #include "core/svg/SVGPathSegLinetoHorizontalRel.h"
23 #include "core/svg/SVGPathSegLinetoRel.h"
24 #include "core/svg/SVGPathSegLinetoVerticalAbs.h"
25 #include "core/svg/SVGPathSegLinetoVerticalRel.h"
26 #include "core/svg/SVGPathSegMovetoAbs.h"
27 #include "core/svg/SVGPathSegMovetoRel.h"
28 12
29 namespace blink { 13 namespace blink {
30 14
31 namespace { 15 namespace {
32 16
33 struct SubPathCoordinates { 17 struct SubPathCoordinates {
34 double initialX = 0; 18 double initialX = 0;
35 double initialY = 0; 19 double initialY = 0;
36 double currentX = 0; 20 double currentX = 0;
37 double currentY = 0; 21 double currentY = 0;
38 }; 22 };
39 23
40 SVGPathSegType absolutePathSegType(const SVGPathSeg& item)
41 {
42 return toAbsolutePathSegType(static_cast<SVGPathSegType>(item.pathSegType()) );
43 }
44
45 bool isAbsolutePathSegType(const SVGPathSeg& item)
46 {
47 return isAbsolutePathSegType(static_cast<SVGPathSegType>(item.pathSegType()) );
48 }
49
50 PassOwnPtr<InterpolableNumber> controlToInterpolableValue(double value, bool isA bsolute, double currentValue) 24 PassOwnPtr<InterpolableNumber> controlToInterpolableValue(double value, bool isA bsolute, double currentValue)
51 { 25 {
52 if (isAbsolute) 26 if (isAbsolute)
53 return InterpolableNumber::create(value); 27 return InterpolableNumber::create(value);
54 return InterpolableNumber::create(currentValue + value); 28 return InterpolableNumber::create(currentValue + value);
55 } 29 }
56 30
57 double controlFromInterpolableValue(const InterpolableValue* number, bool isAbso lute, double currentValue) 31 double controlFromInterpolableValue(const InterpolableValue* number, bool isAbso lute, double currentValue)
58 { 32 {
59 double value = toInterpolableNumber(number)->value(); 33 double value = toInterpolableNumber(number)->value();
(...skipping 15 matching lines...) Expand all
75 double specifiedFromInterpolableValue(const InterpolableValue* number, bool isAb solute, double& currentValue) 49 double specifiedFromInterpolableValue(const InterpolableValue* number, bool isAb solute, double& currentValue)
76 { 50 {
77 double previousValue = currentValue; 51 double previousValue = currentValue;
78 currentValue = toInterpolableNumber(number)->value(); 52 currentValue = toInterpolableNumber(number)->value();
79 53
80 if (isAbsolute) 54 if (isAbsolute)
81 return currentValue; 55 return currentValue;
82 return currentValue - previousValue; 56 return currentValue - previousValue;
83 } 57 }
84 58
85 PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const SVGPathS eg& item, SubPathCoordinates& coordinates) 59 PassOwnPtr<InterpolableValue> pathSegClosePathToInterpolableValue(const PathSegm entData&, SubPathCoordinates& coordinates)
86 { 60 {
87 coordinates.currentX = coordinates.initialX; 61 coordinates.currentX = coordinates.initialX;
88 coordinates.currentY = coordinates.initialY; 62 coordinates.currentY = coordinates.initialY;
89 63
90 // arbitrary 64 // arbitrary
91 return InterpolableBool::create(false); 65 return InterpolableBool::create(false);
92 } 66 }
93 67
94 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegClosePathFromInterpolableValue(const I nterpolableValue&, SVGPathSegType, SubPathCoordinates& coordinates, SVGPathEleme nt* element) 68 PathSegmentData pathSegClosePathFromInterpolableValue(const InterpolableValue&, SVGPathSegType segType, SubPathCoordinates& coordinates)
95 { 69 {
96 coordinates.currentX = coordinates.initialX; 70 coordinates.currentX = coordinates.initialX;
97 coordinates.currentY = coordinates.initialY; 71 coordinates.currentY = coordinates.initialY;
98 72
99 return SVGPathSegClosePath::create(element); 73 PathSegmentData segment;
74 segment.command = segType;
75 return segment;
100 } 76 }
101 77
102 PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const S VGPathSegSingleCoordinate& item, SubPathCoordinates& coordinates) 78 PassOwnPtr<InterpolableValue> pathSegSingleCoordinateToInterpolableValue(const P athSegmentData& segment, SubPathCoordinates& coordinates)
103 { 79 {
104 bool isAbsolute = isAbsolutePathSegType(item); 80 bool isAbsolute = isAbsolutePathSegType(segment.command);
105 OwnPtr<InterpolableList> result = InterpolableList::create(2); 81 OwnPtr<InterpolableList> result = InterpolableList::create(2);
106 result->set(0, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); 82 result->set(0, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX));
107 result->set(1, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); 83 result->set(1, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY));
108 84
109 if (absolutePathSegType(item) == PathSegMoveToAbs) { 85 if (toAbsolutePathSegType(segment.command) == PathSegMoveToAbs) {
110 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to. 86 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to.
111 coordinates.initialX = coordinates.currentX; 87 coordinates.initialX = coordinates.currentX;
112 coordinates.initialY = coordinates.currentY; 88 coordinates.initialY = coordinates.currentY;
113 } 89 }
114 90
115 return result.release(); 91 return result.release();
116 } 92 }
117 93
118 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegSingleCoordinateFromInterpolableValue( const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coor dinates, SVGPathElement* element) 94 PathSegmentData pathSegSingleCoordinateFromInterpolableValue(const InterpolableV alue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
119 { 95 {
120 const InterpolableList& list = toInterpolableList(value); 96 const InterpolableList& list = toInterpolableList(value);
121 bool isAbsolute = isAbsolutePathSegType(segType); 97 bool isAbsolute = isAbsolutePathSegType(segType);
122 float x = specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinate s.currentX); 98 PathSegmentData segment;
123 float y = specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinate s.currentY); 99 segment.command = segType;
100 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(0), isAbsol ute, coordinates.currentX));
101 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(1), isAbsol ute, coordinates.currentY));
124 102
125 if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) { 103 if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) {
126 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to. 104 // Any upcoming 'closepath' commands bring us back to the location we ha ve just moved to.
127 coordinates.initialX = coordinates.currentX; 105 coordinates.initialX = coordinates.currentX;
128 coordinates.initialY = coordinates.currentY; 106 coordinates.initialY = coordinates.currentY;
129 } 107 }
130 108
131 switch (segType) { 109 return segment;
132 case PathSegMoveToAbs:
133 return SVGPathSegMovetoAbs::create(element, x, y);
134 case PathSegMoveToRel:
135 return SVGPathSegMovetoRel::create(element, x, y);
136 case PathSegLineToAbs:
137 return SVGPathSegLinetoAbs::create(element, x, y);
138 case PathSegLineToRel:
139 return SVGPathSegLinetoRel::create(element, x, y);
140 case PathSegCurveToQuadraticSmoothAbs:
141 return SVGPathSegCurvetoQuadraticSmoothAbs::create(element, x, y);
142 case PathSegCurveToQuadraticSmoothRel:
143 return SVGPathSegCurvetoQuadraticSmoothRel::create(element, x, y);
144 default:
145 ASSERT_NOT_REACHED();
146 return nullptr;
147 }
148 } 110 }
149 111
150 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicToInterpolableValue(const SVGPa thSegCurvetoCubic& item, SubPathCoordinates& coordinates) 112 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicToInterpolableValue(const PathS egmentData& segment, SubPathCoordinates& coordinates)
151 { 113 {
152 bool isAbsolute = isAbsolutePathSegType(item); 114 bool isAbsolute = isAbsolutePathSegType(segment.command);
153 OwnPtr<InterpolableList> result = InterpolableList::create(6); 115 OwnPtr<InterpolableList> result = InterpolableList::create(6);
154 result->set(0, controlToInterpolableValue(item.x1(), isAbsolute, coordinates .currentX)); 116 result->set(0, controlToInterpolableValue(segment.x1(), isAbsolute, coordina tes.currentX));
155 result->set(1, controlToInterpolableValue(item.y1(), isAbsolute, coordinates .currentY)); 117 result->set(1, controlToInterpolableValue(segment.y1(), isAbsolute, coordina tes.currentY));
156 result->set(2, controlToInterpolableValue(item.x2(), isAbsolute, coordinates .currentX)); 118 result->set(2, controlToInterpolableValue(segment.x2(), isAbsolute, coordina tes.currentX));
157 result->set(3, controlToInterpolableValue(item.y2(), isAbsolute, coordinates .currentY)); 119 result->set(3, controlToInterpolableValue(segment.y2(), isAbsolute, coordina tes.currentY));
158 result->set(4, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); 120 result->set(4, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX));
159 result->set(5, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); 121 result->set(5, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY));
160 return result.release(); 122 return result.release();
161 } 123 }
162 124
163 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoCubicFromInterpolableValue(cons t InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordina tes, SVGPathElement* element) 125 PathSegmentData pathSegCurvetoCubicFromInterpolableValue(const InterpolableValue & value, SVGPathSegType segType, SubPathCoordinates& coordinates)
164 { 126 {
165 const InterpolableList& list = toInterpolableList(value); 127 const InterpolableList& list = toInterpolableList(value);
166 bool isAbsolute = isAbsolutePathSegType(segType); 128 bool isAbsolute = isAbsolutePathSegType(segType);
167 float x1 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates .currentX); 129 PathSegmentData segment;
168 float y1 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates .currentY); 130 segment.command = segType;
169 float x2 = controlFromInterpolableValue(list.get(2), isAbsolute, coordinates .currentX); 131 segment.point1.setX(controlFromInterpolableValue(list.get(0), isAbsolute, co ordinates.currentX));
170 float y2 = controlFromInterpolableValue(list.get(3), isAbsolute, coordinates .currentY); 132 segment.point1.setY(controlFromInterpolableValue(list.get(1), isAbsolute, co ordinates.currentY));
171 float x = specifiedFromInterpolableValue(list.get(4), isAbsolute, coordinate s.currentX); 133 segment.point2.setX(controlFromInterpolableValue(list.get(2), isAbsolute, co ordinates.currentX));
172 float y = specifiedFromInterpolableValue(list.get(5), isAbsolute, coordinate s.currentY); 134 segment.point2.setY(controlFromInterpolableValue(list.get(3), isAbsolute, co ordinates.currentY));
173 135 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(4), isAbsol ute, coordinates.currentX));
174 switch (segType) { 136 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(5), isAbsol ute, coordinates.currentY));
175 case PathSegCurveToCubicAbs: 137 return segment;
176 return SVGPathSegCurvetoCubicAbs::create(element, x, y, x1, y1, x2, y2);
177 case PathSegCurveToCubicRel:
178 return SVGPathSegCurvetoCubicRel::create(element, x, y, x1, y1, x2, y2);
179 default:
180 ASSERT_NOT_REACHED();
181 return nullptr;
182 }
183 } 138 }
184 139
185 PassOwnPtr<InterpolableValue> pathSegCurvetoQuadraticToInterpolableValue(const S VGPathSegCurvetoQuadratic& item, SubPathCoordinates& coordinates) 140 PassOwnPtr<InterpolableValue> pathSegCurvetoQuadraticToInterpolableValue(const P athSegmentData& segment, SubPathCoordinates& coordinates)
186 { 141 {
187 bool isAbsolute = isAbsolutePathSegType(item); 142 bool isAbsolute = isAbsolutePathSegType(segment.command);
188 OwnPtr<InterpolableList> result = InterpolableList::create(4); 143 OwnPtr<InterpolableList> result = InterpolableList::create(4);
189 result->set(0, controlToInterpolableValue(item.x1(), isAbsolute, coordinates .currentX)); 144 result->set(0, controlToInterpolableValue(segment.x1(), isAbsolute, coordina tes.currentX));
190 result->set(1, controlToInterpolableValue(item.y1(), isAbsolute, coordinates .currentY)); 145 result->set(1, controlToInterpolableValue(segment.y1(), isAbsolute, coordina tes.currentY));
191 result->set(2, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); 146 result->set(2, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX));
192 result->set(3, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); 147 result->set(3, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY));
193 return result.release(); 148 return result.release();
194 } 149 }
195 150
196 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoQuadraticFromInterpolableValue( const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coor dinates, SVGPathElement* element) 151 PathSegmentData pathSegCurvetoQuadraticFromInterpolableValue(const InterpolableV alue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
197 { 152 {
198 const InterpolableList& list = toInterpolableList(value); 153 const InterpolableList& list = toInterpolableList(value);
199 bool isAbsolute = isAbsolutePathSegType(segType); 154 bool isAbsolute = isAbsolutePathSegType(segType);
200 float x1 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates .currentX); 155 PathSegmentData segment;
201 float y1 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates .currentY); 156 segment.command = segType;
202 float x = specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinate s.currentX); 157 segment.point1.setX(controlFromInterpolableValue(list.get(0), isAbsolute, co ordinates.currentX));
203 float y = specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinate s.currentY); 158 segment.point1.setY(controlFromInterpolableValue(list.get(1), isAbsolute, co ordinates.currentY));
204 switch (segType) { 159 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(2), isAbsol ute, coordinates.currentX));
205 case PathSegCurveToQuadraticAbs: 160 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(3), isAbsol ute, coordinates.currentY));
206 return SVGPathSegCurvetoQuadraticAbs::create(element, x, y, x1, y1); 161 return segment;
207 case PathSegCurveToQuadraticRel:
208 return SVGPathSegCurvetoQuadraticRel::create(element, x, y, x1, y1);
209 default:
210 ASSERT_NOT_REACHED();
211 return nullptr;
212 }
213 } 162 }
214 163
215 PassOwnPtr<InterpolableValue> pathSegArcToInterpolableValue(const SVGPathSegArc& item, SubPathCoordinates& coordinates) 164 PassOwnPtr<InterpolableValue> pathSegArcToInterpolableValue(const PathSegmentDat a& segment, SubPathCoordinates& coordinates)
216 { 165 {
217 bool isAbsolute = isAbsolutePathSegType(item); 166 bool isAbsolute = isAbsolutePathSegType(segment.command);
218 OwnPtr<InterpolableList> result = InterpolableList::create(7); 167 OwnPtr<InterpolableList> result = InterpolableList::create(7);
219 result->set(0, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); 168 result->set(0, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX));
220 result->set(1, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); 169 result->set(1, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY));
221 result->set(2, InterpolableNumber::create(item.r1())); 170 result->set(2, InterpolableNumber::create(segment.r1()));
222 result->set(3, InterpolableNumber::create(item.r2())); 171 result->set(3, InterpolableNumber::create(segment.r2()));
223 result->set(4, InterpolableNumber::create(item.angle())); 172 result->set(4, InterpolableNumber::create(segment.arcAngle()));
224 result->set(5, InterpolableBool::create(item.largeArcFlag())); 173 result->set(5, InterpolableBool::create(segment.largeArcFlag()));
225 result->set(6, InterpolableBool::create(item.sweepFlag())); 174 result->set(6, InterpolableBool::create(segment.sweepFlag()));
226 return result.release(); 175 return result.release();
227 } 176 }
228 177
229 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegArcFromInterpolableValue(const Interpo lableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGP athElement* element) 178 PathSegmentData pathSegArcFromInterpolableValue(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
230 { 179 {
231 const InterpolableList& list = toInterpolableList(value); 180 const InterpolableList& list = toInterpolableList(value);
232 bool isAbsolute = isAbsolutePathSegType(segType); 181 bool isAbsolute = isAbsolutePathSegType(segType);
233 float x = specifiedFromInterpolableValue(list.get(0), isAbsolute, coordinate s.currentX); 182 PathSegmentData segment;
234 float y = specifiedFromInterpolableValue(list.get(1), isAbsolute, coordinate s.currentY); 183 segment.command = segType;
235 float r1 = toInterpolableNumber(list.get(2))->value(); 184 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(0), isAbsol ute, coordinates.currentX));
236 float r2 = toInterpolableNumber(list.get(3))->value(); 185 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(1), isAbsol ute, coordinates.currentY));
237 float angle = toInterpolableNumber(list.get(4))->value(); 186 segment.point1.setX(toInterpolableNumber(list.get(2))->value());
238 bool largeArcFlag = toInterpolableBool(list.get(5))->value(); 187 segment.point1.setY(toInterpolableNumber(list.get(3))->value());
239 bool sweepFlag = toInterpolableBool(list.get(6))->value(); 188 segment.point2.setX(toInterpolableNumber(list.get(4))->value());
240 switch (segType) { 189 segment.arcLarge = toInterpolableBool(list.get(5))->value();
241 case PathSegArcAbs: 190 segment.arcSweep = toInterpolableBool(list.get(6))->value();
242 return SVGPathSegArcAbs::create(element, x, y, r1, r2, angle, largeArcFl ag, sweepFlag); 191 return segment;
243 case PathSegArcRel:
244 return SVGPathSegArcRel::create(element, x, y, r1, r2, angle, largeArcFl ag, sweepFlag);
245 default:
246 ASSERT_NOT_REACHED();
247 return nullptr;
248 }
249 } 192 }
250 193
251 PassOwnPtr<InterpolableValue> pathSegLinetoHorizontalToInterpolableValue(const S VGPathSegLinetoHorizontal& item, SubPathCoordinates& coordinates) 194 PassOwnPtr<InterpolableValue> pathSegLinetoHorizontalToInterpolableValue(const P athSegmentData& segment, SubPathCoordinates& coordinates)
252 { 195 {
253 bool isAbsolute = isAbsolutePathSegType(item); 196 bool isAbsolute = isAbsolutePathSegType(segment.command);
254 return specifiedToInterpolableValue(item.x(), isAbsolute, coordinates.curren tX); 197 return specifiedToInterpolableValue(segment.x(), isAbsolute, coordinates.cur rentX);
255 } 198 }
256 199
257 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegLinetoHorizontalFromInterpolableValue( const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coor dinates, SVGPathElement* element) 200 PathSegmentData pathSegLinetoHorizontalFromInterpolableValue(const InterpolableV alue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
258 { 201 {
259 bool isAbsolute = isAbsolutePathSegType(segType); 202 bool isAbsolute = isAbsolutePathSegType(segType);
260 float x = specifiedFromInterpolableValue(&value, isAbsolute, coordinates.cur rentX); 203 PathSegmentData segment;
261 204 segment.command = segType;
262 switch (segType) { 205 segment.targetPoint.setX(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentX));
263 case PathSegLineToHorizontalAbs: 206 return segment;
264 return SVGPathSegLinetoHorizontalAbs::create(element, x);
265 case PathSegLineToHorizontalRel:
266 return SVGPathSegLinetoHorizontalRel::create(element, x);
267 default:
268 ASSERT_NOT_REACHED();
269 return nullptr;
270 }
271 } 207 }
272 208
273 PassOwnPtr<InterpolableValue> pathSegLinetoVerticalToInterpolableValue(const SVG PathSegLinetoVertical& item, SubPathCoordinates& coordinates) 209 PassOwnPtr<InterpolableValue> pathSegLinetoVerticalToInterpolableValue(const Pat hSegmentData& segment, SubPathCoordinates& coordinates)
274 { 210 {
275 bool isAbsolute = isAbsolutePathSegType(item); 211 bool isAbsolute = isAbsolutePathSegType(segment.command);
276 return specifiedToInterpolableValue(item.y(), isAbsolute, coordinates.curren tY); 212 return specifiedToInterpolableValue(segment.y(), isAbsolute, coordinates.cur rentY);
277 } 213 }
278 214
279 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegLinetoVerticalFromInterpolableValue(co nst InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& coordi nates, SVGPathElement* element) 215 PathSegmentData pathSegLinetoVerticalFromInterpolableValue(const InterpolableVal ue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
280 { 216 {
281 bool isAbsolute = isAbsolutePathSegType(segType); 217 bool isAbsolute = isAbsolutePathSegType(segType);
282 float y = specifiedFromInterpolableValue(&value, isAbsolute, coordinates.cur rentY); 218 PathSegmentData segment;
283 219 segment.command = segType;
284 switch (segType) { 220 segment.targetPoint.setY(specifiedFromInterpolableValue(&value, isAbsolute, coordinates.currentY));
285 case PathSegLineToVerticalAbs: 221 return segment;
286 return SVGPathSegLinetoVerticalAbs::create(element, y);
287 case PathSegLineToVerticalRel:
288 return SVGPathSegLinetoVerticalRel::create(element, y);
289 default:
290 ASSERT_NOT_REACHED();
291 return nullptr;
292 }
293 } 222 }
294 223
295 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicSmoothToInterpolableValue(const SVGPathSegCurvetoCubicSmooth& item, SubPathCoordinates& coordinates) 224 PassOwnPtr<InterpolableValue> pathSegCurvetoCubicSmoothToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates)
296 { 225 {
297 bool isAbsolute = isAbsolutePathSegType(item); 226 bool isAbsolute = isAbsolutePathSegType(segment.command);
298 OwnPtr<InterpolableList> result = InterpolableList::create(4); 227 OwnPtr<InterpolableList> result = InterpolableList::create(4);
299 result->set(0, controlToInterpolableValue(item.x2(), isAbsolute, coordinates .currentX)); 228 result->set(0, controlToInterpolableValue(segment.x2(), isAbsolute, coordina tes.currentX));
300 result->set(1, controlToInterpolableValue(item.y2(), isAbsolute, coordinates .currentY)); 229 result->set(1, controlToInterpolableValue(segment.y2(), isAbsolute, coordina tes.currentY));
301 result->set(2, specifiedToInterpolableValue(item.x(), isAbsolute, coordinate s.currentX)); 230 result->set(2, specifiedToInterpolableValue(segment.x(), isAbsolute, coordin ates.currentX));
302 result->set(3, specifiedToInterpolableValue(item.y(), isAbsolute, coordinate s.currentY)); 231 result->set(3, specifiedToInterpolableValue(segment.y(), isAbsolute, coordin ates.currentY));
303 return result.release(); 232 return result.release();
304 } 233 }
305 234
306 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegCurvetoCubicSmoothFromInterpolableValu e(const InterpolableValue& value, SVGPathSegType segType, SubPathCoordinates& co ordinates, SVGPathElement* element) 235 PathSegmentData pathSegCurvetoCubicSmoothFromInterpolableValue(const Interpolabl eValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates)
307 { 236 {
308 const InterpolableList& list = toInterpolableList(value); 237 const InterpolableList& list = toInterpolableList(value);
309 bool isAbsolute = isAbsolutePathSegType(segType); 238 bool isAbsolute = isAbsolutePathSegType(segType);
310 float x2 = controlFromInterpolableValue(list.get(0), isAbsolute, coordinates .currentX); 239 PathSegmentData segment;
311 float y2 = controlFromInterpolableValue(list.get(1), isAbsolute, coordinates .currentY); 240 segment.command = segType;
312 float x = specifiedFromInterpolableValue(list.get(2), isAbsolute, coordinate s.currentX); 241 segment.point2.setX(controlFromInterpolableValue(list.get(0), isAbsolute, co ordinates.currentX));
313 float y = specifiedFromInterpolableValue(list.get(3), isAbsolute, coordinate s.currentY); 242 segment.point2.setY(controlFromInterpolableValue(list.get(1), isAbsolute, co ordinates.currentY));
314 switch (segType) { 243 segment.targetPoint.setX(specifiedFromInterpolableValue(list.get(2), isAbsol ute, coordinates.currentX));
315 case PathSegCurveToCubicSmoothAbs: 244 segment.targetPoint.setY(specifiedFromInterpolableValue(list.get(3), isAbsol ute, coordinates.currentY));
316 return SVGPathSegCurvetoCubicSmoothAbs::create(element, x, y, x2, y2); 245 return segment;
317 case PathSegCurveToCubicSmoothRel:
318 return SVGPathSegCurvetoCubicSmoothRel::create(element, x, y, x2, y2);
319 default:
320 ASSERT_NOT_REACHED();
321 return nullptr;
322 }
323 } 246 }
324 247
325 PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const SVGPathSeg& item, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType) 248 PassOwnPtr<InterpolableValue> pathSegToInterpolableValue(const PathSegmentData& segment, SubPathCoordinates& coordinates, SVGPathSegType* ptrSegType)
326 { 249 {
327 SVGPathSegType segType = static_cast<SVGPathSegType>(item.pathSegType()); 250 if (ptrSegType)
251 *ptrSegType = segment.command;
328 252
329 if (ptrSegType) 253 switch (segment.command) {
330 *ptrSegType = segType;
331
332 switch (segType) {
333 case PathSegClosePath: 254 case PathSegClosePath:
334 return pathSegClosePathToInterpolableValue(item, coordinates); 255 return pathSegClosePathToInterpolableValue(segment, coordinates);
335 256
336 case PathSegMoveToAbs: 257 case PathSegMoveToAbs:
337 case PathSegMoveToRel: 258 case PathSegMoveToRel:
338 case PathSegLineToAbs: 259 case PathSegLineToAbs:
339 case PathSegLineToRel: 260 case PathSegLineToRel:
340 case PathSegCurveToQuadraticSmoothAbs: 261 case PathSegCurveToQuadraticSmoothAbs:
341 case PathSegCurveToQuadraticSmoothRel: 262 case PathSegCurveToQuadraticSmoothRel:
342 return pathSegSingleCoordinateToInterpolableValue(static_cast<const SVGP athSegSingleCoordinate&>(item), coordinates); 263 return pathSegSingleCoordinateToInterpolableValue(segment, coordinates);
343 264
344 case PathSegCurveToCubicAbs: 265 case PathSegCurveToCubicAbs:
345 case PathSegCurveToCubicRel: 266 case PathSegCurveToCubicRel:
346 return pathSegCurvetoCubicToInterpolableValue(static_cast<const SVGPathS egCurvetoCubic&>(item), coordinates); 267 return pathSegCurvetoCubicToInterpolableValue(segment, coordinates);
347 268
348 case PathSegCurveToQuadraticAbs: 269 case PathSegCurveToQuadraticAbs:
349 case PathSegCurveToQuadraticRel: 270 case PathSegCurveToQuadraticRel:
350 return pathSegCurvetoQuadraticToInterpolableValue(static_cast<const SVGP athSegCurvetoQuadratic&>(item), coordinates); 271 return pathSegCurvetoQuadraticToInterpolableValue(segment, coordinates);
351 272
352 case PathSegArcAbs: 273 case PathSegArcAbs:
353 case PathSegArcRel: 274 case PathSegArcRel:
354 return pathSegArcToInterpolableValue(static_cast<const SVGPathSegArc&>(i tem), coordinates); 275 return pathSegArcToInterpolableValue(segment, coordinates);
355 276
356 case PathSegLineToHorizontalAbs: 277 case PathSegLineToHorizontalAbs:
357 case PathSegLineToHorizontalRel: 278 case PathSegLineToHorizontalRel:
358 return pathSegLinetoHorizontalToInterpolableValue(static_cast<const SVGP athSegLinetoHorizontal&>(item), coordinates); 279 return pathSegLinetoHorizontalToInterpolableValue(segment, coordinates);
359 280
360 case PathSegLineToVerticalAbs: 281 case PathSegLineToVerticalAbs:
361 case PathSegLineToVerticalRel: 282 case PathSegLineToVerticalRel:
362 return pathSegLinetoVerticalToInterpolableValue(static_cast<const SVGPat hSegLinetoVertical&>(item), coordinates); 283 return pathSegLinetoVerticalToInterpolableValue(segment, coordinates);
363 284
364 case PathSegCurveToCubicSmoothAbs: 285 case PathSegCurveToCubicSmoothAbs:
365 case PathSegCurveToCubicSmoothRel: 286 case PathSegCurveToCubicSmoothRel:
366 return pathSegCurvetoCubicSmoothToInterpolableValue(static_cast<const SV GPathSegCurvetoCubicSmooth&>(item), coordinates); 287 return pathSegCurvetoCubicSmoothToInterpolableValue(segment, coordinates );
367 288
368 case PathSegUnknown: 289 case PathSegUnknown:
369 ASSERT_NOT_REACHED(); 290 ASSERT_NOT_REACHED();
370 } 291 }
371 ASSERT_NOT_REACHED(); 292 ASSERT_NOT_REACHED();
372 return nullptr; 293 return nullptr;
373 } 294 }
374 295
375 PassRefPtrWillBeRawPtr<SVGPathSeg> pathSegFromInterpolableValue(const Interpolab leValue& value, SVGPathSegType segType, SubPathCoordinates& coordinates, SVGPath Element* element) 296 PathSegmentData pathSegFromInterpolableValue(const InterpolableValue& value, SVG PathSegType segType, SubPathCoordinates& coordinates)
376 { 297 {
377 switch (segType) { 298 switch (segType) {
378 case PathSegClosePath: 299 case PathSegClosePath:
379 return pathSegClosePathFromInterpolableValue(value, segType, coordinates , element); 300 return pathSegClosePathFromInterpolableValue(value, segType, coordinates );
380 301
381 case PathSegMoveToAbs: 302 case PathSegMoveToAbs:
382 case PathSegMoveToRel: 303 case PathSegMoveToRel:
383 case PathSegLineToAbs: 304 case PathSegLineToAbs:
384 case PathSegLineToRel: 305 case PathSegLineToRel:
385 case PathSegCurveToQuadraticSmoothAbs: 306 case PathSegCurveToQuadraticSmoothAbs:
386 case PathSegCurveToQuadraticSmoothRel: 307 case PathSegCurveToQuadraticSmoothRel:
387 return pathSegSingleCoordinateFromInterpolableValue(value, segType, coor dinates, element); 308 return pathSegSingleCoordinateFromInterpolableValue(value, segType, coor dinates);
388 309
389 case PathSegCurveToCubicAbs: 310 case PathSegCurveToCubicAbs:
390 case PathSegCurveToCubicRel: 311 case PathSegCurveToCubicRel:
391 return pathSegCurvetoCubicFromInterpolableValue(value, segType, coordina tes, element); 312 return pathSegCurvetoCubicFromInterpolableValue(value, segType, coordina tes);
392 313
393 case PathSegCurveToQuadraticAbs: 314 case PathSegCurveToQuadraticAbs:
394 case PathSegCurveToQuadraticRel: 315 case PathSegCurveToQuadraticRel:
395 return pathSegCurvetoQuadraticFromInterpolableValue(value, segType, coor dinates, element); 316 return pathSegCurvetoQuadraticFromInterpolableValue(value, segType, coor dinates);
396 317
397 case PathSegArcAbs: 318 case PathSegArcAbs:
398 case PathSegArcRel: 319 case PathSegArcRel:
399 return pathSegArcFromInterpolableValue(value, segType, coordinates, elem ent); 320 return pathSegArcFromInterpolableValue(value, segType, coordinates);
400 321
401 case PathSegLineToHorizontalAbs: 322 case PathSegLineToHorizontalAbs:
402 case PathSegLineToHorizontalRel: 323 case PathSegLineToHorizontalRel:
403 return pathSegLinetoHorizontalFromInterpolableValue(value, segType, coor dinates, element); 324 return pathSegLinetoHorizontalFromInterpolableValue(value, segType, coor dinates);
404 325
405 case PathSegLineToVerticalAbs: 326 case PathSegLineToVerticalAbs:
406 case PathSegLineToVerticalRel: 327 case PathSegLineToVerticalRel:
407 return pathSegLinetoVerticalFromInterpolableValue(value, segType, coordi nates, element); 328 return pathSegLinetoVerticalFromInterpolableValue(value, segType, coordi nates);
408 329
409 case PathSegCurveToCubicSmoothAbs: 330 case PathSegCurveToCubicSmoothAbs:
410 case PathSegCurveToCubicSmoothRel: 331 case PathSegCurveToCubicSmoothRel:
411 return pathSegCurvetoCubicSmoothFromInterpolableValue(value, segType, co ordinates, element); 332 return pathSegCurvetoCubicSmoothFromInterpolableValue(value, segType, co ordinates);
412 333
413 case PathSegUnknown: 334 case PathSegUnknown:
414 ASSERT_NOT_REACHED(); 335 ASSERT_NOT_REACHED();
415 } 336 }
416 ASSERT_NOT_REACHED(); 337 ASSERT_NOT_REACHED();
417 return nullptr; 338 return PathSegmentData();
339 }
340
341 class InterpolatedPathSource : public SVGPathSource {
342 public:
343 InterpolatedPathSource(const InterpolableList& listValue, const Vector<SVGPa thSegType>& pathSegTypes)
344 : m_currentIndex(0)
345 , m_list(listValue)
346 , m_segmentTypes(pathSegTypes)
347 {
348 ASSERT(m_list.length() == m_segmentTypes.size());
349 }
350
351 private:
352 bool hasMoreData() const override;
353 SVGPathSegType peekSegmentType() override;
354 PathSegmentData parseSegment() override;
355
356 SubPathCoordinates m_normalizationState;
357 size_t m_currentIndex;
358 const InterpolableList& m_list;
359 const Vector<SVGPathSegType>& m_segmentTypes;
360 };
361
362 bool InterpolatedPathSource::hasMoreData() const
363 {
364 return m_currentIndex < m_list.length();
365 }
366
367 SVGPathSegType InterpolatedPathSource::peekSegmentType()
368 {
369 ASSERT(hasMoreData());
370 return m_segmentTypes.at(m_currentIndex);
371 }
372
373 PathSegmentData InterpolatedPathSource::parseSegment()
374 {
375 PathSegmentData segment = pathSegFromInterpolableValue(*m_list.get(m_current Index), m_segmentTypes.at(m_currentIndex), m_normalizationState);
376 ++m_currentIndex;
377 return segment;
378 }
379
380 size_t countPathCommands(const SVGPathByteStream& path)
381 {
382 size_t count = 0;
383 SVGPathByteStreamSource pathSource(path);
384 while (pathSource.hasMoreData()) {
385 pathSource.parseSegment();
386 ++count;
387 }
388 return count;
418 } 389 }
419 390
420 } // namespace 391 } // namespace
421 392
422 PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBa se* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute) 393 PassRefPtr<PathSVGInterpolation> PathSVGInterpolation::maybeCreate(SVGPropertyBa se* start, SVGPropertyBase* end, PassRefPtrWillBeRawPtr<SVGAnimatedPropertyBase> attribute)
423 { 394 {
424 ASSERT(start->type() == SVGPathSegList::classType()); 395 ASSERT(start->type() == SVGPathSegList::classType());
425 ASSERT(end->type() == SVGPathSegList::classType()); 396 ASSERT(end->type() == SVGPathSegList::classType());
426 397
427 SVGPathSegList* startList = static_cast<SVGPathSegList*>(start); 398 const SVGPathByteStream& startPath = static_cast<SVGPathSegList*>(start)->by teStream();
428 SVGPathSegList* endList = static_cast<SVGPathSegList*>(end); 399 const SVGPathByteStream& endPath = static_cast<SVGPathSegList*>(end)->byteSt ream();
429 size_t length = startList->length(); 400
430 if (length != endList->length()) 401 if (startPath.size() != endPath.size())
431 return nullptr; 402 return nullptr;
432 403
404 size_t length = countPathCommands(startPath);
405
406 SVGPathByteStreamSource startPathSource(startPath);
407 SVGPathByteStreamSource endPathSource(endPath);
408
433 Vector<SVGPathSegType> pathSegTypes(length); 409 Vector<SVGPathSegType> pathSegTypes(length);
434 OwnPtr<InterpolableList> startValue = InterpolableList::create(length); 410 OwnPtr<InterpolableList> startValue = InterpolableList::create(length);
435 OwnPtr<InterpolableList> endValue = InterpolableList::create(length); 411 OwnPtr<InterpolableList> endValue = InterpolableList::create(length);
436 SubPathCoordinates startCoordinates; 412 SubPathCoordinates startCoordinates;
437 SubPathCoordinates endCoordinates; 413 SubPathCoordinates endCoordinates;
438 for (size_t i = 0; i < length; i++) { 414 size_t i = 0;
439 if (absolutePathSegType(*startList->at(i)) != absolutePathSegType(*endLi st->at(i))) 415 while (startPathSource.hasMoreData()) {
416 if (toAbsolutePathSegType(startPathSource.peekSegmentType()) != toAbsolu tePathSegType(endPathSource.peekSegmentType()))
440 return nullptr; 417 return nullptr;
441 418
442 // Like Firefox SMIL, we use the final path seg type. 419 // Like Firefox SMIL, we use the final path seg type.
443 startValue->set(i, pathSegToInterpolableValue(*startList->at(i), startCo ordinates, nullptr)); 420 const PathSegmentData startSeg = startPathSource.parseSegment();
444 endValue->set(i, pathSegToInterpolableValue(*endList->at(i), endCoordina tes, &pathSegTypes.at(i))); 421 startValue->set(i, pathSegToInterpolableValue(startSeg, startCoordinates , nullptr));
422
423 const PathSegmentData endSeg = endPathSource.parseSegment();
424 endValue->set(i, pathSegToInterpolableValue(endSeg, endCoordinates, &pat hSegTypes.at(i)));
425
426 ++i;
445 } 427 }
428 ASSERT(!endPathSource.hasMoreData());
429 ASSERT(i == length);
446 430
447 return adoptRef(new PathSVGInterpolation(startValue.release(), endValue.rele ase(), attribute, pathSegTypes)); 431 return adoptRef(new PathSVGInterpolation(startValue.release(), endValue.rele ase(), attribute, pathSegTypes));
448 } 432 }
449 433
450 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableVa lue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes, SVGPathElement* element) 434 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::fromInterpolableVa lue(const InterpolableValue& value, const Vector<SVGPathSegType>& pathSegTypes, SVGPathElement* element)
451 { 435 {
452 const InterpolableList& listValue = toInterpolableList(value);
453 RefPtrWillBeRawPtr<SVGPathSegList> result = SVGPathSegList::create(element); 436 RefPtrWillBeRawPtr<SVGPathSegList> result = SVGPathSegList::create(element);
454 SubPathCoordinates coordinates; 437 result->invalidateList();
455 for (size_t i = 0; i < listValue.length(); i++) 438 InterpolatedPathSource source(toInterpolableList(value), pathSegTypes);
456 result->append(pathSegFromInterpolableValue(*listValue.get(i), pathSegTy pes.at(i), coordinates, element)); 439 SVGPathByteStreamBuilder builder(result->mutableByteStream());
440 SVGPathParser parser(&source, &builder);
441 parser.parsePathDataFromSource(UnalteredParsing, false);
457 return result.release(); 442 return result.release();
458 } 443 }
459 444
460 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue( SVGElement& element) const 445 PassRefPtrWillBeRawPtr<SVGPropertyBase> PathSVGInterpolation::interpolatedValue( SVGElement& element) const
461 { 446 {
462 return fromInterpolableValue(*m_cachedValue, m_pathSegTypes, toSVGPathElemen t(&element)); 447 return fromInterpolableValue(*m_cachedValue, m_pathSegTypes, toSVGPathElemen t(&element));
463 } 448 }
464 449
465 } 450 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698