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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « experimental/svg/model/SkSVGAttributeParser.h ('k') | experimental/svg/model/SkSVGDOM.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkParse.h"
9 #include "SkSVGAttributeParser.h"
10 #include "SkSVGTypes.h"
11
12 namespace {
13
14 // TODO: these should be shared with SkParse.cpp
15
16 inline bool is_between(char c, char min, char max) {
17 SkASSERT(min <= max);
18 return (unsigned)(c - min) <= (unsigned)(max - min);
19 }
20
21 inline bool is_eos(char c) {
22 return !c;
23 }
24
25 inline bool is_ws(char c) {
26 return is_between(c, 1, 32);
27 }
28
29 inline bool is_sep(char c) {
30 return is_ws(c) || c == ',' || c == ';';
31 }
32
33 } // anonymous ns
34
35 SkSVGAttributeParser::SkSVGAttributeParser(const char attributeString[])
36 : fCurPos(attributeString) {}
37
38 template <typename F>
39 inline bool SkSVGAttributeParser::advanceWhile(F f) {
40 auto initial = fCurPos;
41 while (f(*fCurPos)) {
42 fCurPos++;
43 }
44 return fCurPos != initial;
45 }
46
47 inline bool SkSVGAttributeParser::parseEOSToken() {
48 return is_eos(*fCurPos);
49 }
50
51 inline bool SkSVGAttributeParser::parseSepToken() {
52 return this->advanceWhile(is_sep);
53 }
54
55 inline bool SkSVGAttributeParser::parseWSToken() {
56 return this->advanceWhile(is_ws);
57 }
58
59 inline bool SkSVGAttributeParser::parseExpectedStringToken(const char* expected) {
60 const char* c = fCurPos;
61
62 while (*c && *expected && *c == *expected) {
63 c++;
64 expected++;
65 }
66
67 if (*expected) {
68 return false;
69 }
70
71 fCurPos = c;
72 return true;
73 }
74
75 bool SkSVGAttributeParser::parseScalarToken(SkScalar* res) {
76 if (const char* next = SkParse::FindScalar(fCurPos, res)) {
77 fCurPos = next;
78 return true;
79 }
80 return false;
81 }
82
83 bool SkSVGAttributeParser::parseHexToken(uint32_t* res) {
84 if (const char* next = SkParse::FindHex(fCurPos, res)) {
85 fCurPos = next;
86 return true;
87 }
88 return false;
89 }
90
91 bool SkSVGAttributeParser::parseLengthUnitToken(SkSVGLength::Unit* unit) {
92 static const struct {
93 const char* fUnitName;
94 SkSVGLength::Unit fUnit;
95 } gUnitInfo[] = {
96 { "%" , SkSVGLength::Unit::kPercentage },
97 { "em", SkSVGLength::Unit::kEMS },
98 { "ex", SkSVGLength::Unit::kEXS },
99 { "px", SkSVGLength::Unit::kPX },
100 { "cm", SkSVGLength::Unit::kCM },
101 { "mm", SkSVGLength::Unit::kMM },
102 { "in", SkSVGLength::Unit::kIN },
103 { "pt", SkSVGLength::Unit::kPT },
104 { "pc", SkSVGLength::Unit::kPC },
105 };
106
107 for (size_t i = 0; i < SK_ARRAY_COUNT(gUnitInfo); ++i) {
108 if (this->parseExpectedStringToken(gUnitInfo[i].fUnitName)) {
109 *unit = gUnitInfo[i].fUnit;
110 return true;
111 }
112 }
113 return false;
114 }
115
116 bool SkSVGAttributeParser::parseNamedColorToken(SkColor* c) {
117 if (const char* next = SkParse::FindNamedColor(fCurPos, strlen(fCurPos), c)) {
118 fCurPos = next;
119 return true;
120 }
121 return false;
122 }
123
124 bool SkSVGAttributeParser::parseHexColorToken(SkColor* c) {
125 uint32_t v;
126 const char* initial = fCurPos;
127
128 if (!this->parseExpectedStringToken("#") || !this->parseHexToken(&v)) {
129 return false;
130 }
131
132 switch (fCurPos - initial) {
133 case 7:
134 // matched #xxxxxxx
135 break;
136 case 4:
137 // matched '#xxx;
138 v = ((v << 12) & 0x00f00000) |
139 ((v << 8) & 0x000ff000) |
140 ((v << 4) & 0x00000ff0) |
141 ((v << 0) & 0x0000000f);
142 break;
143 default:
144 return false;
145 }
146
147 *c = v | 0xff000000;
148 return true;
149 }
150
151 // https://www.w3.org/TR/SVG/types.html#DataTypeColor
152 bool SkSVGAttributeParser::parseColor(SkSVGColor* color) {
153 SkColor c;
154
155 // TODO: rgb(...)
156 if (this->parseHexColorToken(&c) || this->parseNamedColorToken(&c)) {
157 *color = SkSVGColor(c);
158 return true;
159 }
160
161 return false;
162 }
163
164 // https://www.w3.org/TR/SVG/types.html#DataTypeNumber
165 bool SkSVGAttributeParser::parseNumber(SkSVGNumber* number) {
166 // consume WS
167 this->parseWSToken();
168
169 SkScalar s;
170 if (this->parseScalarToken(&s)) {
171 *number = SkSVGNumber(s);
172 // consume trailing separators
173 this->parseSepToken();
174 return true;
175 }
176
177 return false;
178 }
179
180 // https://www.w3.org/TR/SVG/types.html#DataTypeLength
181 bool SkSVGAttributeParser::parseLength(SkSVGLength* length) {
182 SkScalar s;
183 SkSVGLength::Unit u = SkSVGLength::Unit::kNumber;
184
185 if (this->parseScalarToken(&s) &&
186 (this->parseLengthUnitToken(&u) || this->parseSepToken() || this->parseE OSToken())) {
187 *length = SkSVGLength(s, u);
188 // consume trailing separators
189 this->parseSepToken();
190 return true;
191 }
192
193 return false;
194 }
OLDNEW
« 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