mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: fixed a rendering bug when the invalid clipper is applied.
Shapes with boundaries outside the rendering area are ignored as non-visible. The issue arises when such a shape serves as a clipper. The expected behavior is for the entire clipee to be cut out, but previously, the clipee remained fully visible as if no clip was applied. The fix identifies these clippers and skips rendering clipees. Please note that we can skip rendering at the Paint update stage if the clipper's viewport is outside the canvas. This optimization can improve performance, but only for this specific case. The downside of the approach is that it disrupts multi-processing for clipper updates. As a result, that approach was discarded. issue: https://github.com/thorvg/thorvg/issues/3003 issue: https://github.com/thorvg/thorvg/issues/2684 Co-Authored-By: Mira Grudzinska <mira@lottiefiles.com>
This commit is contained in:
parent
e395961f3b
commit
01f4d6304a
3 changed files with 15 additions and 15 deletions
|
@ -543,8 +543,8 @@ SwRle* rleRender(const SwBBox* bbox);
|
|||
void rleFree(SwRle* rle);
|
||||
void rleReset(SwRle* rle);
|
||||
void rleMerge(SwRle* rle, SwRle* clip1, SwRle* clip2);
|
||||
void rleClip(SwRle* rle, const SwRle* clip);
|
||||
void rleClip(SwRle* rle, const SwBBox* clip);
|
||||
bool rleClip(SwRle* rle, const SwRle* clip);
|
||||
bool rleClip(SwRle* rle, const SwBBox* clip);
|
||||
|
||||
SwMpool* mpoolInit(uint32_t threads);
|
||||
bool mpoolTerm(SwMpool* mpool);
|
||||
|
|
|
@ -103,11 +103,9 @@ struct SwShapeTask : SwTask
|
|||
|
||||
bool clip(SwRle* target) override
|
||||
{
|
||||
if (shape.fastTrack) rleClip(target, &bbox);
|
||||
else if (shape.rle) rleClip(target, shape.rle);
|
||||
else return false;
|
||||
|
||||
return true;
|
||||
if (shape.fastTrack) return rleClip(target, &bbox);
|
||||
else if (shape.rle) return rleClip(target, shape.rle);
|
||||
return false;
|
||||
}
|
||||
|
||||
void run(unsigned tid) override
|
||||
|
@ -176,10 +174,8 @@ struct SwShapeTask : SwTask
|
|||
//Clip Path
|
||||
for (auto clip = clips.begin(); clip < clips.end(); ++clip) {
|
||||
auto clipper = static_cast<SwTask*>(*clip);
|
||||
//Clip shape rle
|
||||
if (shape.rle && !clipper->clip(shape.rle)) goto err;
|
||||
//Clip stroke rle
|
||||
if (shape.strokeRle && !clipper->clip(shape.strokeRle)) goto err;
|
||||
if (shape.rle && !clipper->clip(shape.rle)) goto err; //Clip shape rle
|
||||
if (shape.strokeRle && !clipper->clip(shape.strokeRle)) goto err; //Clip stroke rle
|
||||
}
|
||||
|
||||
bbox = renderRegion; //sync
|
||||
|
|
|
@ -1020,9 +1020,9 @@ void rleFree(SwRle* rle)
|
|||
}
|
||||
|
||||
|
||||
void rleClip(SwRle *rle, const SwRle *clip)
|
||||
bool rleClip(SwRle *rle, const SwRle *clip)
|
||||
{
|
||||
if (rle->size == 0 || clip->size == 0) return;
|
||||
if (rle->size == 0 || clip->size == 0) return false;
|
||||
auto spanCnt = rle->size > clip->size ? rle->size : clip->size;
|
||||
auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (spanCnt)));
|
||||
auto spansEnd = _intersectSpansRegion(clip, rle, spans, spanCnt);
|
||||
|
@ -1030,17 +1030,21 @@ void rleClip(SwRle *rle, const SwRle *clip)
|
|||
_replaceClipSpan(rle, spans, spansEnd - spans);
|
||||
|
||||
TVGLOG("SW_ENGINE", "Using Path Clipping!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void rleClip(SwRle *rle, const SwBBox* clip)
|
||||
bool rleClip(SwRle *rle, const SwBBox* clip)
|
||||
{
|
||||
if (rle->size == 0) return;
|
||||
if (rle->size == 0) return false;
|
||||
auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (rle->size)));
|
||||
auto spansEnd = _intersectSpansRect(clip, rle, spans, rle->size);
|
||||
|
||||
_replaceClipSpan(rle, spans, spansEnd - spans);
|
||||
|
||||
TVGLOG("SW_ENGINE", "Using Box Clipping!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue