diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 924769a8..b5d9ef7d 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -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(*(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(*child), frameNo, exps); + auto layer = static_cast(*child); + if (!layer->matteSrc) _updateLayer(root, layer, frameNo, exps); } return true; diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 7fab8ffb..a1dd4e4c 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -354,7 +354,7 @@ LottieLayer::~LottieLayer() delete(*m); } - delete(matte.target); + matte.target = nullptr; delete(transform); } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index eef6025d..1ce9806b 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -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. diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 98e9db42..a03f36ce 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -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(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; }