diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index c70f9c4e49..3a9bfbdf10 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -458,6 +458,11 @@ LOTCompLayerItem::LOTCompLayerItem(LOTLayerData *layerModel) // 3. keep the layer in back-to-front order. // as lottie model keeps the data in front-toback-order. std::reverse(mLayers.begin(), mLayers.end()); + + // 4. check if its a nested composition + if (!layerModel->layerSize().empty()) { + mClipper = std::make_unique(layerModel->layerSize()); + } } void LOTCompLayerItem::updateStaticProperty() @@ -518,6 +523,14 @@ void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const mask = inheritMask; } + if (mClipper) { + if (mask.empty()) { + mask = mClipper->rle(); + } else { + mask = mClipper->rle() & mask; + } + } + LOTLayerItem *matteLayer = nullptr; for (const auto &layer : mLayers) { if (!matteLayer && layer->hasMatte()) { @@ -536,8 +549,35 @@ void LOTCompLayerItem::render(VPainter *painter, const VRle &inheritMask, const } } +void LOTClipperItem::update(const VMatrix &matrix) +{ + mPath.reset(); + mPath.addRect(VRectF(0,0, mSize.width(), mSize.height())); + mPath.transform(matrix); + + VPath tmp = mPath; + + if (!mRleFuture) mRleFuture = std::make_shared>(); + + mRleFuture->reuse(); + VRaster::generateFillInfo(mRleFuture, std::move(tmp), std::move(mRle)); + mRle = VRle(); +} + +VRle LOTClipperItem::rle() +{ + if (mRleFuture && mRleFuture->valid()) { + mRle = mRleFuture->get(); + } + return mRle; +} + void LOTCompLayerItem::updateContent() { + if (mClipper && flag().testFlag(DirtyFlagBit::Matrix)) { + mClipper->update(combinedMatrix()); + } + for (const auto &layer : mLayers) { layer->update( mLayerData->timeRemap(frameNo()) - mLayerData->startFrame(), combinedMatrix(), combinedAlpha()); diff --git a/src/lottie/lottieitem.h b/src/lottie/lottieitem.h index cb6f0bf617..47c816cb1e 100644 --- a/src/lottie/lottieitem.h +++ b/src/lottie/lottieitem.h @@ -71,6 +71,19 @@ private: class LOTLayerMaskItem; +class LOTClipperItem +{ +public: + LOTClipperItem(VSize size): mSize(size){} + void update(const VMatrix &matrix); + VRle rle(); +public: + VSize mSize; + VPath mPath; + RleShare mRleFuture; + VRle mRle; +}; + typedef vFlag DirtyFlag; class LOTLayerItem { @@ -127,6 +140,7 @@ protected: private: std::vector mLayersCNode; std::vector> mLayers; + std::unique_ptr mClipper; }; class LOTSolidLayerItem: public LOTLayerItem