mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: rectify consecutive line drawings.
There are differences in behavior compared to the SVG spec, especially when consecutive line drawings occur without a moveTo command following a closePath command. Actually, thorvg didn't care the behavior in that scenario, this update ensures the scenario is handled correctly to align with the SVG specification. issue: https://github.com/thorvg/thorvg/issues/1487
This commit is contained in:
parent
06cc9709e6
commit
1f996c1382
2 changed files with 25 additions and 6 deletions
1
src/examples/resources/svg/consecutive_lines.svg
Normal file
1
src/examples/resources/svg/consecutive_lines.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m2 2h12v12H2zl12 12" fill="none" stroke-width="2" stroke="#ffca5f"/></svg>
|
After Width: | Height: | Size: 166 B |
|
@ -28,6 +28,19 @@
|
||||||
/* Internal Class Implementation */
|
/* Internal Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
static bool _outlineJump(SwOutline& outline)
|
||||||
|
{
|
||||||
|
//Make a contour if lineTo/curveTo without calling close/moveTo beforehand.
|
||||||
|
if (!outline.pts.empty()) {
|
||||||
|
outline.cntrs.push(outline.pts.count - 1);
|
||||||
|
outline.pts.push(outline.pts[outline.cntrs.last()]);
|
||||||
|
outline.types.push(SW_CURVE_TYPE_POINT);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _outlineEnd(SwOutline& outline)
|
static void _outlineEnd(SwOutline& outline)
|
||||||
{
|
{
|
||||||
if (outline.pts.empty()) return;
|
if (outline.pts.empty()) return;
|
||||||
|
@ -68,20 +81,22 @@ static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _outlineClose(SwOutline& outline)
|
static bool _outlineClose(SwOutline& outline)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
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; //First Path
|
else i = 0;
|
||||||
|
|
||||||
//Make sure there is at least one point in the current path
|
//Make sure there is at least one point in the current path
|
||||||
if (outline.pts.count == i) return;
|
if (outline.pts.count == i) return false;
|
||||||
|
|
||||||
//Close the path
|
//Close the path
|
||||||
outline.pts.push(outline.pts[i]);
|
outline.pts.push(outline.pts[i]);
|
||||||
outline.types.push(SW_CURVE_TYPE_POINT);
|
outline.types.push(SW_CURVE_TYPE_POINT);
|
||||||
outline.closed.push(true);
|
outline.closed.push(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -398,25 +413,28 @@ 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;
|
||||||
//Generate Outlines
|
//Generate Outlines
|
||||||
while (cmdCnt-- > 0) {
|
while (cmdCnt-- > 0) {
|
||||||
switch (*cmds) {
|
switch (*cmds) {
|
||||||
case PathCommand::Close: {
|
case PathCommand::Close: {
|
||||||
_outlineClose(*outline);
|
if (!closed) closed = _outlineClose(*outline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PathCommand::MoveTo: {
|
case PathCommand::MoveTo: {
|
||||||
|
if (closed) closed = false;
|
||||||
_outlineMoveTo(*outline, pts, transform);
|
_outlineMoveTo(*outline, pts, transform);
|
||||||
++pts;
|
++pts;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PathCommand::LineTo: {
|
case PathCommand::LineTo: {
|
||||||
|
if (closed) closed = _outlineJump(*outline);
|
||||||
_outlineLineTo(*outline, pts, transform);
|
_outlineLineTo(*outline, pts, transform);
|
||||||
++pts;
|
++pts;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PathCommand::CubicTo: {
|
case PathCommand::CubicTo: {
|
||||||
|
if (closed) closed = _outlineJump(*outline);
|
||||||
_outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform);
|
_outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform);
|
||||||
pts += 3;
|
pts += 3;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue