initial import
[vuplus_webkit] / Source / WebCore / svg / SVGPathStringSource.cpp
1 /*
2  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21
22 #if ENABLE(SVG)
23 #include "SVGPathStringSource.h"
24
25 #include "SVGParserUtilities.h"
26
27 namespace WebCore {
28
29 SVGPathStringSource::SVGPathStringSource(const String& string)
30     : m_string(string)
31     , m_current(string.characters())
32     , m_end(m_current + string.length())
33 {
34     ASSERT(!string.isEmpty());
35 }
36
37 bool SVGPathStringSource::hasMoreData() const
38 {
39     return m_current < m_end;
40 }
41
42 bool SVGPathStringSource::moveToNextToken()
43 {
44     return skipOptionalSVGSpaces(m_current, m_end);
45 }
46
47 bool SVGPathStringSource::parseSVGSegmentType(SVGPathSegType& pathSegType)
48 {
49     switch (*(m_current++)) {
50     case 'Z':
51     case 'z':
52         pathSegType = PathSegClosePath;
53         break;
54     case 'M':
55         pathSegType = PathSegMoveToAbs;
56         break;
57     case 'm':
58         pathSegType = PathSegMoveToRel;
59         break;
60     case 'L':
61         pathSegType = PathSegLineToAbs;
62         break;
63     case 'l':
64         pathSegType = PathSegLineToRel;
65         break;
66     case 'C':
67         pathSegType = PathSegCurveToCubicAbs;
68         break;
69     case 'c':
70         pathSegType = PathSegCurveToCubicRel;
71         break;
72     case 'Q':
73         pathSegType = PathSegCurveToQuadraticAbs;
74         break;
75     case 'q':
76         pathSegType = PathSegCurveToQuadraticRel;
77         break;
78     case 'A':
79         pathSegType = PathSegArcAbs;
80         break;
81     case 'a':
82         pathSegType = PathSegArcRel;
83         break;
84     case 'H':
85         pathSegType = PathSegLineToHorizontalAbs;
86         break;
87     case 'h':
88         pathSegType = PathSegLineToHorizontalRel;
89         break;
90     case 'V':
91         pathSegType = PathSegLineToVerticalAbs;
92         break;
93     case 'v':
94         pathSegType = PathSegLineToVerticalRel;
95         break;
96     case 'S':
97         pathSegType = PathSegCurveToCubicSmoothAbs;
98         break;
99     case 's':
100         pathSegType = PathSegCurveToCubicSmoothRel;
101         break;
102     case 'T':
103         pathSegType = PathSegCurveToQuadraticSmoothAbs;
104         break;
105     case 't':
106         pathSegType = PathSegCurveToQuadraticSmoothRel;
107         break;
108     default:
109         pathSegType = PathSegUnknown;
110     }
111     return true;
112 }
113
114 SVGPathSegType SVGPathStringSource::nextCommand(SVGPathSegType previousCommand)
115 {
116     // Check for remaining coordinates in the current command.
117     if ((*m_current == '+' || *m_current == '-' || *m_current == '.' || (*m_current >= '0' && *m_current <= '9'))
118         && previousCommand != PathSegClosePath) {
119         if (previousCommand == PathSegMoveToAbs)
120             return PathSegLineToAbs;
121         if (previousCommand == PathSegMoveToRel)
122             return PathSegLineToRel;
123         return previousCommand;
124     }
125     SVGPathSegType nextCommand;
126     parseSVGSegmentType(nextCommand);
127     return nextCommand;
128 }
129
130 bool SVGPathStringSource::parseMoveToSegment(FloatPoint& targetPoint)
131 {
132     float toX;
133     float toY;
134     if (!parseNumber(m_current, m_end, toX) || !parseNumber(m_current, m_end, toY))
135         return false;
136     targetPoint = FloatPoint(toX, toY);
137     return true;
138 }
139
140 bool SVGPathStringSource::parseLineToSegment(FloatPoint& targetPoint)
141 {
142     float toX;
143     float toY;
144     if (!parseNumber(m_current, m_end, toX) || !parseNumber(m_current, m_end, toY))
145         return false;
146     targetPoint = FloatPoint(toX, toY);
147     return true;
148 }
149
150 bool SVGPathStringSource::parseLineToHorizontalSegment(float& x)
151 {
152     return parseNumber(m_current, m_end, x);
153 }
154
155 bool SVGPathStringSource::parseLineToVerticalSegment(float& y)
156 {
157     return parseNumber(m_current, m_end, y);
158 }
159
160 bool SVGPathStringSource::parseCurveToCubicSegment(FloatPoint& point1, FloatPoint& point2, FloatPoint& targetPoint)
161 {
162     float x1;
163     float y1;
164     float x2;
165     float y2;
166     float toX;
167     float toY;
168     if (!parseNumber(m_current, m_end, x1)
169         || !parseNumber(m_current, m_end, y1)
170         || !parseNumber(m_current, m_end, x2)
171         || !parseNumber(m_current, m_end, y2)
172         || !parseNumber(m_current, m_end, toX)
173         || !parseNumber(m_current, m_end, toY))
174         return false;
175     point1 = FloatPoint(x1, y1);
176     point2 = FloatPoint(x2, y2);
177     targetPoint = FloatPoint(toX, toY);
178     return true;
179 }
180
181 bool SVGPathStringSource::parseCurveToCubicSmoothSegment(FloatPoint& point1, FloatPoint& targetPoint)
182 {
183     float x1;
184     float y1;
185     float toX;
186     float toY;
187     if (!parseNumber(m_current, m_end, x1)
188         || !parseNumber(m_current, m_end, y1)
189         || !parseNumber(m_current, m_end, toX)
190         || !parseNumber(m_current, m_end, toY))
191         return false;
192     point1 = FloatPoint(x1, y1);
193     targetPoint = FloatPoint(toX, toY);
194     return true;
195 }
196
197 bool SVGPathStringSource::parseCurveToQuadraticSegment(FloatPoint& point2, FloatPoint& targetPoint)
198 {
199     float x2;
200     float y2;
201     float toX;
202     float toY;
203     if (!parseNumber(m_current, m_end, x2)
204         || !parseNumber(m_current, m_end, y2)
205         || !parseNumber(m_current, m_end, toX)
206         || !parseNumber(m_current, m_end, toY))
207         return false;
208     point2 = FloatPoint(x2, y2);
209     targetPoint = FloatPoint(toX, toY);
210     return true;
211 }
212
213 bool SVGPathStringSource::parseCurveToQuadraticSmoothSegment(FloatPoint& targetPoint)
214 {
215     float toX;
216     float toY;
217     if (!parseNumber(m_current, m_end, toX)
218         || !parseNumber(m_current, m_end, toY))
219         return false;
220     targetPoint = FloatPoint(toX, toY);
221     return true;
222 }
223
224 bool SVGPathStringSource::parseArcToSegment(float& rx, float& ry, float& angle, bool& largeArc, bool& sweep, FloatPoint& targetPoint)
225 {
226     float toX;
227     float toY;
228     if (!parseNumber(m_current, m_end, rx)
229         || !parseNumber(m_current, m_end, ry)
230         || !parseNumber(m_current, m_end, angle)
231         || !parseArcFlag(m_current, m_end, largeArc)
232         || !parseArcFlag(m_current, m_end, sweep)
233         || !parseNumber(m_current, m_end, toX)
234         || !parseNumber(m_current, m_end, toY))
235         return false;
236     targetPoint = FloatPoint(toX, toY);
237     return true;
238 }
239
240
241 }
242
243 #endif // ENABLE(SVG)