rlottie/vector: support subsurface rendering with arbitrary offset.

This commit is contained in:
subhransu mohanty 2019-03-21 15:35:58 +09:00 committed by Subhransu
parent a708ff3721
commit 94fd87b3d9
5 changed files with 28 additions and 13 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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 &region)
{
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<VSpanData::Pinnable> mCachedGradient;
VPoint mPos;
VPoint mOffset; // offset to the subsurface
VSize mDrawableSize;// suburface size
union {
uint32_t mSolid;
VGradientData mGradient;

View File

@ -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 &region)
{
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)

View File

@ -40,6 +40,7 @@ public:
VPainter(VBitmap *buffer);
bool begin(VBitmap *buffer);
void end();
void setDrawRegion(const VRect &region); // sub surface rendering area.
void setBrush(const VBrush &brush);
void setCompositionMode(CompositionMode mode);
void drawRle(const VPoint &pos, const VRle &rle);