diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 49e029bb60..9e4a831f4a 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -126,16 +126,20 @@ bool LOTCompItem::render(const rlottie::Surface &surface) surface.width(), surface.height(), surface.bytesPerLine(), VBitmap::Format::ARGB32_Premultiplied); + /* schedule all preprocess task for this frame at once. */ mDrawableList.clear(); mRootLayer->renderList(mDrawableList); - VRect clip(0, 0, surface.width(), surface.height()); + VRect clip(0, 0, surface.drawRegionWidth(), surface.drawRegionHeight()); for (auto &e : mDrawableList) { e->preprocess(clip); } VPainter painter(&bitmap); + // set sub surface area for drawing. + painter.setDrawRegion(VRect(surface.drawRegionPosX(), surface.drawRegionPosY(), + surface.drawRegionWidth(), surface.drawRegionHeight())); mRootLayer->render(&painter, {}, {}); return true; diff --git a/src/vector/vdrawhelper.cpp b/src/vector/vdrawhelper.cpp index 3a254836f0..9c793726bd 100644 --- a/src/vector/vdrawhelper.cpp +++ b/src/vector/vdrawhelper.cpp @@ -207,7 +207,7 @@ VBitmap::Format VRasterBuffer::prepare(VBitmap *image) void VSpanData::init(VRasterBuffer *image) { mRasterBuffer = image; - mSystemClip = VRect(0, 0, image->width(), image->height()); + setDrawRegion(VRect(0, 0, image->width(), image->height())); mType = VSpanData::Type::None; mBlendFunc = nullptr; mUnclippedBlendFunc = nullptr; diff --git a/src/vector/vdrawhelper.h b/src/vector/vdrawhelper.h index a02f9473fb..9672613dc6 100644 --- a/src/vector/vdrawhelper.h +++ b/src/vector/vdrawhelper.h @@ -150,15 +150,21 @@ struct VSpanData { VPainter::CompositionMode mode = VPainter::CompModeSrcOver, int alpha = 255); void setupMatrix(const VMatrix &matrix); - void setPos(const VPoint &pos) { mPos = pos; } + VRect clipRect() const { - return mSystemClip.translated(-mPos.x(), -mPos.y()); + return VRect(0, 0, mDrawableSize.width(), mDrawableSize.height()); + } + + void setDrawRegion(const VRect ®ion) + { + mOffset = VPoint(region.left(), region.top()); + mDrawableSize = VSize(region.width(), region.height()); } uint *buffer(int x, int y) const { - return (uint *)(mRasterBuffer->scanLine(y + mPos.y())) + x + mPos.x(); + return (uint *)(mRasterBuffer->scanLine(y + mOffset.y())) + x + mOffset.x(); } void initTexture(const VBitmap *image, int alpha, VBitmapData::Type type, const VRect &sourceRect); @@ -166,10 +172,10 @@ struct VSpanData { VRasterBuffer * mRasterBuffer; ProcessRleSpan mBlendFunc; ProcessRleSpan mUnclippedBlendFunc; - VRect mSystemClip; VSpanData::Type mType; std::shared_ptr mCachedGradient; - VPoint mPos; + VPoint mOffset; // offset to the subsurface + VSize mDrawableSize;// suburface size union { uint32_t mSolid; VGradientData mGradient; diff --git a/src/vector/vpainter.cpp b/src/vector/vpainter.cpp index f4fea33f53..7b6d36188a 100644 --- a/src/vector/vpainter.cpp +++ b/src/vector/vpainter.cpp @@ -32,15 +32,13 @@ public: VSpanData mSpanData; }; -void VPainterImpl::drawRle(const VPoint &pos, const VRle &rle) +void VPainterImpl::drawRle(const VPoint &, const VRle &rle) { if (rle.empty()) return; // mSpanData.updateSpanFunc(); if (!mSpanData.mUnclippedBlendFunc) return; - mSpanData.setPos(pos); - // do draw after applying clip. rle.intersect(mSpanData.clipRect(), mSpanData.mUnclippedBlendFunc, &mSpanData); @@ -61,9 +59,9 @@ static void fillRect(const VRect &r, VSpanData *data) int x1, x2, y1, y2; x1 = std::max(r.x(), 0); - x2 = std::min(r.x() + r.width(), data->mRasterBuffer->width()); + x2 = std::min(r.x() + r.width(), data->mDrawableSize.width()); y1 = std::max(r.y(), 0); - y2 = std::min(r.y() + r.height(), data->mRasterBuffer->height()); + y2 = std::min(r.y() + r.height(), data->mDrawableSize.height()); if (x2 <= x1 || y2 <= y1) return; @@ -130,6 +128,12 @@ bool VPainter::begin(VBitmap *buffer) } void VPainter::end() {} +void VPainter::setDrawRegion(const VRect ®ion) +{ + mImpl->mSpanData.setDrawRegion(region); +} + + void VPainter::setBrush(const VBrush &brush) { mImpl->mSpanData.setup(brush); @@ -153,7 +157,7 @@ void VPainter::drawRle(const VRle &rle, const VRle &clip) VRect VPainter::clipBoundingRect() const { - return mImpl->mSpanData.mSystemClip; + return mImpl->mSpanData.clipRect(); } void VPainter::drawBitmap(const VPoint &point, const VBitmap &bitmap, const VRect &source) diff --git a/src/vector/vpainter.h b/src/vector/vpainter.h index 389c94d7e5..9a2d60a049 100644 --- a/src/vector/vpainter.h +++ b/src/vector/vpainter.h @@ -40,6 +40,7 @@ public: VPainter(VBitmap *buffer); bool begin(VBitmap *buffer); void end(); + void setDrawRegion(const VRect ®ion); // sub surface rendering area. void setBrush(const VBrush &brush); void setCompositionMode(CompositionMode mode); void drawRle(const VPoint &pos, const VRle &rle);