OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkParse.h" | 8 #include "SkParse.h" |
9 #include "SkSVGAttributeParser.h" | 9 #include "SkSVGAttributeParser.h" |
10 #include "SkSVGTypes.h" | 10 #include "SkSVGTypes.h" |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 this->parseScalarToken(&w) && this->parseSepToken() && | 204 this->parseScalarToken(&w) && this->parseSepToken() && |
205 this->parseScalarToken(&h)) { | 205 this->parseScalarToken(&h)) { |
206 | 206 |
207 *vb = SkSVGViewBoxType(SkRect::MakeXYWH(x, y, w, h)); | 207 *vb = SkSVGViewBoxType(SkRect::MakeXYWH(x, y, w, h)); |
208 parsedValue = true; | 208 parsedValue = true; |
209 // consume trailing whitespace | 209 // consume trailing whitespace |
210 this->parseWSToken(); | 210 this->parseWSToken(); |
211 } | 211 } |
212 return parsedValue && this->parseEOSToken(); | 212 return parsedValue && this->parseEOSToken(); |
213 } | 213 } |
214 | |
215 template <typename Func, typename T> | |
216 bool SkSVGAttributeParser::parseParenthesized(const char* prefix, Func f, T* res ult) { | |
217 this->parseWSToken(); | |
218 if (prefix && !this->parseExpectedStringToken(prefix)) { | |
219 return false; | |
220 } | |
221 this->parseWSToken(); | |
222 if (!this->parseExpectedStringToken("(")) { | |
223 return false; | |
224 } | |
225 this->parseWSToken(); | |
226 | |
227 if (!f(result)) { | |
228 return false; | |
229 } | |
230 this->parseWSToken(); | |
231 | |
232 return this->parseExpectedStringToken(")"); | |
233 } | |
234 | |
235 bool SkSVGAttributeParser::parseMatrixToken(SkMatrix* matrix) { | |
236 return this->parseParenthesized("matrix", [this](SkMatrix* m) -> bool { | |
237 SkScalar scalars[6]; | |
238 for (int i = 0; i < 6; ++i) { | |
239 if (!(this->parseScalarToken(scalars + i) && | |
robertphillips
2016/08/08 17:48:47
Why "i > 4" ?
f(malita)
2016/08/08 17:53:15
For the last iteration (i == 5) we don't match a t
| |
240 (i > 4 || this->parseSepToken()))) { | |
241 return false; | |
242 } | |
243 } | |
244 | |
245 m->setAll(scalars[0], scalars[2], scalars[4], scalars[1], scalars[3], sc alars[5], 0, 0, 1); | |
246 return true; | |
247 }, matrix); | |
248 } | |
249 | |
250 bool SkSVGAttributeParser::parseTranslateToken(SkMatrix* matrix) { | |
251 return this->parseParenthesized("translate", [this](SkMatrix* m) -> bool { | |
252 SkScalar tx, ty; | |
253 this->parseWSToken(); | |
254 if (!this->parseScalarToken(&tx)) { | |
255 return false; | |
256 } | |
257 | |
robertphillips
2016/08/08 17:48:47
So, "1.0f," should yield a 1.0f, 1.0f translation
f(malita)
2016/08/08 17:53:15
Yup: https://www.w3.org/TR/SVG/coords.html#Transfo
| |
258 if (!(this->parseSepToken() && this->parseScalarToken(&ty))) { | |
259 ty = tx; | |
260 } | |
261 | |
262 m->setTranslate(tx, ty); | |
263 return true; | |
264 }, matrix); | |
265 } | |
266 | |
267 bool SkSVGAttributeParser::parseScaleToken(SkMatrix* matrix) { | |
268 return this->parseParenthesized("scale", [this](SkMatrix* m) -> bool { | |
269 SkScalar sx, sy; | |
270 if (!this->parseScalarToken(&sx)) { | |
271 return false; | |
272 } | |
273 | |
274 if (!(this->parseSepToken() && this->parseScalarToken(&sy))) { | |
275 sy = sx; | |
276 } | |
277 | |
278 m->setScale(sx, sy); | |
279 return true; | |
280 }, matrix); | |
281 } | |
282 | |
283 bool SkSVGAttributeParser::parseRotateToken(SkMatrix* matrix) { | |
284 return this->parseParenthesized("rotate", [this](SkMatrix* m) -> bool { | |
285 SkScalar angle; | |
286 if (!this->parseScalarToken(&angle)) { | |
287 return false; | |
288 } | |
289 | |
290 SkScalar cx = 0; | |
291 SkScalar cy = 0; | |
292 // optional [<cx> <cy>] | |
293 if (this->parseSepToken() && this->parseScalarToken(&cx)) { | |
294 if (!(this->parseSepToken() && this->parseScalarToken(&cy))) { | |
295 return false; | |
296 } | |
297 } | |
298 | |
299 m->setRotate(angle, cx, cy); | |
300 return true; | |
301 }, matrix); | |
302 } | |
303 | |
304 bool SkSVGAttributeParser::parseSkewXToken(SkMatrix* matrix) { | |
305 return this->parseParenthesized("skewX", [this](SkMatrix* m) -> bool { | |
306 SkScalar angle; | |
307 if (!this->parseScalarToken(&angle)) { | |
308 return false; | |
309 } | |
310 m->setSkewX(angle); | |
311 return true; | |
312 }, matrix); | |
313 } | |
314 | |
315 bool SkSVGAttributeParser::parseSkewYToken(SkMatrix* matrix) { | |
316 return this->parseParenthesized("skewY", [this](SkMatrix* m) -> bool { | |
317 SkScalar angle; | |
318 if (!this->parseScalarToken(&angle)) { | |
319 return false; | |
320 } | |
321 m->setSkewY(angle); | |
322 return true; | |
323 }, matrix); | |
324 } | |
325 | |
326 // https://www.w3.org/TR/SVG/coords.html#TransformAttribute | |
327 bool SkSVGAttributeParser::parseTransform(SkSVGTransformType* t) { | |
328 SkMatrix matrix = SkMatrix::I(); | |
329 | |
330 bool parsed = false; | |
331 while (true) { | |
332 SkMatrix m; | |
333 | |
334 if (!( this->parseMatrixToken(&m) | |
335 || this->parseTranslateToken(&m) | |
336 || this->parseScaleToken(&m) | |
337 || this->parseRotateToken(&m) | |
338 || this->parseSkewXToken(&m) | |
339 || this->parseSkewYToken(&m))) { | |
340 break; | |
341 } | |
342 | |
343 matrix.preConcat(m); | |
344 parsed = true; | |
345 } | |
346 | |
347 this->parseWSToken(); | |
348 if (!parsed || !this->parseEOSToken()) { | |
349 return false; | |
350 } | |
351 | |
352 *t = SkSVGTransformType(matrix); | |
353 return true; | |
354 } | |
OLD | NEW |