lottie: add 'tp' tag support

So far it hasn't been possible to specify
a matte layer - by default, it was the layer
above the calling layer. The 'tp' tag support
has been introduced, enabling referencing any
layer by its index.
In cases where the layer referencing the matte
was the first one, a segmentation fault was
observed. This issue has now been resolved.

@Issue: https://github.com/thorvg/thorvg/issues/2325
This commit is contained in:
Mira Grudzinska 2024-05-27 21:59:15 +02:00 committed by Hermet Park
parent 20d3992214
commit b812277a06
4 changed files with 21 additions and 16 deletions

View file

@ -1319,6 +1319,20 @@ static bool _buildComposition(LottieComposition* comp, LottieGroup* parent)
//attach the precomp layer.
if (child->refId) _buildReference(comp, child);
if (child->matte.type != CompositeMethod::None) {
//no index of the matte layer is provided: the layer above is used as the matte source
if (child->mid == -1) {
if (c > parent->children.begin()) {
child->matte.target = static_cast<LottieLayer*>(*(c - 1));
}
//matte layer is specified by an index.
} else {
if (auto matte = comp->layer(child->mid)) {
child->matte.target = matte;
}
}
}
if (child->matte.target) {
//parenting
_bulidHierarchy(parent, child->matte.target);
@ -1353,7 +1367,8 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo)
if (exps && comp->expressions) exps->update(comp->timeAtFrame(frameNo));
for (auto child = root->children.end() - 1; child >= root->children.begin(); --child) {
_updateLayer(root, static_cast<LottieLayer*>(*child), frameNo, exps);
auto layer = static_cast<LottieLayer*>(*child);
if (!layer->matteSrc) _updateLayer(root, layer, frameNo, exps);
}
return true;

View file

@ -354,7 +354,7 @@ LottieLayer::~LottieLayer()
delete(*m);
}
delete(matte.target);
matte.target = nullptr;
delete(transform);
}

View file

@ -561,6 +561,7 @@ struct LottieLayer : LottieGroup
float outFrame = 0.0f;
float startFrame = 0.0f;
char* refId = nullptr; //pre-composition reference.
int16_t mid = -1; //id of the matte layer.
int16_t pid = -1; //id of the parent layer.
int16_t id = -1; //id of the current layer.

View file

@ -1229,6 +1229,7 @@ LottieLayer* LottieParser::parseLayer()
else if (KEY_AS("h") || KEY_AS("sh")) getLayerSize(layer->h);
else if (KEY_AS("sc")) layer->color = getColor(getString());
else if (KEY_AS("tt")) layer->matte.type = getMatteType();
else if (KEY_AS("tp")) layer->mid = getInt();
else if (KEY_AS("masksProperties")) parseMasks(layer);
else if (KEY_AS("hd")) layer->hidden = getBool();
else if (KEY_AS("refId")) layer->refId = getStringCopy();
@ -1264,21 +1265,9 @@ LottieLayer* LottieParser::parseLayers()
enterArray();
while (nextArrayValue()) {
if (auto layer = parseLayer()) {
if (layer->matte.type == CompositeMethod::None) {
root->children.push(layer);
} else {
//matte source must be located in the right previous.
auto matte = static_cast<LottieLayer*>(root->children.last());
if (matte->matteSrc) {
layer->matte.target = matte;
} else {
TVGLOG("LOTTIE", "Matte Source(%s) is not designated?", matte->name);
}
root->children.last() = layer;
}
}
if (auto layer = parseLayer()) root->children.push(layer);
}
root->prepare();
return root;
}