diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 7f4ff4bc..dd19b2d1 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -167,12 +167,8 @@ void LottieBuilder::updateTransform(LottieLayer* layer, float frameNo) _updateTransform(transform, frameNo, layer->autoOrient, matrix, layer->cache.opacity, exps); - if (parent) { - if (!identity((const Matrix*) &parent->cache.matrix)) { - if (identity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix; - else layer->cache.matrix = parent->cache.matrix * matrix; - } - } + if (parent) layer->cache.matrix = parent->cache.matrix * matrix; + layer->cache.frameNo = frameNo; } @@ -182,25 +178,30 @@ void LottieBuilder::updateTransform(LottieGroup* parent, LottieObject** child, f auto transform = static_cast(*child); if (!transform) return; + Matrix m; uint8_t opacity; if (parent->mergeable()) { - if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix)); - _updateTransform(transform, frameNo, false, *ctx->transform, opacity, exps); + if (ctx->transform) { + _updateTransform(transform, frameNo, false, m, opacity, exps); + *ctx->transform *= m; + } else { + ctx->transform = new Matrix; + _updateTransform(transform, frameNo, false, *ctx->transform, opacity, exps); + } return; } ctx->merging = nullptr; - Matrix matrix; - if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return; + if (!_updateTransform(transform, frameNo, false, m, opacity, exps)) return; - ctx->propagator->transform(PP(ctx->propagator)->transform() * matrix); + ctx->propagator->transform(PP(ctx->propagator)->transform() * m); ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity)); //FIXME: preserve the stroke width. too workaround, need a better design. if (P(ctx->propagator)->rs.strokeWidth() > 0.0f) { - auto denominator = sqrtf(matrix.e11 * matrix.e11 + matrix.e12 * matrix.e12); + auto denominator = sqrtf(m.e11 * m.e11 + m.e12 * m.e12); if (denominator > 1.0f) ctx->propagator->stroke(ctx->propagator->strokeWidth() / denominator); } } diff --git a/src/loaders/lottie/tvgLottieBuilder.h b/src/loaders/lottie/tvgLottieBuilder.h index c5155715..0a30f79a 100644 --- a/src/loaders/lottie/tvgLottieBuilder.h +++ b/src/loaders/lottie/tvgLottieBuilder.h @@ -71,7 +71,7 @@ struct RenderContext ~RenderContext() { PP(propagator)->unref(); - free(transform); + delete(transform); delete(roundness); delete(offsetPath); } @@ -84,6 +84,10 @@ struct RenderContext this->repeaters = rhs.repeaters; if (rhs.roundness) this->roundness = new LottieRoundnessModifier(rhs.roundness->r); if (rhs.offsetPath) this->offsetPath = new LottieOffsetModifier(rhs.offsetPath->offset, rhs.offsetPath->miterLimit, rhs.offsetPath->join); + if (rhs.transform) { + transform = new Matrix; + *transform = *rhs.transform; + } } }; diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 29b56ee7..11cf38c8 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -426,7 +426,7 @@ void LottieGroup::prepare(LottieObject::Type type) /* Figure out if this group is a simple path drawing. In that case, the rendering context can be sharable with the parent's. */ - if (allowMerge && (child->type == LottieObject::Group || !child->mergeable())) allowMerge = false; + if (allowMerge && !child->mergeable()) allowMerge = false; //Figure out this group has visible contents switch (child->type) { diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index d8d6dd4a..fb55425c 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -544,8 +544,7 @@ struct LottieTransform : LottieObject bool mergeable() override { - if (!opacity.frames && opacity.value == 255) return true; - return false; + return true; } LottieProperty* property(uint16_t ix) override