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 |