mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
lottie/expressions: apply expressions to missing properites.
This commit is contained in:
parent
81ff238fef
commit
c0582d8d2d
2 changed files with 60 additions and 62 deletions
|
@ -150,8 +150,8 @@ static bool _updateTransform(LottieTransform* transform, float frameNo, bool aut
|
|||
_rotationZ(&matrix, transform->rotation(frameNo, exps) + angle);
|
||||
|
||||
if (transform->rotationEx) {
|
||||
_rotateY(&matrix, transform->rotationEx->y(frameNo));
|
||||
_rotateX(&matrix, transform->rotationEx->x(frameNo));
|
||||
_rotateY(&matrix, transform->rotationEx->y(frameNo, exps));
|
||||
_rotateX(&matrix, transform->rotationEx->x(frameNo, exps));
|
||||
}
|
||||
|
||||
auto scale = transform->scale(frameNo, exps);
|
||||
|
@ -246,7 +246,7 @@ static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameN
|
|||
|
||||
static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext* ctx, LottieExpressions* exps)
|
||||
{
|
||||
ctx->propagator->strokeWidth(stroke->width(frameNo));
|
||||
ctx->propagator->strokeWidth(stroke->width(frameNo, exps));
|
||||
ctx->propagator->strokeCap(stroke->cap);
|
||||
ctx->propagator->strokeJoin(stroke->join);
|
||||
ctx->propagator->strokeMiterlimit(stroke->miterLimit);
|
||||
|
@ -283,8 +283,8 @@ static void _updateSolidStroke(TVG_UNUSED LottieGroup* parent, LottieObject** ch
|
|||
auto stroke = static_cast<LottieSolidStroke*>(*child);
|
||||
|
||||
ctx->merging = nullptr;
|
||||
auto color = stroke->color(frameNo);
|
||||
ctx->propagator->strokeFill(color.rgb[0], color.rgb[1], color.rgb[2], stroke->opacity(frameNo));
|
||||
auto color = stroke->color(frameNo, exps);
|
||||
ctx->propagator->strokeFill(color.rgb[0], color.rgb[1], color.rgb[2], stroke->opacity(frameNo, exps));
|
||||
_updateStroke(static_cast<LottieStroke*>(stroke), frameNo, ctx, exps);
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,7 @@ static void _updateGradientStroke(TVG_UNUSED LottieGroup* parent, LottieObject**
|
|||
}
|
||||
|
||||
|
||||
static void _updateSolidFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx)
|
||||
static void _updateSolidFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
|
||||
{
|
||||
if (_fragmented(child, contexts, ctx)) return;
|
||||
|
||||
|
@ -309,7 +309,7 @@ static void _updateSolidFill(TVG_UNUSED LottieGroup* parent, LottieObject** chil
|
|||
|
||||
ctx->merging = nullptr;
|
||||
auto color = fill->color(frameNo);
|
||||
ctx->propagator->fill(color.rgb[0], color.rgb[1], color.rgb[2], fill->opacity(frameNo));
|
||||
ctx->propagator->fill(color.rgb[0], color.rgb[1], color.rgb[2], fill->opacity(frameNo, exps));
|
||||
ctx->propagator->fill(fill->rule);
|
||||
|
||||
if (ctx->propagator->strokeWidth() > 0) ctx->propagator->order(true);
|
||||
|
@ -443,13 +443,13 @@ static void _appendRect(Shape* shape, float x, float y, float w, float h, float
|
|||
}
|
||||
}
|
||||
|
||||
static void _updateRect(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx)
|
||||
static void _updateRect(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
|
||||
{
|
||||
auto rect = static_cast<LottieRect*>(*child);
|
||||
|
||||
auto position = rect->position(frameNo);
|
||||
auto size = rect->size(frameNo);
|
||||
auto roundness = rect->radius(frameNo);
|
||||
auto position = rect->position(frameNo, exps);
|
||||
auto size = rect->size(frameNo, exps);
|
||||
auto roundness = rect->radius(frameNo, exps);
|
||||
if (ctx->roundness > roundness) roundness = ctx->roundness;
|
||||
|
||||
if (roundness > 0.0f) {
|
||||
|
@ -496,12 +496,12 @@ static void _appendCircle(Shape* shape, float cx, float cy, float rx, float ry,
|
|||
}
|
||||
|
||||
|
||||
static void _updateEllipse(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx)
|
||||
static void _updateEllipse(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
|
||||
{
|
||||
auto ellipse = static_cast<LottieEllipse*>(*child);
|
||||
|
||||
auto position = ellipse->position(frameNo);
|
||||
auto size = ellipse->size(frameNo);
|
||||
auto position = ellipse->position(frameNo, exps);
|
||||
auto size = ellipse->size(frameNo, exps);
|
||||
|
||||
if (ctx->repeater) {
|
||||
auto path = Shape::gen();
|
||||
|
@ -614,15 +614,15 @@ static void _updateText(LottieGroup* parent, LottieObject** child, float frameNo
|
|||
}
|
||||
|
||||
|
||||
static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float frameNo, Shape* merging)
|
||||
static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float frameNo, Shape* merging, LottieExpressions* exps)
|
||||
{
|
||||
static constexpr auto POLYSTAR_MAGIC_NUMBER = 0.47829f / 0.28f;
|
||||
|
||||
auto ptsCnt = star->ptsCnt(frameNo);
|
||||
auto innerRadius = star->innerRadius(frameNo);
|
||||
auto outerRadius = star->outerRadius(frameNo);
|
||||
auto innerRoundness = star->innerRoundness(frameNo) * 0.01f;
|
||||
auto outerRoundness = star->outerRoundness(frameNo) * 0.01f;
|
||||
auto ptsCnt = star->ptsCnt(frameNo, exps);
|
||||
auto innerRadius = star->innerRadius(frameNo, exps);
|
||||
auto outerRadius = star->outerRadius(frameNo, exps);
|
||||
auto innerRoundness = star->innerRoundness(frameNo, exps) * 0.01f;
|
||||
auto outerRoundness = star->outerRoundness(frameNo, exps) * 0.01f;
|
||||
|
||||
auto angle = mathDeg2Rad(-90.0f);
|
||||
auto partialPointRadius = 0.0f;
|
||||
|
@ -723,13 +723,13 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans
|
|||
}
|
||||
|
||||
|
||||
static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float frameNo, Shape* merging)
|
||||
static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float frameNo, Shape* merging, LottieExpressions* exps)
|
||||
{
|
||||
static constexpr auto POLYGON_MAGIC_NUMBER = 0.25f;
|
||||
|
||||
auto ptsCnt = size_t(floor(star->ptsCnt(frameNo)));
|
||||
auto radius = star->outerRadius(frameNo);
|
||||
auto roundness = star->outerRoundness(frameNo) * 0.01f;
|
||||
auto ptsCnt = size_t(floor(star->ptsCnt(frameNo, exps)));
|
||||
auto radius = star->outerRadius(frameNo, exps);
|
||||
auto roundness = star->outerRoundness(frameNo, exps) * 0.01f;
|
||||
|
||||
auto angle = mathDeg2Rad(-90.0f);
|
||||
auto anglePerPoint = 2.0f * MATH_PI / float(ptsCnt);
|
||||
|
@ -792,16 +792,16 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr
|
|||
}
|
||||
|
||||
|
||||
static void _updatePolystar(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx)
|
||||
static void _updatePolystar(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
|
||||
{
|
||||
auto star= static_cast<LottiePolyStar*>(*child);
|
||||
|
||||
//Optimize: Can we skip the individual coords transform?
|
||||
Matrix matrix;
|
||||
mathIdentity(&matrix);
|
||||
auto position = star->position(frameNo);
|
||||
auto position = star->position(frameNo, exps);
|
||||
mathTranslate(&matrix, position.x, position.y);
|
||||
mathRotate(&matrix, star->rotation(frameNo));
|
||||
mathRotate(&matrix, star->rotation(frameNo, exps));
|
||||
|
||||
if (ctx->transform) mathMultiply(ctx->transform, &matrix);
|
||||
|
||||
|
@ -809,13 +809,13 @@ static void _updatePolystar(LottieGroup* parent, LottieObject** child, float fra
|
|||
|
||||
if (ctx->repeater) {
|
||||
auto p = Shape::gen();
|
||||
if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, frameNo, p.get());
|
||||
else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, p.get());
|
||||
if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, frameNo, p.get(), exps);
|
||||
else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, p.get(), exps);
|
||||
_repeat(parent, std::move(p), ctx);
|
||||
} else {
|
||||
auto merging = _draw(parent, ctx);
|
||||
if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, frameNo, merging);
|
||||
else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, merging);
|
||||
if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, frameNo, merging, exps);
|
||||
else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, merging, exps);
|
||||
P(merging)->update(RenderUpdateFlag::Path);
|
||||
}
|
||||
}
|
||||
|
@ -860,28 +860,28 @@ static void _updateImage(LottieGroup* parent, LottieObject** child, float frameN
|
|||
}
|
||||
|
||||
|
||||
static void _updateRoundedCorner(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx)
|
||||
static void _updateRoundedCorner(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
|
||||
{
|
||||
auto roundedCorner= static_cast<LottieRoundedCorner*>(*child);
|
||||
|
||||
auto roundness = roundedCorner->radius(frameNo);
|
||||
auto roundness = roundedCorner->radius(frameNo, exps);
|
||||
if (ctx->roundness < roundness) ctx->roundness = roundness;
|
||||
}
|
||||
|
||||
|
||||
static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx)
|
||||
static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist<RenderContext>& contexts, RenderContext* ctx, LottieExpressions* exps)
|
||||
{
|
||||
auto repeater= static_cast<LottieRepeater*>(*child);
|
||||
|
||||
if (!ctx->repeater) ctx->repeater = new RenderRepeater();
|
||||
ctx->repeater->cnt = static_cast<int>(repeater->copies(frameNo));
|
||||
ctx->repeater->offset = repeater->offset(frameNo);
|
||||
ctx->repeater->position = repeater->position(frameNo);
|
||||
ctx->repeater->anchor = repeater->anchor(frameNo);
|
||||
ctx->repeater->scale = repeater->scale(frameNo);
|
||||
ctx->repeater->rotation = repeater->rotation(frameNo);
|
||||
ctx->repeater->startOpacity = repeater->startOpacity(frameNo);
|
||||
ctx->repeater->endOpacity = repeater->endOpacity(frameNo);
|
||||
ctx->repeater->cnt = static_cast<int>(repeater->copies(frameNo, exps));
|
||||
ctx->repeater->offset = repeater->offset(frameNo, exps);
|
||||
ctx->repeater->position = repeater->position(frameNo, exps);
|
||||
ctx->repeater->anchor = repeater->anchor(frameNo, exps);
|
||||
ctx->repeater->scale = repeater->scale(frameNo, exps);
|
||||
ctx->repeater->rotation = repeater->rotation(frameNo, exps);
|
||||
ctx->repeater->startOpacity = repeater->startOpacity(frameNo, exps);
|
||||
ctx->repeater->endOpacity = repeater->endOpacity(frameNo, exps);
|
||||
ctx->repeater->inorder = repeater->inorder;
|
||||
ctx->repeater->interpOpacity = (ctx->repeater->startOpacity == ctx->repeater->endOpacity) ? false : true;
|
||||
|
||||
|
@ -926,7 +926,7 @@ static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderCon
|
|||
break;
|
||||
}
|
||||
case LottieObject::SolidFill: {
|
||||
_updateSolidFill(parent, child, frameNo, contexts, ctx);
|
||||
_updateSolidFill(parent, child, frameNo, contexts, ctx, exps);
|
||||
break;
|
||||
}
|
||||
case LottieObject::SolidStroke: {
|
||||
|
@ -942,11 +942,11 @@ static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderCon
|
|||
break;
|
||||
}
|
||||
case LottieObject::Rect: {
|
||||
_updateRect(parent, child, frameNo, contexts, ctx);
|
||||
_updateRect(parent, child, frameNo, contexts, ctx, exps);
|
||||
break;
|
||||
}
|
||||
case LottieObject::Ellipse: {
|
||||
_updateEllipse(parent, child, frameNo, contexts, ctx);
|
||||
_updateEllipse(parent, child, frameNo, contexts, ctx, exps);
|
||||
break;
|
||||
}
|
||||
case LottieObject::Path: {
|
||||
|
@ -954,7 +954,7 @@ static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderCon
|
|||
break;
|
||||
}
|
||||
case LottieObject::Polystar: {
|
||||
_updatePolystar(parent, child, frameNo, contexts, ctx);
|
||||
_updatePolystar(parent, child, frameNo, contexts, ctx, exps);
|
||||
break;
|
||||
}
|
||||
case LottieObject::Image: {
|
||||
|
@ -970,11 +970,11 @@ static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderCon
|
|||
break;
|
||||
}
|
||||
case LottieObject::Repeater: {
|
||||
_updateRepeater(parent, child, frameNo, contexts, ctx);
|
||||
_updateRepeater(parent, child, frameNo, contexts, ctx, exps);
|
||||
break;
|
||||
}
|
||||
case LottieObject::RoundedCorner: {
|
||||
_updateRoundedCorner(parent, child, frameNo, contexts, ctx);
|
||||
_updateRoundedCorner(parent, child, frameNo, contexts, ctx, exps);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
|
|
|
@ -92,35 +92,33 @@ void LottieTrimpath::segment(float frameNo, float& start, float& end, LottieExpr
|
|||
Fill* LottieGradient::fill(float frameNo, LottieExpressions* exps)
|
||||
{
|
||||
Fill* fill = nullptr;
|
||||
auto s = start(frameNo, exps);
|
||||
auto e = end(frameNo, exps);
|
||||
|
||||
//Linear Graident
|
||||
if (id == 1) {
|
||||
fill = LinearGradient::gen().release();
|
||||
static_cast<LinearGradient*>(fill)->linear(start(frameNo).x, start(frameNo).y, end(frameNo).x, end(frameNo).y);
|
||||
static_cast<LinearGradient*>(fill)->linear(s.x, s.y, e.x, e.y);
|
||||
}
|
||||
//Radial Gradient
|
||||
if (id == 2) {
|
||||
fill = RadialGradient::gen().release();
|
||||
|
||||
auto sx = start(frameNo).x;
|
||||
auto sy = start(frameNo).y;
|
||||
auto ex = end(frameNo).x;
|
||||
auto ey = end(frameNo).y;
|
||||
auto w = fabsf(ex - sx);
|
||||
auto h = fabsf(ey - sy);
|
||||
auto w = fabsf(e.x - s.x);
|
||||
auto h = fabsf(e.y - s.y);
|
||||
auto r = (w > h) ? (w + 0.375f * h) : (h + 0.375f * w);
|
||||
auto progress = this->height(frameNo) * 0.01f;
|
||||
auto progress = this->height(frameNo, exps) * 0.01f;
|
||||
|
||||
if (mathZero(progress)) {
|
||||
P(static_cast<RadialGradient*>(fill))->radial(sx, sy, r, sx, sy, 0.0f);
|
||||
P(static_cast<RadialGradient*>(fill))->radial(s.x, s.y, r, s.x, s.y, 0.0f);
|
||||
} else {
|
||||
if (mathEqual(progress, 1.0f)) progress = 0.99f;
|
||||
auto startAngle = mathRad2Deg(atan2(ey - sy, ex - sx));
|
||||
auto angle = mathDeg2Rad((startAngle + this->angle(frameNo)));
|
||||
auto fx = sx + cos(angle) * progress * r;
|
||||
auto fy = sy + sin(angle) * progress * r;
|
||||
auto startAngle = mathRad2Deg(atan2(e.y - s.y, e.x - s.x));
|
||||
auto angle = mathDeg2Rad((startAngle + this->angle(frameNo, exps)));
|
||||
auto fx = s.x + cos(angle) * progress * r;
|
||||
auto fy = s.y + sin(angle) * progress * r;
|
||||
// Lottie dosen't have any focal radius concept
|
||||
P(static_cast<RadialGradient*>(fill))->radial(sx, sy, r, fx, fy, 0.0f);
|
||||
P(static_cast<RadialGradient*>(fill))->radial(s.x, s.y, r, fx, fy, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue