OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
3 * Copyright (C) 2013 Apple Inc. All rights reserved. | 3 * Copyright (C) 2013 Apple Inc. All rights reserved. |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 * Library General Public License for more details. | 13 * Library General Public License for more details. |
14 * | 14 * |
15 * You should have received a copy of the GNU Library General Public License | 15 * You should have received a copy of the GNU Library General Public License |
16 * along with this library; see the file COPYING.LIB. If not, write to | 16 * along with this library; see the file COPYING.LIB. If not, write to |
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 * Boston, MA 02110-1301, USA. | 18 * Boston, MA 02110-1301, USA. |
19 */ | 19 */ |
20 | 20 |
21 #include "core/svg/SVGPathStringSource.h" | 21 #include "core/svg/SVGPathStringSource.h" |
22 | 22 |
23 #include "core/svg/SVGParserUtilities.h" | 23 #include "core/svg/SVGParserUtilities.h" |
24 #include "platform/geometry/FloatPoint.h" | 24 #include "platform/geometry/FloatPoint.h" |
25 | 25 |
26 namespace blink { | 26 namespace blink { |
27 | 27 |
28 SVGPathStringSource::SVGPathStringSource(const String& string) | 28 SVGPathStringSource::SVGPathStringSource(const String& string) |
29 : m_string(string) | 29 : m_is8BitSource(string.is8Bit()) |
30 , m_is8BitSource(string.is8Bit()) | |
31 , m_seenError(false) | |
32 , m_previousCommand(PathSegUnknown) | 30 , m_previousCommand(PathSegUnknown) |
31 , m_string(string) | |
33 { | 32 { |
34 ASSERT(!string.isNull()); | 33 ASSERT(!string.isNull()); |
35 | 34 |
36 if (m_is8BitSource) { | 35 if (m_is8BitSource) { |
37 m_current.m_character8 = string.characters8(); | 36 m_current.m_character8 = string.characters8(); |
38 m_end.m_character8 = m_current.m_character8 + string.length(); | 37 m_end.m_character8 = m_current.m_character8 + string.length(); |
39 } else { | 38 } else { |
40 m_current.m_character16 = string.characters16(); | 39 m_current.m_character16 = string.characters16(); |
41 m_end.m_character16 = m_current.m_character16 + string.length(); | 40 m_end.m_character16 = m_current.m_character16 + string.length(); |
42 } | 41 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 if (previousCommand == PathSegMoveToRel) { | 116 if (previousCommand == PathSegMoveToRel) { |
118 nextCommand = PathSegLineToRel; | 117 nextCommand = PathSegLineToRel; |
119 return true; | 118 return true; |
120 } | 119 } |
121 nextCommand = previousCommand; | 120 nextCommand = previousCommand; |
122 return true; | 121 return true; |
123 } | 122 } |
124 return false; | 123 return false; |
125 } | 124 } |
126 | 125 |
126 void SVGPathStringSource::setErrorMark(SVGParseStatus status) | |
127 { | |
128 if (m_error.status() != SVGParseStatus::NoError) | |
129 return; | |
130 size_t locus = m_is8BitSource | |
131 ? m_current.m_character8 - m_string.characters8() | |
132 : m_current.m_character16 - m_string.characters16(); | |
133 m_error = SVGParsingError(status, locus); | |
134 } | |
135 | |
127 float SVGPathStringSource::parseNumberWithError() | 136 float SVGPathStringSource::parseNumberWithError() |
128 { | 137 { |
129 float numberValue = 0; | 138 float numberValue = 0; |
139 bool error; | |
130 if (m_is8BitSource) | 140 if (m_is8BitSource) |
131 m_seenError |= !parseNumber(m_current.m_character8, m_end.m_character8, numberValue); | 141 error = !parseNumber(m_current.m_character8, m_end.m_character8, numberV alue); |
132 else | 142 else |
133 m_seenError |= !parseNumber(m_current.m_character16, m_end.m_character16 , numberValue); | 143 error = !parseNumber(m_current.m_character16, m_end.m_character16, numbe rValue); |
144 if (UNLIKELY(error)) | |
145 setErrorMark(SVGParseStatus::ExpectedNumber); | |
134 return numberValue; | 146 return numberValue; |
135 } | 147 } |
136 | 148 |
137 bool SVGPathStringSource::parseArcFlagWithError() | 149 bool SVGPathStringSource::parseArcFlagWithError() |
138 { | 150 { |
139 bool flagValue = false; | 151 bool flagValue = false; |
152 bool error; | |
140 if (m_is8BitSource) | 153 if (m_is8BitSource) |
141 m_seenError |= !parseArcFlag(m_current.m_character8, m_end.m_character8, flagValue); | 154 error = !parseArcFlag(m_current.m_character8, m_end.m_character8, flagVa lue); |
142 else | 155 else |
143 m_seenError |= !parseArcFlag(m_current.m_character16, m_end.m_character1 6, flagValue); | 156 error = !parseArcFlag(m_current.m_character16, m_end.m_character16, flag Value); |
157 if (UNLIKELY(error)) | |
158 setErrorMark(SVGParseStatus::ExpectedArcFlag); | |
144 return flagValue; | 159 return flagValue; |
145 } | 160 } |
146 | 161 |
147 SVGPathSegType SVGPathStringSource::peekSegmentType() | 162 SVGPathSegType SVGPathStringSource::peekSegmentType() |
148 { | 163 { |
149 ASSERT(hasMoreData()); | 164 ASSERT(hasMoreData()); |
150 // This won't work in all cases because of the state required to "detect" im plicit commands. | 165 // This won't work in all cases because of the state required to "detect" im plicit commands. |
151 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16; | 166 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16; |
152 return parseSVGSegmentTypeHelper(lookahead); | 167 SVGPathSegType segmentType = parseSVGSegmentTypeHelper(lookahead); |
168 // Here we assume that this is only called via SVGPathParser::initialCommand IsMoveTo. | |
169 // TODO(fs): It ought to be possible to refactor away this entirely, and | |
170 // just handle this in parseSegment (which we sort of do already...) The | |
171 // only user is the method mentioned above. | |
f(malita)
2016/01/27 14:51:13
Yeah, it would be nice to get rid of this assumpti
fs
2016/01/27 14:57:56
I have some sort of (outline of a) plan for this [
| |
172 if (segmentType != PathSegMoveToAbs && segmentType != PathSegMoveToRel) | |
173 setErrorMark(SVGParseStatus::ExpectedMoveToCommand); | |
174 return segmentType; | |
153 } | 175 } |
154 | 176 |
155 PathSegmentData SVGPathStringSource::parseSegment() | 177 PathSegmentData SVGPathStringSource::parseSegment() |
156 { | 178 { |
157 ASSERT(hasMoreData()); | 179 ASSERT(hasMoreData()); |
158 PathSegmentData segment; | 180 PathSegmentData segment; |
159 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16; | 181 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16; |
160 SVGPathSegType command = parseSVGSegmentTypeHelper(lookahead); | 182 SVGPathSegType command = parseSVGSegmentTypeHelper(lookahead); |
161 if (command == PathSegUnknown) { | 183 if (command == PathSegUnknown) { |
162 // Possibly an implicit command. Not allowed if this is the first comman d. | 184 // Possibly an implicit command. Not allowed if this is the first comman d. |
163 if (m_previousCommand == PathSegUnknown) | 185 if (m_previousCommand == PathSegUnknown) { |
186 setErrorMark(SVGParseStatus::ExpectedMoveToCommand); | |
164 return segment; | 187 return segment; |
165 if (!nextCommandHelper(lookahead, m_previousCommand, command)) | 188 } |
189 if (!nextCommandHelper(lookahead, m_previousCommand, command)) { | |
190 setErrorMark(SVGParseStatus::ExpectedPathCommand); | |
166 return segment; | 191 return segment; |
192 } | |
167 } else { | 193 } else { |
168 // Valid explicit command. | 194 // Valid explicit command. |
169 if (m_is8BitSource) | 195 if (m_is8BitSource) |
170 m_current.m_character8++; | 196 m_current.m_character8++; |
171 else | 197 else |
172 m_current.m_character16++; | 198 m_current.m_character16++; |
173 } | 199 } |
174 | 200 |
175 segment.command = m_previousCommand = command; | 201 segment.command = m_previousCommand = command; |
176 | 202 |
177 ASSERT(!m_seenError); | 203 ASSERT(m_error.status() == SVGParseStatus::NoError); |
178 | 204 |
179 switch (segment.command) { | 205 switch (segment.command) { |
180 case PathSegCurveToCubicRel: | 206 case PathSegCurveToCubicRel: |
181 case PathSegCurveToCubicAbs: | 207 case PathSegCurveToCubicAbs: |
182 segment.point1.setX(parseNumberWithError()); | 208 segment.point1.setX(parseNumberWithError()); |
183 segment.point1.setY(parseNumberWithError()); | 209 segment.point1.setY(parseNumberWithError()); |
184 /* fall through */ | 210 /* fall through */ |
185 case PathSegCurveToCubicSmoothRel: | 211 case PathSegCurveToCubicSmoothRel: |
186 case PathSegCurveToCubicSmoothAbs: | 212 case PathSegCurveToCubicSmoothAbs: |
187 segment.point2.setX(parseNumberWithError()); | 213 segment.point2.setX(parseNumberWithError()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 segment.setArcAngle(parseNumberWithError()); | 247 segment.setArcAngle(parseNumberWithError()); |
222 segment.arcLarge = parseArcFlagWithError(); | 248 segment.arcLarge = parseArcFlagWithError(); |
223 segment.arcSweep = parseArcFlagWithError(); | 249 segment.arcSweep = parseArcFlagWithError(); |
224 segment.targetPoint.setX(parseNumberWithError()); | 250 segment.targetPoint.setX(parseNumberWithError()); |
225 segment.targetPoint.setY(parseNumberWithError()); | 251 segment.targetPoint.setY(parseNumberWithError()); |
226 break; | 252 break; |
227 case PathSegUnknown: | 253 case PathSegUnknown: |
228 ASSERT_NOT_REACHED(); | 254 ASSERT_NOT_REACHED(); |
229 } | 255 } |
230 | 256 |
231 if (UNLIKELY(m_seenError)) | 257 if (UNLIKELY(m_error.status() != SVGParseStatus::NoError)) |
232 segment.command = PathSegUnknown; | 258 segment.command = PathSegUnknown; |
233 return segment; | 259 return segment; |
234 } | 260 } |
235 | 261 |
236 } // namespace blink | 262 } // namespace blink |
OLD | NEW |