mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
lottie: Properly handle the TrimPath mode.
This correction addresses the drawing order of objects when a group contains a TrimPath and is merging shapes. Additionally, the TrimPath method is can applied to the engine to control the drawing behavior by 7f3dc541d6b7abcdc03facd884489f37c327fd98 issue: https://github.com/thorvg/thorvg/issues/2047
This commit is contained in:
parent
c74cd42363
commit
cbed261ba2
3 changed files with 32 additions and 11 deletions
|
@ -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<RenderContext> 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<LottieObject*>(*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<LottieGroup*>(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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<LottieObject*> 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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue