Parse arc flags correctly when there is no optional ws
Today, if the arc command flags are not separated by whitespace, the parser fails to parse the string. I noticed this when trying to parse a path similar to the one in the test case when playing around with PathKit.FromSVGString. Change-Id: I40967c07dfa03d76d26ac2e060b3ef7ac488d0fc Reviewed-on: https://skia-review.googlesource.com/c/skia/+/520256 Reviewed-by: Florin Malita <fmalita@google.com> Commit-Queue: Dan Field <dnfield@google.com>
This commit is contained in:
parent
bd11ec8eab
commit
23cb294413
@ -72,6 +72,22 @@ static const char* find_scalar(const char str[], SkScalar* value,
|
||||
return str;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/SVG11/paths.html#PathDataBNF
|
||||
//
|
||||
// flag:
|
||||
// "0" | "1"
|
||||
static const char* find_flag(const char str[], bool* value) {
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
if (str[0] != '1' && str[0] != '0') {
|
||||
return nullptr;
|
||||
}
|
||||
*value = str[0] != '0';
|
||||
str = skip_sep(str + 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
bool SkParsePath::FromSVGString(const char data[], SkPath* result) {
|
||||
SkPath path;
|
||||
SkPoint first = {0, 0};
|
||||
@ -164,18 +180,19 @@ bool SkParsePath::FromSVGString(const char data[], SkPath* result) {
|
||||
break;
|
||||
case 'A': {
|
||||
SkPoint radii;
|
||||
SkScalar angle, largeArc, sweep;
|
||||
SkScalar angle;
|
||||
bool largeArc, sweep;
|
||||
if ((data = find_points(data, &radii, 1, false, nullptr))
|
||||
&& (data = skip_sep(data))
|
||||
&& (data = find_scalar(data, &angle, false, 0))
|
||||
&& (data = skip_sep(data))
|
||||
&& (data = find_scalar(data, &largeArc, false, 0))
|
||||
&& (data = find_flag(data, &largeArc))
|
||||
&& (data = skip_sep(data))
|
||||
&& (data = find_scalar(data, &sweep, false, 0))
|
||||
&& (data = find_flag(data, &sweep))
|
||||
&& (data = skip_sep(data))
|
||||
&& (data = find_points(data, &points[0], 1, relative, &c))) {
|
||||
path.arcTo(radii, angle, (SkPath::ArcSize) SkToBool(largeArc),
|
||||
(SkPathDirection) !SkToBool(sweep), points[0]);
|
||||
path.arcTo(radii, angle, (SkPath::ArcSize) largeArc,
|
||||
(SkPathDirection) !sweep, points[0]);
|
||||
path.getLastPt(&c);
|
||||
}
|
||||
} break;
|
||||
|
@ -128,3 +128,13 @@ DEF_TEST(ParsePathOptionalCommand, r) {
|
||||
REPORTER_ASSERT(r, path.countPoints() == gTests[i].fPoints);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(ParsePathArcFlags, r) {
|
||||
const char* arcs = "M10 10a2.143 2.143 0 100-4.285 2.143 2.143 0 000 4.286";
|
||||
SkPath path;
|
||||
REPORTER_ASSERT(r, SkParsePath::FromSVGString(arcs, &path));
|
||||
// Arcs decompose to two conics.
|
||||
REPORTER_ASSERT(r, path.countVerbs() == 5);
|
||||
// One for move, 2x per conic.
|
||||
REPORTER_ASSERT(r, path.countPoints() == 9);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user