Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Static Public Member Functions | List of all members
SkParsePath Class Reference

#include <SkParsePath.h>

Public Types

enum class  PathEncoding { Absolute , Relative }
 

Static Public Member Functions

static bool FromSVGString (const char str[], SkPath *)
 
static SkString ToSVGString (const SkPath &, PathEncoding=PathEncoding::Absolute)
 

Detailed Description

Definition at line 17 of file SkParsePath.h.

Member Enumeration Documentation

◆ PathEncoding

enum class SkParsePath::PathEncoding
strong
Enumerator
Absolute 
Relative 

Definition at line 21 of file SkParsePath.h.

Member Function Documentation

◆ FromSVGString()

bool SkParsePath::FromSVGString ( const char  str[],
SkPath result 
)
static

Definition at line 103 of file SkParsePath.cpp.

103 {
104 SkPath path;
105 SkPoint first = {0, 0};
106 SkPoint c = {0, 0};
107 SkPoint lastc = {0, 0};
108 SkPoint points[3];
109 char op = '\0';
110 char previousOp = '\0';
111 bool relative = false;
112 for (;;) {
113 if (!data) {
114 // Truncated data
115 return false;
116 }
117 data = skip_ws(data);
118 if (data[0] == '\0') {
119 break;
120 }
121 char ch = data[0];
122 if (is_digit(ch) || ch == '-' || ch == '+' || ch == '.') {
123 if (op == '\0' || op == 'Z') {
124 return false;
125 }
126 } else if (is_sep(ch)) {
127 data = skip_sep(data);
128 } else {
129 op = ch;
130 relative = false;
131 if (is_lower(op)) {
132 op = (char) to_upper(op);
133 relative = true;
134 }
135 data++;
136 data = skip_sep(data);
137 }
138 switch (op) {
139 case 'M':
140 data = find_points(data, points, 1, relative, &c);
141 path.moveTo(points[0]);
142 previousOp = '\0';
143 op = 'L';
144 c = points[0];
145 break;
146 case 'L':
147 data = find_points(data, points, 1, relative, &c);
148 path.lineTo(points[0]);
149 c = points[0];
150 break;
151 case 'H': {
152 SkScalar x;
153 data = find_scalar(data, &x, relative, c.fX);
154 path.lineTo(x, c.fY);
155 c.fX = x;
156 } break;
157 case 'V': {
158 SkScalar y;
159 data = find_scalar(data, &y, relative, c.fY);
160 path.lineTo(c.fX, y);
161 c.fY = y;
162 } break;
163 case 'C':
164 data = find_points(data, points, 3, relative, &c);
165 goto cubicCommon;
166 case 'S':
167 data = find_points(data, &points[1], 2, relative, &c);
168 points[0] = c;
169 if (previousOp == 'C' || previousOp == 'S') {
170 points[0].fX -= lastc.fX - c.fX;
171 points[0].fY -= lastc.fY - c.fY;
172 }
173 cubicCommon:
174 path.cubicTo(points[0], points[1], points[2]);
175 lastc = points[1];
176 c = points[2];
177 break;
178 case 'Q': // Quadratic Bezier Curve
179 data = find_points(data, points, 2, relative, &c);
180 goto quadraticCommon;
181 case 'T':
182 data = find_points(data, &points[1], 1, relative, &c);
183 points[0] = c;
184 if (previousOp == 'Q' || previousOp == 'T') {
185 points[0].fX -= lastc.fX - c.fX;
186 points[0].fY -= lastc.fY - c.fY;
187 }
188 quadraticCommon:
189 path.quadTo(points[0], points[1]);
190 lastc = points[0];
191 c = points[1];
192 break;
193 case 'A': {
194 SkPoint radii;
195 SkScalar angle;
196 bool largeArc, sweep;
197 if ((data = find_points(data, &radii, 1, false, nullptr))
198 && (data = skip_sep(data))
199 && (data = find_scalar(data, &angle, false, 0))
200 && (data = skip_sep(data))
201 && (data = find_flag(data, &largeArc))
202 && (data = skip_sep(data))
203 && (data = find_flag(data, &sweep))
204 && (data = skip_sep(data))
205 && (data = find_points(data, &points[0], 1, relative, &c))) {
206 path.arcTo(radii, angle, (SkPath::ArcSize) largeArc,
207 (SkPathDirection) !sweep, points[0]);
208 path.getLastPt(&c);
209 }
210 } break;
211 case 'Z':
212 path.close();
213 c = first;
214 break;
215 case '~': {
216 SkPoint args[2];
217 data = find_points(data, args, 2, false, nullptr);
218 path.moveTo(args[0].fX, args[0].fY);
219 path.lineTo(args[1].fX, args[1].fY);
220 } break;
221 default:
222 return false;
223 }
224 if (previousOp == 0) {
225 first = c;
226 }
227 previousOp = op;
228 }
229 // we're good, go ahead and swap in the result
230 result->swap(path);
231 return true;
232}
static const int points[]
static int to_upper(int c)
static const char * find_flag(const char str[], bool *value)
static const char * find_scalar(const char str[], SkScalar *value, bool isRelative, SkScalar relative)
static const char * find_points(const char str[], SkPoint value[], int count, bool isRelative, SkPoint *relative)
static bool is_lower(int c)
static bool is_sep(int c)
Definition SkParse.cpp:34
static const char * skip_sep(const char str[])
Definition SkParse.cpp:64
static bool is_digit(int c)
Definition SkParse.cpp:29
static const char * skip_ws(const char str[])
Definition SkParse.cpp:56
SkPathDirection
Definition SkPathTypes.h:34
ArcSize
Definition SkPath.h:923
float SkScalar
Definition extension.cpp:12
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
double y
double x
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
float fX
x-axis value
float fY
y-axis value

