lottie: handle rounded polygons

The implementation of rounded polygons was
mistakenly omitted, now has been added.

@Issue: https://github.com/thorvg/thorvg/issues/2624
This commit is contained in:
Mira Grudzinska 2024-08-09 19:30:44 +02:00 committed by Hermet Park
parent 55d248a31d
commit 49f586b3e7

View file

@ -809,35 +809,42 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans
} }
static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float frameNo, Shape* merging, LottieExpressions* exps) static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float roundness, float frameNo, Shape* merging, LottieExpressions* exps)
{ {
static constexpr auto POLYGON_MAGIC_NUMBER = 0.25f; static constexpr auto POLYGON_MAGIC_NUMBER = 0.25f;
auto ptsCnt = size_t(floor(star->ptsCnt(frameNo, exps))); auto ptsCnt = size_t(floor(star->ptsCnt(frameNo, exps)));
auto radius = star->outerRadius(frameNo, exps); auto radius = star->outerRadius(frameNo, exps);
auto roundness = star->outerRoundness(frameNo, exps) * 0.01f; auto outerRoundness = star->outerRoundness(frameNo, exps) * 0.01f;
auto angle = deg2rad(-90.0f); auto angle = deg2rad(-90.0f);
auto anglePerPoint = 2.0f * MATH_PI / float(ptsCnt); auto anglePerPoint = 2.0f * MATH_PI / float(ptsCnt);
auto direction = star->clockwise ? 1.0f : -1.0f; auto direction = star->clockwise ? 1.0f : -1.0f;
auto hasRoundness = false; auto hasRoundness = !tvg::zero(outerRoundness);
bool roundedCorner = roundness > ROUNDNESS_EPSILON && !hasRoundness;
auto x = radius * cosf(angle); auto x = radius * cosf(angle);
auto y = radius * sinf(angle); auto y = radius * sinf(angle);
angle += anglePerPoint * direction; angle += anglePerPoint * direction;
if (tvg::zero(roundness)) { Shape* shape;
P(merging)->rs.path.pts.reserve(ptsCnt + 2); if (roundedCorner) {
P(merging)->rs.path.cmds.reserve(ptsCnt + 3); shape = star->pooling();
shape->reset();
} else { } else {
P(merging)->rs.path.pts.reserve(ptsCnt * 3 + 2); shape = merging;
P(merging)->rs.path.cmds.reserve(ptsCnt + 3); if (hasRoundness) {
hasRoundness = true; P(shape)->rs.path.pts.reserve(ptsCnt * 3 + 2);
P(shape)->rs.path.cmds.reserve(ptsCnt + 3);
} else {
P(shape)->rs.path.pts.reserve(ptsCnt + 2);
P(shape)->rs.path.cmds.reserve(ptsCnt + 3);
}
} }
Point in = {x, y}; Point in = {x, y};
if (transform) in *= *transform; if (transform) in *= *transform;
merging->moveTo(in.x, in.y); shape->moveTo(in.x, in.y);
for (size_t i = 0; i < ptsCnt; i++) { for (size_t i = 0; i < ptsCnt; i++) {
auto previousX = x; auto previousX = x;
@ -853,10 +860,10 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr
auto cp2Dx = cosf(cp2Theta); auto cp2Dx = cosf(cp2Theta);
auto cp2Dy = sinf(cp2Theta); auto cp2Dy = sinf(cp2Theta);
auto cp1x = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dx; auto cp1x = radius * outerRoundness * POLYGON_MAGIC_NUMBER * cp1Dx;
auto cp1y = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dy; auto cp1y = radius * outerRoundness * POLYGON_MAGIC_NUMBER * cp1Dy;
auto cp2x = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dx; auto cp2x = radius * outerRoundness * POLYGON_MAGIC_NUMBER * cp2Dx;
auto cp2y = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dy; auto cp2y = radius * outerRoundness * POLYGON_MAGIC_NUMBER * cp2Dy;
Point in2 = {previousX - cp1x, previousY - cp1y}; Point in2 = {previousX - cp1x, previousY - cp1y};
Point in3 = {x + cp2x, y + cp2y}; Point in3 = {x + cp2x, y + cp2y};
@ -866,15 +873,17 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr
in3 *= *transform; in3 *= *transform;
in4 *= *transform; in4 *= *transform;
} }
merging->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); shape->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y);
} else { } else {
Point in = {x, y}; Point in = {x, y};
if (transform) in *= *transform; if (transform) in *= *transform;
merging->lineTo(in.x, in.y); shape->lineTo(in.x, in.y);
} }
angle += anglePerPoint * direction; angle += anglePerPoint * direction;
} }
merging->close(); shape->close();
if (roundedCorner) _applyRoundedCorner(shape, merging, 0.0f, roundness, false);
} }
@ -897,12 +906,12 @@ static void _updatePolystar(LottieGroup* parent, LottieObject** child, float fra
auto shape = star->pooling(); auto shape = star->pooling();
shape->reset(); shape->reset();
if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, shape, exps); if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, shape, exps);
else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, shape, exps); else _updatePolygon(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, shape, exps);
_repeat(parent, shape, ctx); _repeat(parent, shape, ctx);
} else { } else {
_draw(parent, star, ctx); _draw(parent, star, ctx);
if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, ctx->merging, exps); if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, ctx->merging, exps);
else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, ctx->merging, exps); else _updatePolygon(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, ctx->merging, exps);
P(ctx->merging)->update(RenderUpdateFlag::Path); P(ctx->merging)->update(RenderUpdateFlag::Path);
} }
} }