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

Side by Side Diff: Source/core/svg/SVGPathParser.cpp

Issue 1023993002: Rework the SVGPathSource interface (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Blender fixups. Created 5 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/svg/SVGPathParser.h ('k') | Source/core/svg/SVGPathSeg.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2002, 2003 The Karbon Developers 2 * Copyright (C) 2002, 2003 The Karbon Developers
3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> 3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> 4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
5 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. 5 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 18 matching lines...) Expand all
29 #include "wtf/MathExtras.h" 29 #include "wtf/MathExtras.h"
30 30
31 namespace blink { 31 namespace blink {
32 32
33 DEFINE_TRACE(SVGPathParser) 33 DEFINE_TRACE(SVGPathParser)
34 { 34 {
35 visitor->trace(m_source); 35 visitor->trace(m_source);
36 visitor->trace(m_consumer); 36 visitor->trace(m_consumer);
37 } 37 }
38 38
39 void SVGPathParser::parseClosePathSegment() 39 bool SVGPathParser::initialCommandIsMoveTo()
40 { 40 {
41 // Reset m_currentPoint for the next path. 41 // If the path is empty it is still valid, so return true.
42 if (m_pathParsingMode == NormalizedParsing) 42 if (!m_source->hasMoreData())
43 m_currentPoint = m_subPathPoint; 43 return true;
44 m_consumer->closePath(); 44
45 SVGPathSegType command = m_source->peekSegmentType();
46 // Path must start with moveTo.
47 return command == PathSegMoveToAbs || command == PathSegMoveToRel;
45 } 48 }
46 49
47 bool SVGPathParser::parseMoveToSegment() 50 void SVGPathParser::emitMoveToSegment(PathSegmentData& segment)
48 { 51 {
49 FloatPoint targetPoint;
50 if (!m_source->parseMoveToSegment(targetPoint))
51 return false;
52
53 if (m_pathParsingMode == UnalteredParsing) { 52 if (m_pathParsingMode == UnalteredParsing) {
54 m_consumer->moveTo(targetPoint, m_mode); 53 m_consumer->moveTo(segment.targetPoint, m_mode);
55 return true; 54 return;
56 } 55 }
57 if (m_mode == RelativeCoordinates) 56 if (m_mode == RelativeCoordinates)
58 m_currentPoint += targetPoint; 57 m_currentPoint += segment.targetPoint;
59 else 58 else
60 m_currentPoint = targetPoint; 59 m_currentPoint = segment.targetPoint;
61 m_subPathPoint = m_currentPoint; 60 m_subPathPoint = m_currentPoint;
62 m_consumer->moveTo(m_currentPoint, AbsoluteCoordinates); 61 m_consumer->moveTo(m_currentPoint, AbsoluteCoordinates);
63 return true;
64 } 62 }
65 63
66 bool SVGPathParser::parseLineToSegment() 64 void SVGPathParser::emitLineToSegment(PathSegmentData& segment)
67 { 65 {
68 FloatPoint targetPoint;
69 if (!m_source->parseLineToSegment(targetPoint))
70 return false;
71
72 if (m_pathParsingMode == UnalteredParsing) { 66 if (m_pathParsingMode == UnalteredParsing) {
73 m_consumer->lineTo(targetPoint, m_mode); 67 m_consumer->lineTo(segment.targetPoint, m_mode);
74 return true; 68 return;
75 } 69 }
76 if (m_mode == RelativeCoordinates) 70 if (m_mode == RelativeCoordinates)
77 m_currentPoint += targetPoint; 71 m_currentPoint += segment.targetPoint;
78 else 72 else
79 m_currentPoint = targetPoint; 73 m_currentPoint = segment.targetPoint;
80 m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates); 74 m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
81 return true;
82 } 75 }
83 76
84 bool SVGPathParser::parseLineToHorizontalSegment() 77 void SVGPathParser::emitLineToHorizontalSegment(PathSegmentData& segment)
85 { 78 {
86 float toX;
87 if (!m_source->parseLineToHorizontalSegment(toX))
88 return false;
89
90 if (m_pathParsingMode == UnalteredParsing) { 79 if (m_pathParsingMode == UnalteredParsing) {
91 m_consumer->lineToHorizontal(toX, m_mode); 80 m_consumer->lineToHorizontal(segment.targetPoint.x(), m_mode);
92 return true; 81 return;
93 } 82 }
94 if (m_mode == RelativeCoordinates) 83 if (m_mode == RelativeCoordinates)
95 m_currentPoint.move(toX, 0); 84 m_currentPoint += segment.targetPoint;
96 else 85 else
97 m_currentPoint.setX(toX); 86 m_currentPoint.setX(segment.targetPoint.x());
98 m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates); 87 m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
99 return true;
100 } 88 }
101 89
102 bool SVGPathParser::parseLineToVerticalSegment() 90 void SVGPathParser::emitLineToVerticalSegment(PathSegmentData& segment)
103 { 91 {
104 float toY;
105 if (!m_source->parseLineToVerticalSegment(toY))
106 return false;
107
108 if (m_pathParsingMode == UnalteredParsing) { 92 if (m_pathParsingMode == UnalteredParsing) {
109 m_consumer->lineToVertical(toY, m_mode); 93 m_consumer->lineToVertical(segment.targetPoint.y(), m_mode);
110 return true; 94 return;
111 } 95 }
112 if (m_mode == RelativeCoordinates) 96 if (m_mode == RelativeCoordinates)
113 m_currentPoint.move(0, toY); 97 m_currentPoint += segment.targetPoint;
114 else 98 else
115 m_currentPoint.setY(toY); 99 m_currentPoint.setY(segment.targetPoint.y());
116 m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates); 100 m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
117 return true;
118 } 101 }
119 102
120 bool SVGPathParser::parseCurveToCubicSegment() 103 void SVGPathParser::emitCurveToCubicSegment(PathSegmentData& segment)
121 { 104 {
122 FloatPoint point1;
123 FloatPoint point2;
124 FloatPoint targetPoint;
125 if (!m_source->parseCurveToCubicSegment(point1, point2, targetPoint))
126 return false;
127
128 if (m_pathParsingMode == UnalteredParsing) { 105 if (m_pathParsingMode == UnalteredParsing) {
129 m_consumer->curveToCubic(point1, point2, targetPoint, m_mode); 106 m_consumer->curveToCubic(segment.point1, segment.point2, segment.targetP oint, m_mode);
130 return true; 107 return;
131 } 108 }
132 if (m_mode == RelativeCoordinates) { 109 if (m_mode == RelativeCoordinates) {
133 point1 += m_currentPoint; 110 segment.point1 += m_currentPoint;
134 point2 += m_currentPoint; 111 segment.point2 += m_currentPoint;
135 targetPoint += m_currentPoint; 112 segment.targetPoint += m_currentPoint;
136 } 113 }
137 m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); 114 m_consumer->curveToCubic(segment.point1, segment.point2, segment.targetPoint , AbsoluteCoordinates);
138 115
139 m_controlPoint = point2; 116 m_controlPoint = segment.point2;
140 m_currentPoint = targetPoint; 117 m_currentPoint = segment.targetPoint;
141 return true;
142 } 118 }
143 119
144 static FloatPoint reflectedPoint(const FloatPoint& reflectIn, const FloatPoint& pointToReflect) 120 static FloatPoint reflectedPoint(const FloatPoint& reflectIn, const FloatPoint& pointToReflect)
145 { 121 {
146 return FloatPoint(2 * reflectIn.x() - pointToReflect.x(), 2 * reflectIn.y() - pointToReflect.y()); 122 return FloatPoint(2 * reflectIn.x() - pointToReflect.x(), 2 * reflectIn.y() - pointToReflect.y());
147 } 123 }
148 124
149 bool SVGPathParser::parseCurveToCubicSmoothSegment() 125 void SVGPathParser::emitCurveToCubicSmoothSegment(PathSegmentData& segment)
150 { 126 {
151 FloatPoint point2;
152 FloatPoint targetPoint;
153 if (!m_source->parseCurveToCubicSmoothSegment(point2, targetPoint))
154 return false;
155
156 if (m_pathParsingMode == UnalteredParsing) { 127 if (m_pathParsingMode == UnalteredParsing) {
157 m_consumer->curveToCubicSmooth(point2, targetPoint, m_mode); 128 m_consumer->curveToCubicSmooth(segment.point2, segment.targetPoint, m_mo de);
158 return true; 129 return;
159 } 130 }
160 if (m_lastCommand != PathSegCurveToCubicAbs 131 if (m_lastCommand != PathSegCurveToCubicAbs
161 && m_lastCommand != PathSegCurveToCubicRel 132 && m_lastCommand != PathSegCurveToCubicRel
162 && m_lastCommand != PathSegCurveToCubicSmoothAbs 133 && m_lastCommand != PathSegCurveToCubicSmoothAbs
163 && m_lastCommand != PathSegCurveToCubicSmoothRel) 134 && m_lastCommand != PathSegCurveToCubicSmoothRel)
164 m_controlPoint = m_currentPoint; 135 m_controlPoint = m_currentPoint;
165 136
166 FloatPoint point1 = reflectedPoint(m_currentPoint, m_controlPoint); 137 FloatPoint point1 = reflectedPoint(m_currentPoint, m_controlPoint);
167 if (m_mode == RelativeCoordinates) { 138 if (m_mode == RelativeCoordinates) {
168 point2 += m_currentPoint; 139 segment.point2 += m_currentPoint;
169 targetPoint += m_currentPoint; 140 segment.targetPoint += m_currentPoint;
170 } 141 }
171 142
172 m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); 143 m_consumer->curveToCubic(point1, segment.point2, segment.targetPoint, Absolu teCoordinates);
173 144
174 m_controlPoint = point2; 145 m_controlPoint = segment.point2;
175 m_currentPoint = targetPoint; 146 m_currentPoint = segment.targetPoint;
176 return true;
177 } 147 }
178 148
179 // Blend the points with a ratio (1/3):(2/3). 149 // Blend the points with a ratio (1/3):(2/3).
180 static FloatPoint blendPoints(const FloatPoint& p1, const FloatPoint& p2) 150 static FloatPoint blendPoints(const FloatPoint& p1, const FloatPoint& p2)
181 { 151 {
182 const float oneOverThree = 1 / 3.f; 152 const float oneOverThree = 1 / 3.f;
183 return FloatPoint((p1.x() + 2 * p2.x()) * oneOverThree, (p1.y() + 2 * p2.y() ) * oneOverThree); 153 return FloatPoint((p1.x() + 2 * p2.x()) * oneOverThree, (p1.y() + 2 * p2.y() ) * oneOverThree);
184 } 154 }
185 155
186 bool SVGPathParser::parseCurveToQuadraticSegment() 156 void SVGPathParser::emitCurveToQuadraticSegment(PathSegmentData& segment)
187 { 157 {
188 FloatPoint point1;
189 FloatPoint targetPoint;
190 if (!m_source->parseCurveToQuadraticSegment(point1, targetPoint))
191 return false;
192
193 if (m_pathParsingMode == UnalteredParsing) { 158 if (m_pathParsingMode == UnalteredParsing) {
194 m_consumer->curveToQuadratic(point1, targetPoint, m_mode); 159 m_consumer->curveToQuadratic(segment.point1, segment.targetPoint, m_mode );
195 return true; 160 return;
196 } 161 }
197 m_controlPoint = point1; 162 m_controlPoint = segment.point1;
198 163
199 if (m_mode == RelativeCoordinates) { 164 if (m_mode == RelativeCoordinates) {
200 m_controlPoint += m_currentPoint; 165 m_controlPoint += m_currentPoint;
201 targetPoint += m_currentPoint; 166 segment.targetPoint += m_currentPoint;
202 } 167 }
203 point1 = blendPoints(m_currentPoint, m_controlPoint); 168 segment.point1 = blendPoints(m_currentPoint, m_controlPoint);
204 FloatPoint point2 = blendPoints(targetPoint, m_controlPoint); 169 FloatPoint point2 = blendPoints(segment.targetPoint, m_controlPoint);
205 170
206 m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); 171 m_consumer->curveToCubic(segment.point1, point2, segment.targetPoint, Absolu teCoordinates);
207 172
208 m_currentPoint = targetPoint; 173 m_currentPoint = segment.targetPoint;
209 return true;
210 } 174 }
211 175
212 bool SVGPathParser::parseCurveToQuadraticSmoothSegment() 176 void SVGPathParser::emitCurveToQuadraticSmoothSegment(PathSegmentData& segment)
213 { 177 {
214 FloatPoint targetPoint;
215 if (!m_source->parseCurveToQuadraticSmoothSegment(targetPoint))
216 return false;
217
218 if (m_pathParsingMode == UnalteredParsing) { 178 if (m_pathParsingMode == UnalteredParsing) {
219 m_consumer->curveToQuadraticSmooth(targetPoint, m_mode); 179 m_consumer->curveToQuadraticSmooth(segment.targetPoint, m_mode);
220 return true; 180 return;
221 } 181 }
222 if (m_lastCommand != PathSegCurveToQuadraticAbs 182 if (m_lastCommand != PathSegCurveToQuadraticAbs
223 && m_lastCommand != PathSegCurveToQuadraticRel 183 && m_lastCommand != PathSegCurveToQuadraticRel
224 && m_lastCommand != PathSegCurveToQuadraticSmoothAbs 184 && m_lastCommand != PathSegCurveToQuadraticSmoothAbs
225 && m_lastCommand != PathSegCurveToQuadraticSmoothRel) 185 && m_lastCommand != PathSegCurveToQuadraticSmoothRel)
226 m_controlPoint = m_currentPoint; 186 m_controlPoint = m_currentPoint;
227 187
228 if (m_mode == RelativeCoordinates) 188 if (m_mode == RelativeCoordinates)
229 targetPoint += m_currentPoint; 189 segment.targetPoint += m_currentPoint;
230 190
231 m_controlPoint = reflectedPoint(m_currentPoint, m_controlPoint); 191 m_controlPoint = reflectedPoint(m_currentPoint, m_controlPoint);
232 FloatPoint point1 = blendPoints(m_currentPoint, m_controlPoint); 192 FloatPoint point1 = blendPoints(m_currentPoint, m_controlPoint);
233 FloatPoint point2 = blendPoints(targetPoint, m_controlPoint); 193 FloatPoint point2 = blendPoints(segment.targetPoint, m_controlPoint);
234 194
235 m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); 195 m_consumer->curveToCubic(point1, point2, segment.targetPoint, AbsoluteCoordi nates);
236 196
237 m_currentPoint = targetPoint; 197 m_currentPoint = segment.targetPoint;
238 return true;
239 } 198 }
240 199
241 bool SVGPathParser::parseArcToSegment() 200 void SVGPathParser::emitArcToSegment(PathSegmentData& segment)
242 { 201 {
243 float rx;
244 float ry;
245 float angle;
246 bool largeArc;
247 bool sweep;
248 FloatPoint targetPoint;
249 if (!m_source->parseArcToSegment(rx, ry, angle, largeArc, sweep, targetPoint ))
250 return false;
251
252 if (m_pathParsingMode == UnalteredParsing) { 202 if (m_pathParsingMode == UnalteredParsing) {
253 m_consumer->arcTo(rx, ry, angle, largeArc, sweep, targetPoint, m_mode); 203 m_consumer->arcTo(segment.arcRadii().x(), segment.arcRadii().y(), segmen t.arcAngle(), segment.arcLarge, segment.arcSweep, segment.targetPoint, m_mode);
254 return true; 204 return;
255 } 205 }
256 206
257 // If rx = 0 or ry = 0 then this arc is treated as a straight line segment ( a "lineto") joining the endpoints. 207 // If rx = 0 or ry = 0 then this arc is treated as a straight line segment ( a "lineto") joining the endpoints.
258 // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters 208 // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
259 // If the current point and target point for the arc are identical, it shoul d be treated as a zero length 209 // If the current point and target point for the arc are identical, it shoul d be treated as a zero length
260 // path. This ensures continuity in animations. 210 // path. This ensures continuity in animations.
261 rx = fabsf(rx); 211 float rx = fabsf(segment.arcRadii().x());
262 ry = fabsf(ry); 212 float ry = fabsf(segment.arcRadii().y());
263 213
264 if (m_mode == RelativeCoordinates) 214 if (m_mode == RelativeCoordinates)
265 targetPoint += m_currentPoint; 215 segment.targetPoint += m_currentPoint;
266 216
267 if (!rx || !ry || targetPoint == m_currentPoint) { 217 if (!rx || !ry || segment.targetPoint == m_currentPoint) {
268 m_consumer->lineTo(targetPoint, AbsoluteCoordinates); 218 m_consumer->lineTo(segment.targetPoint, AbsoluteCoordinates);
269 m_currentPoint = targetPoint; 219 m_currentPoint = segment.targetPoint;
270 return true; 220 return;
271 } 221 }
272 222
223 float angle = segment.arcAngle();
273 FloatPoint point1 = m_currentPoint; 224 FloatPoint point1 = m_currentPoint;
274 m_currentPoint = targetPoint; 225 m_currentPoint = segment.targetPoint;
275 return decomposeArcToCubic(angle, rx, ry, point1, targetPoint, largeArc, swe ep); 226 if (!decomposeArcToCubic(angle, rx, ry, point1, segment.targetPoint, segment .arcLarge, segment.arcSweep))
227 m_consumer->lineTo(segment.targetPoint, AbsoluteCoordinates);
276 } 228 }
277 229
278 bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo l checkForInitialMoveTo) 230 bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo l checkForInitialMoveTo)
279 { 231 {
280 ASSERT(m_source); 232 ASSERT(m_source);
281 ASSERT(m_consumer); 233 ASSERT(m_consumer);
282 234
283 m_pathParsingMode = pathParsingMode; 235 m_pathParsingMode = pathParsingMode;
284 236
285 m_controlPoint = FloatPoint(); 237 m_controlPoint = FloatPoint();
286 m_currentPoint = FloatPoint(); 238 m_currentPoint = FloatPoint();
287 m_subPathPoint = FloatPoint(); 239 m_subPathPoint = FloatPoint();
288 240
289 // Skip any leading spaces. 241 if (checkForInitialMoveTo && !initialCommandIsMoveTo())
290 if (!m_source->moveToNextToken())
291 return true;
292
293 SVGPathSegType command;
294 m_source->parseSVGSegmentType(command);
295 m_lastCommand = PathSegUnknown;
296
297 // Path must start with moveto.
298 if (checkForInitialMoveTo && command != PathSegMoveToAbs && command != PathS egMoveToRel)
299 return false; 242 return false;
300 243
301 while (true) { 244 m_lastCommand = PathSegUnknown;
302 // Skip spaces between command and first coordinate. 245 while (m_source->hasMoreData()) {
303 m_source->moveToNextToken(); 246 PathSegmentData segment = m_source->parseSegment();
247 if (segment.command == PathSegUnknown)
248 return false;
249
304 m_mode = AbsoluteCoordinates; 250 m_mode = AbsoluteCoordinates;
305 switch (command) { 251
252 switch (segment.command) {
306 case PathSegMoveToRel: 253 case PathSegMoveToRel:
307 m_mode = RelativeCoordinates; 254 m_mode = RelativeCoordinates;
308 case PathSegMoveToAbs: 255 case PathSegMoveToAbs:
309 if (!parseMoveToSegment()) 256 emitMoveToSegment(segment);
310 return false;
311 break; 257 break;
312 case PathSegLineToRel: 258 case PathSegLineToRel:
313 m_mode = RelativeCoordinates; 259 m_mode = RelativeCoordinates;
314 case PathSegLineToAbs: 260 case PathSegLineToAbs:
315 if (!parseLineToSegment()) 261 emitLineToSegment(segment);
316 return false;
317 break; 262 break;
318 case PathSegLineToHorizontalRel: 263 case PathSegLineToHorizontalRel:
319 m_mode = RelativeCoordinates; 264 m_mode = RelativeCoordinates;
320 case PathSegLineToHorizontalAbs: 265 case PathSegLineToHorizontalAbs:
321 if (!parseLineToHorizontalSegment()) 266 emitLineToHorizontalSegment(segment);
322 return false;
323 break; 267 break;
324 case PathSegLineToVerticalRel: 268 case PathSegLineToVerticalRel:
325 m_mode = RelativeCoordinates; 269 m_mode = RelativeCoordinates;
326 case PathSegLineToVerticalAbs: 270 case PathSegLineToVerticalAbs:
327 if (!parseLineToVerticalSegment()) 271 emitLineToVerticalSegment(segment);
328 return false;
329 break; 272 break;
330 case PathSegClosePath: 273 case PathSegClosePath:
331 parseClosePathSegment(); 274 m_consumer->closePath();
275 // Reset m_currentPoint for the next path.
276 if (m_pathParsingMode == NormalizedParsing)
277 m_currentPoint = m_subPathPoint;
332 break; 278 break;
333 case PathSegCurveToCubicRel: 279 case PathSegCurveToCubicRel:
334 m_mode = RelativeCoordinates; 280 m_mode = RelativeCoordinates;
335 case PathSegCurveToCubicAbs: 281 case PathSegCurveToCubicAbs:
336 if (!parseCurveToCubicSegment()) 282 emitCurveToCubicSegment(segment);
337 return false;
338 break; 283 break;
339 case PathSegCurveToCubicSmoothRel: 284 case PathSegCurveToCubicSmoothRel:
340 m_mode = RelativeCoordinates; 285 m_mode = RelativeCoordinates;
341 case PathSegCurveToCubicSmoothAbs: 286 case PathSegCurveToCubicSmoothAbs:
342 if (!parseCurveToCubicSmoothSegment()) 287 emitCurveToCubicSmoothSegment(segment);
343 return false;
344 break; 288 break;
345 case PathSegCurveToQuadraticRel: 289 case PathSegCurveToQuadraticRel:
346 m_mode = RelativeCoordinates; 290 m_mode = RelativeCoordinates;
347 case PathSegCurveToQuadraticAbs: 291 case PathSegCurveToQuadraticAbs:
348 if (!parseCurveToQuadraticSegment()) 292 emitCurveToQuadraticSegment(segment);
349 return false;
350 break; 293 break;
351 case PathSegCurveToQuadraticSmoothRel: 294 case PathSegCurveToQuadraticSmoothRel:
352 m_mode = RelativeCoordinates; 295 m_mode = RelativeCoordinates;
353 case PathSegCurveToQuadraticSmoothAbs: 296 case PathSegCurveToQuadraticSmoothAbs:
354 if (!parseCurveToQuadraticSmoothSegment()) 297 emitCurveToQuadraticSmoothSegment(segment);
355 return false;
356 break; 298 break;
357 case PathSegArcRel: 299 case PathSegArcRel:
358 m_mode = RelativeCoordinates; 300 m_mode = RelativeCoordinates;
359 case PathSegArcAbs: 301 case PathSegArcAbs:
360 if (!parseArcToSegment()) 302 emitArcToSegment(segment);
361 return false;
362 break; 303 break;
363 default: 304 default:
364 return false; 305 ASSERT_NOT_REACHED();
365 } 306 }
366 if (!m_consumer->continueConsuming()) 307 if (!m_consumer->continueConsuming())
367 return true; 308 return true;
368 309
369 m_lastCommand = command; 310 m_lastCommand = segment.command;
370
371 if (!m_source->hasMoreData())
372 return true;
373
374 command = m_source->nextCommand(command);
375 311
376 if (m_lastCommand != PathSegCurveToCubicAbs 312 if (m_lastCommand != PathSegCurveToCubicAbs
377 && m_lastCommand != PathSegCurveToCubicRel 313 && m_lastCommand != PathSegCurveToCubicRel
378 && m_lastCommand != PathSegCurveToCubicSmoothAbs 314 && m_lastCommand != PathSegCurveToCubicSmoothAbs
379 && m_lastCommand != PathSegCurveToCubicSmoothRel 315 && m_lastCommand != PathSegCurveToCubicSmoothRel
380 && m_lastCommand != PathSegCurveToQuadraticAbs 316 && m_lastCommand != PathSegCurveToQuadraticAbs
381 && m_lastCommand != PathSegCurveToQuadraticRel 317 && m_lastCommand != PathSegCurveToQuadraticRel
382 && m_lastCommand != PathSegCurveToQuadraticSmoothAbs 318 && m_lastCommand != PathSegCurveToQuadraticSmoothAbs
383 && m_lastCommand != PathSegCurveToQuadraticSmoothRel) 319 && m_lastCommand != PathSegCurveToQuadraticSmoothRel)
384 m_controlPoint = m_currentPoint; 320 m_controlPoint = m_currentPoint;
385 321
386 m_consumer->incrementPathSegmentCount(); 322 if (m_source->hasMoreData())
323 m_consumer->incrementPathSegmentCount();
387 } 324 }
388 325 return true;
389 return false;
390 } 326 }
391 327
392 // This works by converting the SVG arc to "simple" beziers. 328 // This works by converting the SVG arc to "simple" beziers.
393 // Partly adapted from Niko's code in kdelibs/kdecore/svgicons. 329 // Partly adapted from Niko's code in kdelibs/kdecore/svgicons.
394 // See also SVG implementation notes: http://www.w3.org/TR/SVG/implnote.html#Arc ConversionEndpointToCenter 330 // See also SVG implementation notes: http://www.w3.org/TR/SVG/implnote.html#Arc ConversionEndpointToCenter
395 bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, const F loatPoint& start, const FloatPoint& end, bool largeArcFlag, bool sweepFlag) 331 bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, const F loatPoint& start, const FloatPoint& end, bool largeArcFlag, bool sweepFlag)
396 { 332 {
397 FloatSize midPointDistance = start - end; 333 FloatSize midPointDistance = start - end;
398 midPointDistance.scale(0.5f); 334 midPointDistance.scale(0.5f);
399 335
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 point2 = targetPoint; 405 point2 = targetPoint;
470 point2.move(t * sinEndTheta, -t * cosEndTheta); 406 point2.move(t * sinEndTheta, -t * cosEndTheta);
471 407
472 m_consumer->curveToCubic(pointTransform.mapPoint(point1), pointTransform .mapPoint(point2), 408 m_consumer->curveToCubic(pointTransform.mapPoint(point1), pointTransform .mapPoint(point2),
473 pointTransform.mapPoint(targetPoint), AbsoluteC oordinates); 409 pointTransform.mapPoint(targetPoint), AbsoluteC oordinates);
474 } 410 }
475 return true; 411 return true;
476 } 412 }
477 413
478 } 414 }
OLDNEW
« no previous file with comments | « Source/core/svg/SVGPathParser.h ('k') | Source/core/svg/SVGPathSeg.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698