mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: fix too small memory of spans
In some clipping cases, the memory allocated for storing spans was too small. As a result, the entire clipped area might not have been rendered. This has been resolved by conditionally increasing the memory allocation when needed. @Issue: https://github.com/thorvg/thorvg/issues/3461
This commit is contained in:
parent
633bcd3176
commit
844fd050bc
1 changed files with 18 additions and 12 deletions
|
@ -737,8 +737,9 @@ static bool _genRle(RleWorker& rw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SwSpan* _intersectSpansRegion(const SwRle *clip, const SwRle *target, SwSpan *outSpans, uint32_t outSpansCnt)
|
static uint32_t _intersectSpansRegion(const SwRle *clip, const SwRle *target, SwSpan *&outSpans, uint32_t outSpansAlloc)
|
||||||
{
|
{
|
||||||
|
auto outSpansCnt = 0;
|
||||||
auto out = outSpans;
|
auto out = outSpans;
|
||||||
auto spans = target->spans;
|
auto spans = target->spans;
|
||||||
auto end = target->spans + target->size;
|
auto end = target->spans + target->size;
|
||||||
|
@ -758,7 +759,7 @@ static SwSpan* _intersectSpansRegion(const SwRle *clip, const SwRle *target, SwS
|
||||||
|
|
||||||
//Try clipping with all clip spans which have a same y-coordinate.
|
//Try clipping with all clip spans which have a same y-coordinate.
|
||||||
auto temp = clipSpans;
|
auto temp = clipSpans;
|
||||||
while(temp < clipEnd && outSpansCnt > 0 && temp->y == clipSpans->y) {
|
while(temp < clipEnd && temp->y == clipSpans->y) {
|
||||||
auto sx1 = spans->x;
|
auto sx1 = spans->x;
|
||||||
auto sx2 = sx1 + spans->len;
|
auto sx2 = sx1 + spans->len;
|
||||||
auto cx1 = temp->x;
|
auto cx1 = temp->x;
|
||||||
|
@ -774,22 +775,27 @@ static SwSpan* _intersectSpansRegion(const SwRle *clip, const SwRle *target, SwS
|
||||||
auto x = sx1 > cx1 ? sx1 : cx1;
|
auto x = sx1 > cx1 ? sx1 : cx1;
|
||||||
auto len = (sx2 < cx2 ? sx2 : cx2) - x;
|
auto len = (sx2 < cx2 ? sx2 : cx2) - x;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
|
if (outSpansCnt == outSpansAlloc) {
|
||||||
|
outSpansAlloc *= 2;
|
||||||
|
outSpans = tvg::realloc<SwSpan*>(outSpans, sizeof(SwSpan) * outSpansAlloc);
|
||||||
|
out = outSpans + outSpansCnt;
|
||||||
|
}
|
||||||
out->x = x;
|
out->x = x;
|
||||||
out->y = temp->y;
|
out->y = temp->y;
|
||||||
out->len = len;
|
out->len = len;
|
||||||
out->coverage = (uint8_t)(((spans->coverage * temp->coverage) + 0xff) >> 8);
|
out->coverage = (uint8_t)(((spans->coverage * temp->coverage) + 0xff) >> 8);
|
||||||
++out;
|
++out;
|
||||||
--outSpansCnt;
|
++outSpansCnt;
|
||||||
}
|
}
|
||||||
++temp;
|
++temp;
|
||||||
}
|
}
|
||||||
++spans;
|
++spans;
|
||||||
}
|
}
|
||||||
return out;
|
return outSpansCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRle *targetRle, SwSpan *outSpans, uint32_t outSpansCnt)
|
static uint32_t _intersectSpansRect(const SwBBox *bbox, const SwRle *targetRle, SwSpan *outSpans, uint32_t outSpansCnt)
|
||||||
{
|
{
|
||||||
auto out = outSpans;
|
auto out = outSpans;
|
||||||
auto spans = targetRle->spans;
|
auto spans = targetRle->spans;
|
||||||
|
@ -824,7 +830,7 @@ static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRle *targetRle, S
|
||||||
}
|
}
|
||||||
++spans;
|
++spans;
|
||||||
}
|
}
|
||||||
return out;
|
return out - outSpans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -997,11 +1003,11 @@ void rleFree(SwRle* rle)
|
||||||
bool rleClip(SwRle *rle, const SwRle *clip)
|
bool rleClip(SwRle *rle, const SwRle *clip)
|
||||||
{
|
{
|
||||||
if (rle->size == 0 || clip->size == 0) return false;
|
if (rle->size == 0 || clip->size == 0) return false;
|
||||||
auto spanCnt = rle->size > clip->size ? rle->size : clip->size;
|
auto spanAlloc = rle->size > clip->size ? rle->size : clip->size;
|
||||||
auto spans = tvg::malloc<SwSpan*>(sizeof(SwSpan) * (spanCnt));
|
auto spans = tvg::malloc<SwSpan*>(sizeof(SwSpan) * spanAlloc);
|
||||||
auto spansEnd = _intersectSpansRegion(clip, rle, spans, spanCnt);
|
auto spanCnt = _intersectSpansRegion(clip, rle, spans, spanAlloc);
|
||||||
|
|
||||||
_replaceClipSpan(rle, spans, spansEnd - spans);
|
_replaceClipSpan(rle, spans, spanCnt);
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Using Path Clipping!");
|
TVGLOG("SW_ENGINE", "Using Path Clipping!");
|
||||||
|
|
||||||
|
@ -1013,9 +1019,9 @@ bool rleClip(SwRle *rle, const SwBBox* clip)
|
||||||
{
|
{
|
||||||
if (rle->size == 0) return false;
|
if (rle->size == 0) return false;
|
||||||
auto spans = tvg::malloc<SwSpan*>(sizeof(SwSpan) * (rle->size));
|
auto spans = tvg::malloc<SwSpan*>(sizeof(SwSpan) * (rle->size));
|
||||||
auto spansEnd = _intersectSpansRect(clip, rle, spans, rle->size);
|
auto spanCnt = _intersectSpansRect(clip, rle, spans, rle->size);
|
||||||
|
|
||||||
_replaceClipSpan(rle, spans, spansEnd - spans);
|
_replaceClipSpan(rle, spans, spanCnt);
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Using Box Clipping!");
|
TVGLOG("SW_ENGINE", "Using Box Clipping!");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue