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) && |
| 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 |
| 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 |