aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/SkParsePath.cpp
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2016-02-09 10:30:22 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-09 10:30:22 -0800
commitf1d415188ffb4c34e2886c2cfceb363a148333f1 (patch)
tree07cbfee906d827a1f4731d68812c45d46ea78c29 /src/utils/SkParsePath.cpp
parent719c48050127b2a18793bbcfa0dc49c2df5f080a (diff)
Add unit test to feed valid SVG sequences to make sure that
path strings can be parsed without returning an error. Draw the output through Skia and SVG to make sure they are parsed correctly. R=fmalita@chromium.org BUG=skia:4549 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1675053002 Review URL: https://codereview.chromium.org/1675053002
Diffstat (limited to 'src/utils/SkParsePath.cpp')
-rw-r--r--src/utils/SkParsePath.cpp49
1 files changed, 26 insertions, 23 deletions
diff --git a/src/utils/SkParsePath.cpp b/src/utils/SkParsePath.cpp
index c0f39aa06f..8baa6611ee 100644
--- a/src/utils/SkParsePath.cpp
+++ b/src/utils/SkParsePath.cpp
@@ -40,7 +40,9 @@ static const char* skip_ws(const char str[]) {
}
static const char* skip_sep(const char str[]) {
- SkASSERT(str);
+ if (!str) {
+ return nullptr;
+ }
while (is_sep(*str))
str++;
return str;
@@ -61,6 +63,9 @@ static const char* find_points(const char str[], SkPoint value[], int count,
static const char* find_scalar(const char str[], SkScalar* value,
bool isRelative, SkScalar relative) {
str = SkParse::FindScalar(str, value);
+ if (!str) {
+ return nullptr;
+ }
if (isRelative) {
*value += relative;
}
@@ -70,7 +75,7 @@ static const char* find_scalar(const char str[], SkScalar* value,
bool SkParsePath::FromSVGString(const char data[], SkPath* result) {
SkPath path;
- SkPoint f = {0, 0};
+ SkPoint first = {0, 0};
SkPoint c = {0, 0};
SkPoint lastc = {0, 0};
SkPoint points[3];
@@ -107,6 +112,7 @@ bool SkParsePath::FromSVGString(const char data[], SkPath* result) {
case 'M':
data = find_points(data, points, 1, relative, &c);
path.moveTo(points[0]);
+ previousOp = '\0';
op = 'L';
c = points[0];
break;
@@ -147,10 +153,10 @@ bool SkParsePath::FromSVGString(const char data[], SkPath* result) {
goto quadraticCommon;
case 'T':
data = find_points(data, &points[1], 1, relative, &c);
- points[0] = points[1];
+ points[0] = c;
if (previousOp == 'Q' || previousOp == 'T') {
- points[0].fX = c.fX * 2 - lastc.fX;
- points[0].fY = c.fY * 2 - lastc.fY;
+ points[0].fX -= lastc.fX - c.fX;
+ points[0].fY -= lastc.fY - c.fY;
}
quadraticCommon:
path.quadTo(points[0], points[1]);
@@ -159,27 +165,24 @@ bool SkParsePath::FromSVGString(const char data[], SkPath* result) {
break;
case 'A': {
SkPoint radii;
- data = find_points(data, &radii, 1, false, nullptr);
SkScalar angle, largeArc, sweep;
- data = find_scalar(data, &angle, false, 0);
- data = find_scalar(data, &largeArc, false, 0);
- data = find_scalar(data, &sweep, false, 0);
- data = find_points(data, &points[0], 1, relative, &c);
- path.arcTo(radii, angle, (SkPath::ArcSize) SkToBool(largeArc),
- (SkPath::Direction) !SkToBool(sweep), points[0]);
+ 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 = skip_sep(data))
+ && (data = find_scalar(data, &sweep, false, 0))
+ && (data = skip_sep(data))
+ && (data = find_points(data, &points[0], 1, relative, &c))) {
+ path.arcTo(radii, angle, (SkPath::ArcSize) SkToBool(largeArc),
+ (SkPath::Direction) !SkToBool(sweep), points[0]);
+ path.getLastPt(&c);
+ }
} break;
case 'Z':
path.close();
-#if 0 // !!! still a bug?
- if (fPath.isEmpty() && (f.fX != 0 || f.fY != 0)) {
- c.fX -= SkScalar.Epsilon; // !!! enough?
- fPath.moveTo(c);
- fPath.lineTo(f);
- fPath.close();
- }
-#endif
- c = f;
- op = '\0';
+ c = first;
break;
case '~': {
SkPoint args[2];
@@ -191,7 +194,7 @@ bool SkParsePath::FromSVGString(const char data[], SkPath* result) {
return false;
}
if (previousOp == 0) {
- f = c;
+ first = c;
}
previousOp = op;
}