diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index efa3e44e..3405bf78 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -198,7 +198,7 @@ static void _updateTransform(LottieGroup* parent, LottieObject** child, float fr uint8_t opacity; - if (parent->mergeable) { + if (parent->mergeable()) { if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix)); _updateTransform(transform, frameNo, false, *ctx->transform, opacity); return; @@ -232,10 +232,10 @@ static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameN group->reqFragment |= ctx->reqFragment; //generate a merging shape to consolidate partial shapes into a single entity - if (group->mergeable) _draw(parent, ctx); + if (group->mergeable()) _draw(parent, ctx); Inlist contexts; - contexts.back(new RenderContext(*ctx, group->mergeable)); + contexts.back(new RenderContext(*ctx, group->mergeable())); _updateChildren(group, frameNo, contexts); @@ -897,9 +897,7 @@ static void _updateTrimpath(TVG_UNUSED LottieGroup* parent, LottieObject** child end = (length * end) + pbegin; } - P(ctx->propagator)->strokeTrim(begin, end, false); - - //TODO: individual or simultaenous mode + P(ctx->propagator)->strokeTrim(begin, end, trimpath->type == LottieTrimpath::Type::Individual ? true : false); } diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index c8ce3dda..eb925a69 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -142,20 +142,20 @@ void LottieGroup::prepare(LottieObject::Type type) size_t fillCnt = 0; for (auto c = children.end() - 1; c >= children.begin(); --c) { - if (!mergeable && reqFragment) break; - auto child = static_cast(*c); + if (child->type == LottieObject::Type::Trimpath) trimpath = true; + /* Figure out if this group is a simple path drawing. In that case, the rendering context can be sharable with the parent's. */ - if (mergeable && !child->mergeable()) mergeable = false; + if (allowMerge && (child->type == LottieObject::Group || !child->mergeable())) allowMerge = false; if (reqFragment) continue; /* Figure out if the rendering context should be fragmented. Multiple stroking or grouping with a stroking would occur this. This fragment resolves the overlapped stroke outlines. */ - if (child->type == LottieObject::Group && !static_cast(child)->mergeable) { + if (child->type == LottieObject::Group && !child->mergeable()) { if (strokeCnt > 0 || fillCnt > 0) reqFragment = true; } else if (child->type == LottieObject::SolidStroke || child->type == LottieObject::GradientStroke) { if (strokeCnt > 0) reqFragment = true; @@ -165,6 +165,25 @@ void LottieGroup::prepare(LottieObject::Type type) else ++fillCnt; } } + + //Reverse the drawing order if this group has a trimpath. + if (!trimpath) return; + + for (uint32_t i = 0; i < children.count - 1; ) { + auto child2 = children[i + 1]; + if (!child2->mergeable() || child2->type == LottieObject::Transform) { + i += 2; + continue; + } + auto child = children[i]; + if (!child->mergeable() || child->type == LottieObject::Transform) { + i++; + continue; + } + children[i] = child2; + children[i + 1] = child; + i++; + } } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index e10c9c67..78b85c32 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -572,13 +572,15 @@ struct LottieGroup : LottieObject } void prepare(LottieObject::Type type = LottieObject::Group); + bool mergeable() override { return allowMerge; } Scene* scene = nullptr; //tvg render data Array children; bool reqFragment = false; //requirment to fragment the render context bool buildDone = false; //completed in building the composition. - bool mergeable = true; //if this group is consisted of simple (transformed) shapes. + bool allowMerge = true; //if this group is consisted of simple (transformed) shapes. + bool trimpath = false; //this group has a trimpath. }; @@ -595,6 +597,8 @@ struct LottieLayer : LottieGroup return transform->opacity(frameNo); } + bool mergeable() override { return false; } + void prepare(); float remap(float frameNo);