Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Unified Diff: experimental/svg/model/SkSVGAttributeParser.cpp

Issue 2202053002: [SVGDom/experimental] Initial SVGLength support (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: review Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « experimental/svg/model/SkSVGAttributeParser.h ('k') | experimental/svg/model/SkSVGDOM.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: experimental/svg/model/SkSVGAttributeParser.cpp
diff --git a/experimental/svg/model/SkSVGAttributeParser.cpp b/experimental/svg/model/SkSVGAttributeParser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..75e5d12f38558868bc2b15dfa426b15c84d1740f
--- /dev/null
+++ b/experimental/svg/model/SkSVGAttributeParser.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkParse.h"
+#include "SkSVGAttributeParser.h"
+#include "SkSVGTypes.h"
+
+namespace {
+
+// TODO: these should be shared with SkParse.cpp
+
+inline bool is_between(char c, char min, char max) {
+ SkASSERT(min <= max);
+ return (unsigned)(c - min) <= (unsigned)(max - min);
+}
+
+inline bool is_eos(char c) {
+ return !c;
+}
+
+inline bool is_ws(char c) {
+ return is_between(c, 1, 32);
+}
+
+inline bool is_sep(char c) {
+ return is_ws(c) || c == ',' || c == ';';
+}
+
+} // anonymous ns
+
+SkSVGAttributeParser::SkSVGAttributeParser(const char attributeString[])
+ : fCurPos(attributeString) {}
+
+template <typename F>
+inline bool SkSVGAttributeParser::advanceWhile(F f) {
+ auto initial = fCurPos;
+ while (f(*fCurPos)) {
+ fCurPos++;
+ }
+ return fCurPos != initial;
+}
+
+inline bool SkSVGAttributeParser::parseEOSToken() {
+ return is_eos(*fCurPos);
+}
+
+inline bool SkSVGAttributeParser::parseSepToken() {
+ return this->advanceWhile(is_sep);
+}
+
+inline bool SkSVGAttributeParser::parseWSToken() {
+ return this->advanceWhile(is_ws);
+}
+
+inline bool SkSVGAttributeParser::parseExpectedStringToken(const char* expected) {
+ const char* c = fCurPos;
+
+ while (*c && *expected && *c == *expected) {
+ c++;
+ expected++;
+ }
+
+ if (*expected) {
+ return false;
+ }
+
+ fCurPos = c;
+ return true;
+}
+
+bool SkSVGAttributeParser::parseScalarToken(SkScalar* res) {
+ if (const char* next = SkParse::FindScalar(fCurPos, res)) {
+ fCurPos = next;
+ return true;
+ }
+ return false;
+}
+
+bool SkSVGAttributeParser::parseHexToken(uint32_t* res) {
+ if (const char* next = SkParse::FindHex(fCurPos, res)) {
+ fCurPos = next;
+ return true;
+ }
+ return false;
+}
+
+bool SkSVGAttributeParser::parseLengthUnitToken(SkSVGLength::Unit* unit) {
+ static const struct {
+ const char* fUnitName;
+ SkSVGLength::Unit fUnit;
+ } gUnitInfo[] = {
+ { "%" , SkSVGLength::Unit::kPercentage },
+ { "em", SkSVGLength::Unit::kEMS },
+ { "ex", SkSVGLength::Unit::kEXS },
+ { "px", SkSVGLength::Unit::kPX },
+ { "cm", SkSVGLength::Unit::kCM },
+ { "mm", SkSVGLength::Unit::kMM },
+ { "in", SkSVGLength::Unit::kIN },
+ { "pt", SkSVGLength::Unit::kPT },
+ { "pc", SkSVGLength::Unit::kPC },
+ };
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gUnitInfo); ++i) {
+ if (this->parseExpectedStringToken(gUnitInfo[i].fUnitName)) {
+ *unit = gUnitInfo[i].fUnit;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SkSVGAttributeParser::parseNamedColorToken(SkColor* c) {
+ if (const char* next = SkParse::FindNamedColor(fCurPos, strlen(fCurPos), c)) {
+ fCurPos = next;
+ return true;
+ }
+ return false;
+}
+
+bool SkSVGAttributeParser::parseHexColorToken(SkColor* c) {
+ uint32_t v;
+ const char* initial = fCurPos;
+
+ if (!this->parseExpectedStringToken("#") || !this->parseHexToken(&v)) {
+ return false;
+ }
+
+ switch (fCurPos - initial) {
+ case 7:
+ // matched #xxxxxxx
+ break;
+ case 4:
+ // matched '#xxx;
+ v = ((v << 12) & 0x00f00000) |
+ ((v << 8) & 0x000ff000) |
+ ((v << 4) & 0x00000ff0) |
+ ((v << 0) & 0x0000000f);
+ break;
+ default:
+ return false;
+ }
+
+ *c = v | 0xff000000;
+ return true;
+}
+
+// https://www.w3.org/TR/SVG/types.html#DataTypeColor
+bool SkSVGAttributeParser::parseColor(SkSVGColor* color) {
+ SkColor c;
+
+ // TODO: rgb(...)
+ if (this->parseHexColorToken(&c) || this->parseNamedColorToken(&c)) {
+ *color = SkSVGColor(c);
+ return true;
+ }
+
+ return false;
+}
+
+// https://www.w3.org/TR/SVG/types.html#DataTypeNumber
+bool SkSVGAttributeParser::parseNumber(SkSVGNumber* number) {
+ // consume WS
+ this->parseWSToken();
+
+ SkScalar s;
+ if (this->parseScalarToken(&s)) {
+ *number = SkSVGNumber(s);
+ // consume trailing separators
+ this->parseSepToken();
+ return true;
+ }
+
+ return false;
+}
+
+// https://www.w3.org/TR/SVG/types.html#DataTypeLength
+bool SkSVGAttributeParser::parseLength(SkSVGLength* length) {
+ SkScalar s;
+ SkSVGLength::Unit u = SkSVGLength::Unit::kNumber;
+
+ if (this->parseScalarToken(&s) &&
+ (this->parseLengthUnitToken(&u) || this->parseSepToken() || this->parseEOSToken())) {
+ *length = SkSVGLength(s, u);
+ // consume trailing separators
+ this->parseSepToken();
+ return true;
+ }
+
+ return false;
+}
« no previous file with comments | « experimental/svg/model/SkSVGAttributeParser.h ('k') | experimental/svg/model/SkSVGDOM.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698