| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 | 106 |
| 107 for (size_t i = 0; i < SK_ARRAY_COUNT(gUnitInfo); ++i) { | 107 for (size_t i = 0; i < SK_ARRAY_COUNT(gUnitInfo); ++i) { |
| 108 if (this->parseExpectedStringToken(gUnitInfo[i].fUnitName)) { | 108 if (this->parseExpectedStringToken(gUnitInfo[i].fUnitName)) { |
| 109 *unit = gUnitInfo[i].fUnit; | 109 *unit = gUnitInfo[i].fUnit; |
| 110 return true; | 110 return true; |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 return false; | 113 return false; |
| 114 } | 114 } |
| 115 | 115 |
| 116 // https://www.w3.org/TR/SVG/types.html#DataTypeColor |
| 116 bool SkSVGAttributeParser::parseNamedColorToken(SkColor* c) { | 117 bool SkSVGAttributeParser::parseNamedColorToken(SkColor* c) { |
| 117 if (const char* next = SkParse::FindNamedColor(fCurPos, strlen(fCurPos), c))
{ | 118 if (const char* next = SkParse::FindNamedColor(fCurPos, strlen(fCurPos), c))
{ |
| 118 fCurPos = next; | 119 fCurPos = next; |
| 119 return true; | 120 return true; |
| 120 } | 121 } |
| 121 return false; | 122 return false; |
| 122 } | 123 } |
| 123 | 124 |
| 124 bool SkSVGAttributeParser::parseHexColorToken(SkColor* c) { | 125 bool SkSVGAttributeParser::parseHexColorToken(SkColor* c) { |
| 125 uint32_t v; | 126 uint32_t v; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 141 ((v << 0) & 0x0000000f); | 142 ((v << 0) & 0x0000000f); |
| 142 break; | 143 break; |
| 143 default: | 144 default: |
| 144 return false; | 145 return false; |
| 145 } | 146 } |
| 146 | 147 |
| 147 *c = v | 0xff000000; | 148 *c = v | 0xff000000; |
| 148 return true; | 149 return true; |
| 149 } | 150 } |
| 150 | 151 |
| 151 // https://www.w3.org/TR/SVG/types.html#DataTypeColor | 152 bool SkSVGAttributeParser::parseColorComponentToken(int32_t* c) { |
| 153 fCurPos = SkParse::FindS32(fCurPos, c); |
| 154 if (!fCurPos) { |
| 155 return false; |
| 156 } |
| 157 |
| 158 if (*fCurPos == '%') { |
| 159 *c = SkScalarRoundToInt(*c * 255.0f / 100); |
| 160 fCurPos++; |
| 161 } |
| 162 |
| 163 return true; |
| 164 } |
| 165 |
| 166 bool SkSVGAttributeParser::parseRGBColorToken(SkColor* c) { |
| 167 return this->parseParenthesized("rgb", [this](SkColor* c) -> bool { |
| 168 int32_t r, g, b; |
| 169 if (this->parseColorComponentToken(&r) && |
| 170 this->parseSepToken() && |
| 171 this->parseColorComponentToken(&g) && |
| 172 this->parseSepToken() && |
| 173 this->parseColorComponentToken(&b)) { |
| 174 |
| 175 *c = SkColorSetRGB(static_cast<uint8_t>(r), |
| 176 static_cast<uint8_t>(g), |
| 177 static_cast<uint8_t>(b)); |
| 178 return true; |
| 179 } |
| 180 return false; |
| 181 }, c); |
| 182 } |
| 183 |
| 152 bool SkSVGAttributeParser::parseColor(SkSVGColorType* color) { | 184 bool SkSVGAttributeParser::parseColor(SkSVGColorType* color) { |
| 153 SkColor c; | 185 SkColor c; |
| 154 | 186 |
| 155 // consume preceding whitespace | 187 // consume preceding whitespace |
| 156 this->parseWSToken(); | 188 this->parseWSToken(); |
| 157 | 189 |
| 158 // TODO: rgb(...) | 190 // TODO: rgb(...) |
| 159 bool parsedValue = false; | 191 bool parsedValue = false; |
| 160 if (this->parseHexColorToken(&c) || this->parseNamedColorToken(&c)) { | 192 if (this->parseHexColorToken(&c) |
| 193 || this->parseNamedColorToken(&c) |
| 194 || this->parseRGBColorToken(&c)) { |
| 161 *color = SkSVGColorType(c); | 195 *color = SkSVGColorType(c); |
| 162 parsedValue = true; | 196 parsedValue = true; |
| 163 | 197 |
| 164 // consume trailing whitespace | 198 // consume trailing whitespace |
| 165 this->parseWSToken(); | 199 this->parseWSToken(); |
| 166 } | 200 } |
| 167 | 201 |
| 168 return parsedValue && this->parseEOSToken(); | 202 return parsedValue && this->parseEOSToken(); |
| 169 } | 203 } |
| 170 | 204 |
| 205 // https://www.w3.org/TR/SVG/linking.html#IRIReference |
| 206 bool SkSVGAttributeParser::parseIRI(SkSVGStringType* iri) { |
| 207 // consume preceding whitespace |
| 208 this->parseWSToken(); |
| 209 |
| 210 // we only support local fragments |
| 211 if (!this->parseExpectedStringToken("#")) { |
| 212 return false; |
| 213 } |
| 214 const auto* start = fCurPos; |
| 215 this->advanceWhile([](char c) -> bool { return !is_eos(c) && c != ')'; }); |
| 216 if (start == fCurPos) { |
| 217 return false; |
| 218 } |
| 219 *iri = SkString(start, fCurPos - start); |
| 220 return true; |
| 221 } |
| 222 |
| 223 // https://www.w3.org/TR/SVG/types.html#DataTypeFuncIRI |
| 224 bool SkSVGAttributeParser::parseFuncIRI(SkSVGStringType* iri) { |
| 225 return this->parseParenthesized("url", [this](SkSVGStringType* iri) -> bool
{ |
| 226 return this->parseIRI(iri); |
| 227 }, iri); |
| 228 } |
| 229 |
| 171 // https://www.w3.org/TR/SVG/types.html#DataTypeNumber | 230 // https://www.w3.org/TR/SVG/types.html#DataTypeNumber |
| 172 bool SkSVGAttributeParser::parseNumber(SkSVGNumberType* number) { | 231 bool SkSVGAttributeParser::parseNumber(SkSVGNumberType* number) { |
| 173 // consume WS | 232 // consume WS |
| 174 this->parseWSToken(); | 233 this->parseWSToken(); |
| 175 | 234 |
| 176 SkScalar s; | 235 SkScalar s; |
| 177 if (this->parseScalarToken(&s)) { | 236 if (this->parseScalarToken(&s)) { |
| 178 *number = SkSVGNumberType(s); | 237 *number = SkSVGNumberType(s); |
| 179 // consume trailing separators | 238 // consume trailing separators |
| 180 this->parseSepToken(); | 239 this->parseSepToken(); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 return false; | 415 return false; |
| 357 } | 416 } |
| 358 | 417 |
| 359 *t = SkSVGTransformType(matrix); | 418 *t = SkSVGTransformType(matrix); |
| 360 return true; | 419 return true; |
| 361 } | 420 } |
| 362 | 421 |
| 363 // https://www.w3.org/TR/SVG/painting.html#SpecifyingPaint | 422 // https://www.w3.org/TR/SVG/painting.html#SpecifyingPaint |
| 364 bool SkSVGAttributeParser::parsePaint(SkSVGPaint* paint) { | 423 bool SkSVGAttributeParser::parsePaint(SkSVGPaint* paint) { |
| 365 SkSVGColorType c; | 424 SkSVGColorType c; |
| 425 SkSVGStringType iri; |
| 366 bool parsedValue = false; | 426 bool parsedValue = false; |
| 367 if (this->parseColor(&c)) { | 427 if (this->parseColor(&c)) { |
| 368 *paint = SkSVGPaint(c); | 428 *paint = SkSVGPaint(c); |
| 369 parsedValue = true; | 429 parsedValue = true; |
| 370 } else if (this->parseExpectedStringToken("none")) { | 430 } else if (this->parseExpectedStringToken("none")) { |
| 371 *paint = SkSVGPaint(SkSVGPaint::Type::kNone); | 431 *paint = SkSVGPaint(SkSVGPaint::Type::kNone); |
| 372 parsedValue = true; | 432 parsedValue = true; |
| 373 } else if (this->parseExpectedStringToken("currentColor")) { | 433 } else if (this->parseExpectedStringToken("currentColor")) { |
| 374 *paint = SkSVGPaint(SkSVGPaint::Type::kCurrentColor); | 434 *paint = SkSVGPaint(SkSVGPaint::Type::kCurrentColor); |
| 375 parsedValue = true; | 435 parsedValue = true; |
| 376 } else if (this->parseExpectedStringToken("inherit")) { | 436 } else if (this->parseExpectedStringToken("inherit")) { |
| 377 *paint = SkSVGPaint(SkSVGPaint::Type::kInherit); | 437 *paint = SkSVGPaint(SkSVGPaint::Type::kInherit); |
| 378 parsedValue = true; | 438 parsedValue = true; |
| 439 } else if (this->parseFuncIRI(&iri)) { |
| 440 *paint = SkSVGPaint(iri.value()); |
| 441 parsedValue = true; |
| 379 } | 442 } |
| 380 return parsedValue && this->parseEOSToken(); | 443 return parsedValue && this->parseEOSToken(); |
| 381 } | 444 } |
| 382 | 445 |
| 383 // https://www.w3.org/TR/SVG/painting.html#StrokeLinecapProperty | 446 // https://www.w3.org/TR/SVG/painting.html#StrokeLinecapProperty |
| 384 bool SkSVGAttributeParser::parseLineCap(SkSVGLineCap* cap) { | 447 bool SkSVGAttributeParser::parseLineCap(SkSVGLineCap* cap) { |
| 385 static const struct { | 448 static const struct { |
| 386 SkSVGLineCap::Type fType; | 449 SkSVGLineCap::Type fType; |
| 387 const char* fName; | 450 const char* fName; |
| 388 } gCapInfo[] = { | 451 } gCapInfo[] = { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 parsedValue = true; | 521 parsedValue = true; |
| 459 } | 522 } |
| 460 | 523 |
| 461 if (parsedValue && this->parseEOSToken()) { | 524 if (parsedValue && this->parseEOSToken()) { |
| 462 *points = pts; | 525 *points = pts; |
| 463 return true; | 526 return true; |
| 464 } | 527 } |
| 465 | 528 |
| 466 return false; | 529 return false; |
| 467 } | 530 } |
| OLD | NEW |