sw_engine: stabilize the contour composition logic.

there has been a logical error that breaks the contour
composition context. This fixes it.

issue: https://github.com/thorvg/thorvg/issues/2093
This commit is contained in:
Hermet Park 2024-03-27 12:14:05 +09:00
parent c8ddc316db
commit 68e4d35f7b

View file

@ -29,35 +29,24 @@
/************************************************************************/ /************************************************************************/
static bool _outlineJump(SwOutline& outline) static bool _outlineEnd(SwOutline& outline)
{ {
//Make a contour if lineTo/curveTo without calling close/moveTo beforehand. //Make a contour if lineTo/curveTo without calling close/moveTo beforehand.
if (!outline.pts.empty()) { if (outline.pts.empty()) return false;
outline.cntrs.push(outline.pts.count - 1); outline.cntrs.push(outline.pts.count - 1);
outline.pts.push(outline.pts[outline.cntrs.last()]); outline.closed.push(false);
outline.types.push(SW_CURVE_TYPE_POINT);
}
return false; return false;
} }
static void _outlineEnd(SwOutline& outline) static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform, bool closed = false)
{ {
if (outline.pts.empty()) return; //make it a contour, if the last contour is not closed yet.
outline.cntrs.push(outline.pts.count - 1); if (!closed) _outlineEnd(outline);
outline.closed.push(false);
}
static void _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform)
{
if (outline.pts.count > 0) {
outline.cntrs.push(outline.pts.count - 1);
outline.closed.push(false);
}
outline.pts.push(mathTransform(to, transform)); outline.pts.push(mathTransform(to, transform));
outline.types.push(SW_CURVE_TYPE_POINT); outline.types.push(SW_CURVE_TYPE_POINT);
return false;
} }
@ -84,7 +73,6 @@ static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point*
static bool _outlineClose(SwOutline& outline) static bool _outlineClose(SwOutline& outline)
{ {
uint32_t i; uint32_t i;
if (outline.cntrs.count > 0) i = outline.cntrs.last() + 1; if (outline.cntrs.count > 0) i = outline.cntrs.last() + 1;
else i = 0; else i = 0;
@ -93,6 +81,7 @@ static bool _outlineClose(SwOutline& outline)
//Close the path //Close the path
outline.pts.push(outline.pts[i]); outline.pts.push(outline.pts[i]);
outline.cntrs.push(outline.pts.count - 1);
outline.types.push(SW_CURVE_TYPE_POINT); outline.types.push(SW_CURVE_TYPE_POINT);
outline.closed.push(true); outline.closed.push(true);
@ -414,6 +403,7 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
shape->outline = mpoolReqOutline(mpool, tid); shape->outline = mpoolReqOutline(mpool, tid);
auto outline = shape->outline; auto outline = shape->outline;
bool closed = false; bool closed = false;
//Generate Outlines //Generate Outlines
while (cmdCnt-- > 0) { while (cmdCnt-- > 0) {
switch (*cmds) { switch (*cmds) {
@ -422,19 +412,18 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
break; break;
} }
case PathCommand::MoveTo: { case PathCommand::MoveTo: {
if (closed) closed = false; closed = _outlineMoveTo(*outline, pts, transform, closed);
_outlineMoveTo(*outline, pts, transform);
++pts; ++pts;
break; break;
} }
case PathCommand::LineTo: { case PathCommand::LineTo: {
if (closed) closed = _outlineJump(*outline); if (closed) closed = _outlineEnd(*outline);
_outlineLineTo(*outline, pts, transform); _outlineLineTo(*outline, pts, transform);
++pts; ++pts;
break; break;
} }
case PathCommand::CubicTo: { case PathCommand::CubicTo: {
if (closed) closed = _outlineJump(*outline); if (closed) closed = _outlineEnd(*outline);
_outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform); _outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform);
pts += 3; pts += 3;
break; break;
@ -443,7 +432,7 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
++cmds; ++cmds;
} }
_outlineEnd(*outline); if (!closed) _outlineEnd(*outline);
outline->fillRule = rshape->rule; outline->fillRule = rshape->rule;
shape->outline = outline; shape->outline = outline;