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;
|
uint8_t opacity;
|
||||||
|
|
||||||
if (parent->mergeable) {
|
if (parent->mergeable()) {
|
||||||
if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix));
|
if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix));
|
||||||
_updateTransform(transform, frameNo, false, *ctx->transform, opacity);
|
_updateTransform(transform, frameNo, false, *ctx->transform, opacity);
|
||||||
return;
|
return;
|
||||||
|
@ -232,10 +232,10 @@ static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameN
|
||||||
group->reqFragment |= ctx->reqFragment;
|
group->reqFragment |= ctx->reqFragment;
|
||||||
|
|
||||||
//generate a merging shape to consolidate partial shapes into a single entity
|
//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;
|
Inlist<RenderContext> contexts;
|
||||||
contexts.back(new RenderContext(*ctx, group->mergeable));
|
contexts.back(new RenderContext(*ctx, group->mergeable()));
|
||||||
|
|
||||||
_updateChildren(group, frameNo, contexts);
|
_updateChildren(group, frameNo, contexts);
|
||||||
|
|
||||||
|
@ -897,9 +897,7 @@ static void _updateTrimpath(TVG_UNUSED LottieGroup* parent, LottieObject** child
|
||||||
end = (length * end) + pbegin;
|
end = (length * end) + pbegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
P(ctx->propagator)->strokeTrim(begin, end, false);
|
P(ctx->propagator)->strokeTrim(begin, end, trimpath->type == LottieTrimpath::Type::Individual ? true : false);
|
||||||
|
|
||||||
//TODO: individual or simultaenous mode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -142,20 +142,20 @@ void LottieGroup::prepare(LottieObject::Type type)
|
||||||
size_t fillCnt = 0;
|
size_t fillCnt = 0;
|
||||||
|
|
||||||
for (auto c = children.end() - 1; c >= children.begin(); --c) {
|
for (auto c = children.end() - 1; c >= children.begin(); --c) {
|
||||||
if (!mergeable && reqFragment) break;
|
|
||||||
|
|
||||||
auto child = static_cast<LottieObject*>(*c);
|
auto child = static_cast<LottieObject*>(*c);
|
||||||
|
|
||||||
|
if (child->type == LottieObject::Type::Trimpath) trimpath = true;
|
||||||
|
|
||||||
/* Figure out if this group is a simple path drawing.
|
/* Figure out if this group is a simple path drawing.
|
||||||
In that case, the rendering context can be sharable with the parent's. */
|
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;
|
if (reqFragment) continue;
|
||||||
|
|
||||||
/* Figure out if the rendering context should be fragmented.
|
/* Figure out if the rendering context should be fragmented.
|
||||||
Multiple stroking or grouping with a stroking would occur this.
|
Multiple stroking or grouping with a stroking would occur this.
|
||||||
This fragment resolves the overlapped stroke outlines. */
|
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;
|
if (strokeCnt > 0 || fillCnt > 0) reqFragment = true;
|
||||||
} else if (child->type == LottieObject::SolidStroke || child->type == LottieObject::GradientStroke) {
|
} else if (child->type == LottieObject::SolidStroke || child->type == LottieObject::GradientStroke) {
|
||||||
if (strokeCnt > 0) reqFragment = true;
|
if (strokeCnt > 0) reqFragment = true;
|
||||||
|
@ -165,6 +165,25 @@ void LottieGroup::prepare(LottieObject::Type type)
|
||||||
else ++fillCnt;
|
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);
|
void prepare(LottieObject::Type type = LottieObject::Group);
|
||||||
|
bool mergeable() override { return allowMerge; }
|
||||||
|
|
||||||
Scene* scene = nullptr; //tvg render data
|
Scene* scene = nullptr; //tvg render data
|
||||||
Array<LottieObject*> children;
|
Array<LottieObject*> children;
|
||||||
|
|
||||||
bool reqFragment = false; //requirment to fragment the render context
|
bool reqFragment = false; //requirment to fragment the render context
|
||||||
bool buildDone = false; //completed in building the composition.
|
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);
|
return transform->opacity(frameNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mergeable() override { return false; }
|
||||||
|
|
||||||
void prepare();
|
void prepare();
|
||||||
float remap(float frameNo);
|
float remap(float frameNo);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue