gl_engine: fix line join while dashing

While dashing, changing the path command each time caused
a new 'move to' command to be added, even when dash segments
across different path commands should have been connected.

@Issue: https://github.com/thorvg/thorvg/issues/3231
This commit is contained in:
Mira Grudzinska 2025-02-25 00:16:02 +01:00 committed by Hermet Park
parent 9a2d1136de
commit 2c73da0e20
2 changed files with 37 additions and 10 deletions

View file

@ -1960,6 +1960,7 @@ DashStroke::DashStroke(Array<PathCommand> *cmds, Array<Point> *pts, uint32_t das
mCurrLen(),
mCurrIdx(),
mCurOpGap(false),
mMove(true),
mPtStart(),
mPtCur()
{
@ -1999,6 +2000,7 @@ void DashStroke::doStroke(const PathCommand *cmds, uint32_t cmd_count, const Poi
mCurrIdx = idx;
mCurrLen = mDashPattern[idx] - offset;
mCurOpGap = gap;
mMove = true;
mPtStart = mPtCur = *pts;
pts++;
break;
@ -2024,23 +2026,31 @@ void DashStroke::dashLineTo(const Point& to)
{
auto len = length(mPtCur - to);
if (len < mCurrLen) {
if (tvg::zero(len)) {
this->moveTo(mPtCur);
} else if (len <= mCurrLen) {
mCurrLen -= len;
if (!mCurOpGap) {
if (mMove) {
this->moveTo(mPtCur);
mMove = false;
}
this->lineTo(to);
}
} else {
Line curr = {mPtCur, to};
while (len > mCurrLen) {
while (len - mCurrLen > 0.0001f) {
Line right;
if (mCurrLen > 0.0f) {
Line left;
curr.split(mCurrLen, left, right);
len -= mCurrLen;
if (!mCurOpGap) {
if (mMove || mDashPattern[mCurrIdx] - mCurrLen < FLOAT_EPSILON) {
this->moveTo(left.pt1);
mMove = false;
}
this->lineTo(left.pt2);
}
} else right = curr;
@ -2049,10 +2059,14 @@ void DashStroke::dashLineTo(const Point& to)
mCurOpGap = !mCurOpGap;
curr = right;
mPtCur = curr.pt1;
mMove = true;
}
mCurrLen -= len;
if (!mCurOpGap) {
if (mMove) {
this->moveTo(curr.pt1);
mMove = false;
}
this->lineTo(curr.pt2);
}
@ -2077,21 +2091,29 @@ void DashStroke::dashCubicTo(const Point& cnt1, const Point& cnt2, const Point&
auto len = cur.length();
if (len < mCurrLen) {
if (tvg::zero(len)) {
this->moveTo(mPtCur);
} else if (len <= mCurrLen) {
mCurrLen -= len;
if (!mCurOpGap) {
if (mMove) {
this->moveTo(mPtCur);
mMove = false;
}
this->cubicTo(cnt1, cnt2, end);
}
} else {
while (len > mCurrLen) {
while (len - mCurrLen > 0.0001f) {
Bezier right;
if (mCurrLen > 0.0f) {
Bezier left;
cur.split(mCurrLen, left, right);
len -= mCurrLen;
if (!mCurOpGap) {
if (mMove || mDashPattern[mCurrIdx] - mCurrLen < FLOAT_EPSILON) {
this->moveTo(left.start);
mMove = false;
}
this->cubicTo(left.ctrl1, left.ctrl2, left.end);
}
} else right = cur;
@ -2100,11 +2122,15 @@ void DashStroke::dashCubicTo(const Point& cnt1, const Point& cnt2, const Point&
mCurOpGap = !mCurOpGap;
cur = right;
mPtCur = cur.start;
mMove = true;
}
mCurrLen -= len;
if (!mCurOpGap) {
if (mMove) {
this->moveTo(cur.start);
mMove = false;
}
this->cubicTo(cur.ctrl1, cur.ctrl2, cur.end);
}

View file

@ -139,6 +139,7 @@ private:
float mCurrLen;
int32_t mCurrIdx;
bool mCurOpGap;
bool mMove;
Point mPtStart;
Point mPtCur;
};