◆ ToSVGString()

SkString SkParsePath::ToSVGString ( const SkPath path,
PathEncoding  encoding = PathEncoding::Absolute 
)
static

Definition at line 243 of file SkParsePath.cpp.

243 {
245
246 SkPoint current_point{0,0};
247 const auto rel_selector = encoding == PathEncoding::Relative;
248
249 const auto append_command = [&](char cmd, const SkPoint pts[], size_t count) {
250 // Use lower case cmds for relative encoding.
251 cmd += 32 * rel_selector;
252 stream.write(&cmd, 1);
253
254 for (size_t i = 0; i < count; ++i) {
255 const auto pt = pts[i] - current_point;
256 if (i > 0) {
257 stream.write(" ", 1);
258 }
259 write_scalar(&stream, pt.fX);
260 stream.write(" ", 1);
261 write_scalar(&stream, pt.fY);
262 }
263
264 SkASSERT(count > 0);
265 // For relative encoding, track the current point (otherwise == origin).
266 current_point = pts[count - 1] * rel_selector;
267 };
268
269 SkPath::Iter iter(path, false);
270 SkPoint pts[4];
271
272 for (;;) {
273 switch (iter.next(pts)) {
274 case SkPath::kConic_Verb: {
275 const SkScalar tol = SK_Scalar1 / 1024; // how close to a quad
276 SkAutoConicToQuads quadder;
277 const SkPoint* quadPts = quadder.computeQuads(pts, iter.conicWeight(), tol);
278 for (int i = 0; i < quadder.countQuads(); ++i) {
279 append_command('Q', &quadPts[i*2 + 1], 2);
280 }
281 } break;
283 append_command('M', &pts[0], 1);
284 break;
286 append_command('L', &pts[1], 1);
287 break;
289 append_command('Q', &pts[1], 2);
290 break;
292 append_command('C', &pts[1], 3);
293 break;
295 stream.write("Z", 1);
296 break;
297 case SkPath::kDone_Verb: {
298 SkString str;
299 str.resize(stream.bytesWritten());
300 stream.copyTo(str.data());
301 return str;
302 }
303 }
304 }
305}
int count
#define SkASSERT(cond)
Definition SkAssert.h:116
static bool write_scalar(SkWStream *stream, SkScalar n, uint32_t id)
#define SK_Scalar1
Definition SkScalar.h:18
const SkPoint * computeQuads(const SkConic &conic, SkScalar tol)
Definition SkGeometry.h:524
int countQuads() const
Definition SkGeometry.h:539
@ kClose_Verb
Definition SkPath.h:1463
@ kMove_Verb
Definition SkPath.h:1458
@ kConic_Verb
Definition SkPath.h:1461
@ kDone_Verb
Definition SkPath.h:1464
@ kCubic_Verb
Definition SkPath.h:1462
@ kQuad_Verb
Definition SkPath.h:1460
@ kLine_Verb
Definition SkPath.h:1459
const char * data() const
Definition SkString.h:132
void resize(size_t len)
Definition SkString.cpp:374

The documentation for this class was generated from the following files: