diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index dd100833..5ceecff5 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -581,6 +581,13 @@ void LottieBuilder::updatePath(LottieGroup* parent, LottieObject** child, float } +static void _close(Array& pts, const Point& p, bool round) +{ + if (round && tvg::zero(pts.last() - pts[pts.count - 2])) pts[pts.count - 2] = p; + pts.last() = p; +} + + static void _updateStar(TVG_UNUSED LottieGroup* parent, LottiePolyStar* star, Matrix* transform, const LottieRoundnessModifier* roundness, const LottieOffsetModifier* offsetPath, float frameNo, Shape* merging, LottieExpressions* exps) { static constexpr auto POLYSTAR_MAGIC_NUMBER = 0.47829f / 0.28f; @@ -695,6 +702,8 @@ static void _updateStar(TVG_UNUSED LottieGroup* parent, LottiePolyStar* star, Ma angle += dTheta * direction; longSegment = !longSegment; } + //ensure proper shape closure - important for modifiers that behave differently for degenerate (linear) vs curved cubics + _close(P(shape)->rs.path.pts, in, hasRoundness); shape->close(); if (roundedCorner) { @@ -777,6 +786,8 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr } angle += anglePerPoint * direction; } + //ensure proper shape closure - important for modifiers that behave differently for degenerate (linear) vs curved cubics + _close(P(shape)->rs.path.pts, in, hasRoundness); shape->close(); if (roundedCorner) { diff --git a/src/loaders/lottie/tvgLottieModifier.cpp b/src/loaders/lottie/tvgLottieModifier.cpp index 0fa00aa3..a5c01401 100644 --- a/src/loaders/lottie/tvgLottieModifier.cpp +++ b/src/loaders/lottie/tvgLottieModifier.cpp @@ -46,16 +46,9 @@ static void _roundCorner(Array& cmds, Array& pts, const Poin } -static bool _zero(const Point& p1, const Point& p2) -{ - constexpr float epsilon = 1e-3f; - return fabsf(p1.x / p2.x - 1.0f) < epsilon && fabsf(p1.y / p2.y - 1.0f) < epsilon; -} - - static bool _intersect(const Line& line1, const Line& line2, Point& intersection, bool& inside) { - if (_zero(line1.pt2, line2.pt1)) { + if (tvg::zero(line1.pt2 - line2.pt1)) { intersection = line1.pt2; inside = true; return true; @@ -162,7 +155,7 @@ void LottieOffsetModifier::line(const PathCommand* inCmds, uint32_t inCmdsCnt, c Line nextLine = state.firstLine; if (inCmds[currentCmd + 1] == PathCommand::LineTo) nextLine = _offset(inPts[currentPt + degenerated], inPts[currentPt + 1 + degenerated], offset); else if (inCmds[currentCmd + 1] == PathCommand::CubicTo) nextLine = _offset(inPts[currentPt + 1 + degenerated], inPts[currentPt + 2 + degenerated], offset); - else if (inCmds[currentCmd + 1] == PathCommand::Close && !_zero(inPts[currentPt + degenerated], inPts[state.movetoInIndex + degenerated])) + else if (inCmds[currentCmd + 1] == PathCommand::Close && !tvg::zero(inPts[currentPt + degenerated] - inPts[state.movetoInIndex + degenerated])) nextLine = _offset(inPts[currentPt + degenerated], inPts[state.movetoInIndex + degenerated], offset); corner(state.line, nextLine, state.movetoOutIndex, inCmds[currentCmd + 1] == PathCommand::Close, outCmds, outPts); @@ -368,7 +361,7 @@ bool LottieOffsetModifier::modifyPath(const PathCommand* inCmds, uint32_t inCmds iPt += 3; } else { - if (!_zero(inPts[iPt - 1], inPts[state.movetoInIndex])) { + if (!tvg::zero(inPts[iPt - 1] - inPts[state.movetoInIndex])) { outCmds.push(PathCommand::LineTo); corner(state.line, state.firstLine, state.movetoOutIndex, true, outCmds, outPts); }