| Index: src/utils/SkParsePath.cpp
|
| diff --git a/src/utils/SkParsePath.cpp b/src/utils/SkParsePath.cpp
|
| index c0f39aa06fd74b93d4989234472ea4c7496211cf..8baa6611ee437abfbc0a058c56e18822501dd6e6 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;
|
| }
|
|
|