sw_engine: revised the trimpath dash line logic

Support the TrimPath modes (individual/simultaneous)
internally in the engine to handle them efficiently.
This commit is contained in:
Hermet Park 2024-03-31 12:40:44 +09:00 committed by Hermet Park
parent 75477f502e
commit c74cd42363
4 changed files with 38 additions and 9 deletions

View file

@ -897,7 +897,7 @@ static void _updateTrimpath(TVG_UNUSED LottieGroup* parent, LottieObject** child
end = (length * end) + pbegin;
}
P(ctx->propagator)->strokeTrim(begin, end);
P(ctx->propagator)->strokeTrim(begin, end, false);
//TODO: individual or simultaenous mode
}

View file

@ -105,6 +105,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
//draw the current line fully
} else if (len < dash.curLen) {
dash.curLen -= len;
if (!dash.curOpGap) {
@ -114,6 +115,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
}
_outlineLineTo(*dash.outline, to, transform);
}
//draw the current line partially
} else {
while (len - dash.curLen > 0.0001f) {
Line left, right;
@ -162,6 +164,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to};
auto len = bezLength(cur);
//draw the current line fully
if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
} else if (len < dash.curLen) {
@ -173,6 +176,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
}
_outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform);
}
//draw the current line partially
} else {
while ((len - dash.curLen) > 0.0001f) {
Bezier left, right;
@ -222,7 +226,15 @@ static void _dashClose(SwDashStroke& dash, const Matrix* transform)
}
static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts, const Matrix* transform)
static void _dashMoveTo(SwDashStroke& dash, const Point* pts)
{
dash.ptCur = *pts;
dash.ptStart = *pts;
dash.move = true;
}
static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts)
{
dash.curIdx = offIdx % dash.cnt;
dash.curLen = dash.pattern[dash.curIdx] - offset;
@ -257,7 +269,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
//default
if (end > begin) {
if (begin > 0) dash.cnt += 4;
if (begin > 0.0f) dash.cnt += 4;
else dash.cnt += 2;
//looping
} else dash.cnt += 3;
@ -275,7 +287,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
dash.pattern[0] = 0; //zero dash to start with a space.
dash.pattern[1] = begin;
dash.pattern[2] = end - begin;
dash.pattern[3] = length - (end - begin);
dash.pattern[3] = length - end;
}
trimmed = true;
@ -304,14 +316,22 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
dash.outline = mpoolReqDashOutline(mpool, tid);
while (cmdCnt-- > 0) {
//must begin with moveTo
if (cmds[0] == PathCommand::MoveTo) {
_dashMoveTo(dash, offIdx, offset, pts);
cmds++;
pts++;
}
while (--cmdCnt > 0) {
switch (*cmds) {
case PathCommand::Close: {
_dashClose(dash, transform);
break;
}
case PathCommand::MoveTo: {
_dashMoveTo(dash, offIdx, offset, pts, transform);
if (rshape->stroke->trim.individual) _dashMoveTo(dash, pts);
else _dashMoveTo(dash, offIdx, offset, pts);
++pts;
break;
}
@ -349,13 +369,19 @@ static float _outlineLength(const RenderShape* rshape)
const Point* close = nullptr;
auto length = 0.0f;
auto slength = 0.0f;
auto simutaneous = !rshape->stroke->trim.individual;
//Compute the whole length
while (cmdCnt-- > 0) {
switch (*cmds) {
case PathCommand::Close: {
length += mathLength(pts - 1, close);
++pts;
//retrieve the max length of the shape if the simultaneous mode.
if (simutaneous && slength < length) {
slength = length;
length = 0.0f;
}
break;
}
case PathCommand::MoveTo: {
@ -376,7 +402,8 @@ static float _outlineLength(const RenderShape* rshape)
}
++cmds;
}
return length;
if (simutaneous && slength > length) return slength;
else return length;
}

View file

@ -161,6 +161,7 @@ struct RenderStroke
struct {
float begin = 0.0f;
float end = 1.0f;
bool individual = false;
} trim;
~RenderStroke()

View file

@ -203,7 +203,7 @@ struct Shape::Impl
return true;
}
bool strokeTrim(float begin, float end)
bool strokeTrim(float begin, float end, bool individual)
{
if (!rs.stroke) {
if (begin == 0.0f && end == 1.0f) return true;
@ -214,6 +214,7 @@ struct Shape::Impl
rs.stroke->trim.begin = begin;
rs.stroke->trim.end = end;
rs.stroke->trim.individual = individual;
flag |= RenderUpdateFlag::Stroke;
return true;