From 269ef22a97d83d888606f6d80a4f92faab8ebead Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 2 Jul 2024 13:59:39 +0900 Subject: [PATCH] lottie/builder: revise the masking update. Append the mask shape to the previous one, instead of composition, when it's able by the condition. issue: https://github.com/thorvg/thorvg/issues/2426 --- src/loaders/lottie/tvgLottieBuilder.cpp | 59 +++++++++++-------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index d4094502..5271ab94 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -1144,44 +1144,39 @@ static void _updateMaskings(LottieLayer* layer, float frameNo, LottieExpressions { if (layer->masks.count == 0) return; - //maskings - Shape* pmask = nullptr; - auto pmethod = CompositeMethod::None; + //Apply the base mask + auto pMask = static_cast(layer->masks[0]); + auto pMethod = pMask->method; - for (auto m = layer->masks.begin(); m < layer->masks.end(); ++m) { + auto pShape = Shape::gen().release(); + pShape->fill(255, 255, 255, pMask->opacity(frameNo)); + pShape->transform(layer->cache.matrix); + if (pMask->pathset(frameNo, P(pShape)->rs.path.cmds, P(pShape)->rs.path.pts, nullptr, 0.0f, exps)) { + P(pShape)->update(RenderUpdateFlag::Path); + } + layer->scene->composite(tvg::cast(pShape), (pMethod == CompositeMethod::SubtractMask) ? CompositeMethod::InvAlphaMask : CompositeMethod::AlphaMask); + + //Apply the subsquent masks + for (auto m = layer->masks.begin() + 1; m < layer->masks.end(); ++m) { auto mask = static_cast(*m); auto method = mask->method; + if (method == CompositeMethod::None) continue; - //FIXME: None method mask should be appended to the root layer? - if (method == CompositeMethod::None) { - pmethod = method; - continue; - } - - //Masking shape - auto shape = Shape::gen().release(); - shape->fill(255, 255, 255, mask->opacity(frameNo)); - shape->transform(layer->cache.matrix); - if (mask->pathset(frameNo, P(shape)->rs.path.cmds, P(shape)->rs.path.pts, nullptr, 0.0f, exps)) { - P(shape)->update(RenderUpdateFlag::Path); - } - - //Append the chain-masking composition - if (pmask) { - //false of false is true. invert? - if (pmethod == method) { - if (method == CompositeMethod::SubtractMask) method = CompositeMethod::AddMask; - else if (method == CompositeMethod::DifferenceMask) method = CompositeMethod::IntersectMask; - } - pmask->composite(cast(shape), method); - //Apply the masking + //Append the mask shape + if (pMethod == method && (method == CompositeMethod::SubtractMask || method == CompositeMethod::DifferenceMask)) { + mask->pathset(frameNo, P(pShape)->rs.path.cmds, P(pShape)->rs.path.pts, nullptr, 0.0f, exps); + //Chain composition } else { - method = (method == CompositeMethod::SubtractMask) ? CompositeMethod::InvAlphaMask : CompositeMethod::AlphaMask; - layer->scene->composite(cast(shape), method); + auto shape = Shape::gen().release(); + shape->fill(255, 255, 255, mask->opacity(frameNo)); + shape->transform(layer->cache.matrix); + if (mask->pathset(frameNo, P(shape)->rs.path.cmds, P(shape)->rs.path.pts, nullptr, 0.0f, exps)) { + P(shape)->update(RenderUpdateFlag::Path); + } + pShape->composite(tvg::cast(shape), method); + pShape = shape; + pMethod = method; } - - pmethod = mask->method; - pmask = shape; } }