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

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: cleanup 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
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 : fChr(attributeString) {}
37
38 template <typename F>
39 inline bool SkSVGAttributeParser::advanceWhile(F f) {
40 auto initial = fChr;
41 while (f(*fChr)) {
42 fChr++;
43 }
44 return fChr != initial;
45 }
46
47 inline bool SkSVGAttributeParser::parseEOSAtom() {
48 return is_eos(*fChr);
49 }
50
51 inline bool SkSVGAttributeParser::parseSepAtom() {
52 return this->advanceWhile(is_sep);
53 }
54
55 inline bool SkSVGAttributeParser::parseWSAtom() {
56 return this->advanceWhile(is_ws);
57 }
58
robertphillips 2016/08/02 22:25:56 consumeExpectedToken ?
f(malita) 2016/08/03 16:50:51 Done (parseExpectedStringToken for consistency wit
59 inline bool SkSVGAttributeParser::parseStringAtom(const char* expected) {
60 const char* c = fChr;
61
62 while (*c && *expected && *c == *expected) {
63 c++;
64 expected++;
65 }
66
67 if (*expected) {
68 return false;
69 }
70
71 fChr = c;
72 return true;
73 }
74
75 bool SkSVGAttributeParser::parseScalarAtom(SkScalar* res) {
76 if (const char* next = SkParse::FindScalar(fChr, res)) {
77 fChr = next;
78 return true;
79 }
80 return false;
81 }
82
83 bool SkSVGAttributeParser::parseHexAtom(uint32_t* res) {
84 if (const char* next = SkParse::FindHex(fChr, res)) {
85 fChr = next;
86 return true;
87 }
88 return false;
89 }
90
91 bool SkSVGAttributeParser::parseLengthUnitAtom(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->parseStringAtom(gUnitInfo[i].fUnitName)) {
109 *unit = gUnitInfo[i].fUnit;
110 return true;
111 }
112 }
113 return false;
114 }
115
116 bool SkSVGAttributeParser::parseNamedColorAtom(SkColor* c) {
117 if (const char* next = SkParse::FindNamedColor(fChr, strlen(fChr), c)) {
118 fChr = next;
119 return true;
120 }
121 return false;
122 }
123
124 bool SkSVGAttributeParser::parseHexColorAtom(SkColor* c) {
125 uint32_t v;
126 const char* initial = fChr;
127
128 if (!this->parseStringAtom("#") || !this->parseHexAtom(&v)) {
129 return false;
130 }
131
132 switch (fChr - 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->parseHexColorAtom(&c) || this->parseNamedColorAtom(&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->parseWSAtom();
168
169 SkScalar s;
170 if (this->parseScalarAtom(&s)) {
171 *number = SkSVGNumber(s);
172 // consume trailing separators
173 this->parseSepAtom();
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->parseScalarAtom(&s) &&
186 (this->parseLengthUnitAtom(&u) || this->parseSepAtom() || this->parseEOS Atom())) {
187 *length = SkSVGLength(s, u);
188 // consume trailing separators
189 this->parseSepAtom();
190 return true;
191 }
192
193 return false;
194 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698