Chromium Code Reviews| 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 |