[svg] Parse data and non-local IRIs

Not currently used, but will be used for <image> support.

Change-Id: I3bbb79c88890100901a8b85734d3a4d86a618848
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/360605
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
Tyler Denniston 2021-01-27 14:22:19 -05:00 committed by Skia Commit-Bot
parent 5c6c3be981
commit 209857c20f
2 changed files with 33 additions and 13 deletions

View File

@ -82,6 +82,8 @@ private:
template <typename F>
bool advanceWhile(F func);
bool matchStringToken(const char* token, const char** newPos = nullptr) const;
bool parseWSToken();
bool parseEOSToken();
bool parseSepToken();

View File

@ -45,6 +45,25 @@ inline bool SkSVGAttributeParser::advanceWhile(F f) {
return fCurPos != initial;
}
bool SkSVGAttributeParser::matchStringToken(const char* token, const char** newPos) const {
const char* c = fCurPos;
while (*c && *token && *c == *token) {
c++;
token++;
}
if (*token) {
return false;
}
if (newPos) {
*newPos = c;
}
return true;
}
bool SkSVGAttributeParser::parseEOSToken() {
return is_eos(*fCurPos);
}
@ -64,18 +83,12 @@ bool SkSVGAttributeParser::parseCommaWspToken() {
}
bool SkSVGAttributeParser::parseExpectedStringToken(const char* expected) {
const char* c = fCurPos;
while (*c && *expected && *c == *expected) {
c++;
expected++;
}
if (*expected) {
const char* newPos;
if (!matchStringToken(expected, &newPos)) {
return false;
}
fCurPos = c;
fCurPos = newPos;
return true;
}
@ -268,16 +281,21 @@ bool SkSVGAttributeParser::parse(SkSVGIRI* iri) {
// consume preceding whitespace
this->parseWSToken();
// we only support local fragments
if (!this->parseExpectedStringToken("#")) {
return false;
SkSVGIRI::Type iriType;
if (this->parseExpectedStringToken("#")) {
iriType = SkSVGIRI::Type::kLocal;
} else if (this->matchStringToken("data:")) {
iriType = SkSVGIRI::Type::kDataURI;
} else {
iriType = SkSVGIRI::Type::kNonlocal;
}
const auto* start = fCurPos;
this->advanceWhile([](char c) -> bool { return !is_eos(c) && c != ')'; });
if (start == fCurPos) {
return false;
}
*iri = SkSVGIRI(SkSVGIRI::Type::kLocal, SkString(start, fCurPos - start));
*iri = SkSVGIRI(iriType, SkString(start, fCurPos - start));
return true;
}