lottie: properly capture the stroking context

Each group must determine the stroking rendering contexts
and assess whether context switching has occurred.

Migrate the sequence from the root layer to all groups.
This commit is contained in:
Hermet Park 2024-01-17 00:33:48 +09:00
parent 441542b272
commit 5b89479963
2 changed files with 18 additions and 39 deletions

View file

@ -1035,6 +1035,7 @@ static void _buildReference(LottieComposition* comp, LottieLayer* layer)
auto assetLayer = static_cast<LottieLayer*>(*asset);
if (_buildComposition(comp, assetLayer)) {
layer->children = assetLayer->children;
layer->reqFragment = assetLayer->reqFragment;
}
} else if (layer->type == LottieLayer::Image) {
layer->children.push(*asset);
@ -1069,40 +1070,6 @@ static void _bulidHierarchy(LottieGroup* parent, LottieLayer* child)
}
//TODO: Optimize this. Can we preprocess in the parsing stage?
static void _checkFragment(LottieGroup* parent)
{
if (parent->children.count == 0) return;
int strokeCnt = 0;
/* 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. */
for (auto c = parent->children.end() - 1; c >= parent->children.data; --c) {
switch ((*c)->type) {
case LottieObject::Group: {
if (strokeCnt > 0) {
parent->reqFragment = true;
return;
}
break;
}
case LottieObject::SolidStroke:
case LottieObject::GradientStroke: {
if (strokeCnt > 0) {
parent->reqFragment = true;
return;
}
++strokeCnt;
break;
}
default: break;
}
}
}
static void _attachFont(LottieComposition* comp, LottieLayer* parent)
{
//TODO: Consider to migrate this attachment to the frame update time.
@ -1142,8 +1109,6 @@ static bool _buildComposition(LottieComposition* comp, LottieGroup* parent)
}
_bulidHierarchy(parent, child);
_checkFragment(static_cast<LottieGroup*>(*c));
//attach the necessary font data
if (child->type == LottieLayer::Text) _attachFont(comp, child);

View file

@ -135,9 +135,23 @@ Fill* LottieGradient::fill(float frameNo)
void LottieGroup::prepare(LottieObject::Type type)
{
LottieObject::type = type;
for (auto child = children.data; child < children.end(); ++child) {
statical &= (*child)->statical;
if (!statical) break;
if (children.count == 0) return;
size_t strokeCnt = 0;
for (auto c = children.end() - 1; c >= children.data; --c) {
if (reqFragment && !statical) break;
auto child = static_cast<LottieObject*>(*c);
if (statical) statical &= child->statical;
/* 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 (reqFragment) continue;
if (child->type == LottieObject::SolidStroke || child->type == LottieObject::GradientStroke) {
if (strokeCnt > 0) reqFragment = true;
else ++strokeCnt;
} else if (child->type == LottieObject::Group && strokeCnt > 0) reqFragment = true;
}
}