sw_engine: ++stability

cut the Bezier curve based on the number of points
and transform it into a straight line when it's very small.

issue: https://github.com/thorvg/thorvg/issues/2759
This commit is contained in:
Hermet Park 2024-10-03 16:26:16 +09:00
parent bceedf081f
commit aece166cb7
2 changed files with 17 additions and 27 deletions

View file

@ -690,31 +690,27 @@ static void _decomposeOutline(RleWorker& rw)
auto start = UPSCALE(outline->pts[first]);
auto pt = outline->pts.data + first;
auto types = outline->types.data + first;
++types;
_moveTo(rw, UPSCALE(outline->pts[first]));
while (pt < limit) {
++pt;
++types;
//emit a single line_to
if (types[0] == SW_CURVE_TYPE_POINT) {
++pt;
++types;
_lineTo(rw, UPSCALE(*pt));
//types cubic
} else {
pt += 2;
types += 2;
if (pt <= limit) {
_cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0]));
continue;
}
_cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start);
goto close;
pt += 3;
types += 3;
if (pt <= limit) _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0]));
else if (pt - 1 == limit) _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start);
else goto close;
}
}
_lineTo(rw, start);
close:
_lineTo(rw, start);
first = last + 1;
}
}

View file

@ -845,31 +845,25 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline)
//A contour cannot start with a cubic control point
if (type == SW_CURVE_TYPE_CUBIC) return false;
++types;
auto closed = outline.closed.data ? outline.closed.data[i]: false;
_beginSubPath(*stroke, start, closed);
while (pt < limit) {
++pt;
++types;
//emit a single line_to
if (types[0] == SW_CURVE_TYPE_POINT) {
++pt;
++types;
_lineTo(*stroke, *pt);
//types cubic
} else {
if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false;
pt += 2;
types += 2;
if (pt <= limit) {
_cubicTo(*stroke, pt[-2], pt[-1], pt[0]);
continue;
}
_cubicTo(*stroke, pt[-2], pt[-1], start);
goto close;
pt += 3;
types += 3;
if (pt <= limit) _cubicTo(*stroke, pt[-2], pt[-1], pt[0]);
else if (pt - 1 == limit) _cubicTo(*stroke, pt[-2], pt[-1], start);
else goto close;
}
}
close: