mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-24 23:28:57 +00:00
sw_engine raster: fix a crash at the texmap clipping.
Handle correctly duplicated spans from the multiple y span data. Previous logic only expected the one single y span data from the rle. However rle might have multiple y span data if the anti-aliasing is applied. This patch also removed the bad design of the common engine which handles the anti-alising option to ignore the anti-aliasing rle generation. Just realized, it's difficult to control that condition due to scene-composition.
This commit is contained in:
parent
05fefcf61f
commit
df64a7b0dc
4 changed files with 24 additions and 25 deletions
|
@ -30,7 +30,7 @@
|
||||||
int32_t dw = surface->stride;
|
int32_t dw = surface->stride;
|
||||||
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
||||||
int32_t vv = 0, uu = 0;
|
int32_t vv = 0, uu = 0;
|
||||||
int32_t minx = 0, maxx = 0;
|
int32_t minx, maxx;
|
||||||
float dx, u, v, iptr;
|
float dx, u, v, iptr;
|
||||||
uint32_t* buf;
|
uint32_t* buf;
|
||||||
SwSpan* span = nullptr; //used only when rle based.
|
SwSpan* span = nullptr; //used only when rle based.
|
||||||
|
@ -42,24 +42,36 @@
|
||||||
if (!_arrange(image, region, yStart, yEnd)) return;
|
if (!_arrange(image, region, yStart, yEnd)) return;
|
||||||
|
|
||||||
//Loop through all lines in the segment
|
//Loop through all lines in the segment
|
||||||
y = yStart;
|
uint32_t spanIdx = 0;
|
||||||
|
|
||||||
if (region) {
|
if (region) {
|
||||||
minx = region->min.x;
|
minx = region->min.x;
|
||||||
maxx = region->max.x;
|
maxx = region->max.x;
|
||||||
} else {
|
} else {
|
||||||
span = image->rle->spans + (yStart - image->rle->spans->y);
|
span = image->rle->spans;
|
||||||
|
while (span->y < yStart) {
|
||||||
|
++span;
|
||||||
|
++spanIdx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
y = yStart;
|
||||||
|
|
||||||
while (y < yEnd) {
|
while (y < yEnd) {
|
||||||
x1 = _xa;
|
x1 = _xa;
|
||||||
x2 = _xb;
|
x2 = _xb;
|
||||||
|
|
||||||
if (!region) {
|
if (!region) {
|
||||||
minx = span->x;
|
minx = INT32_MAX;
|
||||||
maxx = span->x + span->len;
|
maxx = INT32_MIN;
|
||||||
|
//one single row, could be consisted of multiple spans.
|
||||||
|
while (span->y == y && spanIdx < image->rle->size) {
|
||||||
|
if (minx > span->x) minx = span->x;
|
||||||
|
if (maxx < span->x + span->len) maxx = span->x + span->len;
|
||||||
|
++span;
|
||||||
|
++spanIdx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x1 < minx) x1 = minx;
|
if (x1 < minx) x1 = minx;
|
||||||
if (x2 > maxx) x2 = maxx;
|
if (x2 > maxx) x2 = maxx;
|
||||||
|
|
||||||
|
@ -138,12 +150,9 @@ next:
|
||||||
_ua += _dudya;
|
_ua += _dudya;
|
||||||
_va += _dvdya;
|
_va += _dvdya;
|
||||||
|
|
||||||
if (span) {
|
if (!region && spanIdx >= image->rle->size) break;
|
||||||
++span;
|
|
||||||
y = span->y;
|
++y;
|
||||||
} else {
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
xa = _xa;
|
xa = _xa;
|
||||||
xb = _xb;
|
xb = _xb;
|
||||||
|
|
|
@ -111,13 +111,11 @@ struct SwShapeTask : SwTask
|
||||||
//Fill
|
//Fill
|
||||||
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
||||||
if (visibleFill) {
|
if (visibleFill) {
|
||||||
auto antiAlias = (flags & RenderUpdateFlag::IgnoreAliasing) ? false : true;
|
|
||||||
|
|
||||||
/* We assume that if stroke width is bigger than 2,
|
/* We assume that if stroke width is bigger than 2,
|
||||||
shape outline below stroke could be full covered by stroke drawing.
|
shape outline below stroke could be full covered by stroke drawing.
|
||||||
Thus it turns off antialising in that condition.
|
Thus it turns off antialising in that condition.
|
||||||
Also, it shouldn't be dash style. */
|
Also, it shouldn't be dash style. */
|
||||||
if (strokeAlpha == 255 && sdata->strokeWidth() > 2 && sdata->strokeDash(nullptr) == 0) antiAlias = false;
|
auto antiAlias = (strokeAlpha == 255 && sdata->strokeWidth() > 2 && sdata->strokeDash(nullptr) == 0) ? false : true;
|
||||||
|
|
||||||
if (!shapeGenRle(&shape, sdata, antiAlias)) goto err;
|
if (!shapeGenRle(&shape, sdata, antiAlias)) goto err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,15 +223,7 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!compFastTrack) {
|
if (!compFastTrack) {
|
||||||
//Bad design!: ignore anti-aliasing if the bitmap image is the source of the clip-path!
|
tdata = target->pImpl->update(renderer, pTransform, 255, clips, pFlag);
|
||||||
auto tempFlag = pFlag;
|
|
||||||
|
|
||||||
if (id == TVG_CLASS_ID_PICTURE) {
|
|
||||||
auto picture = static_cast<Picture*>(compData->source);
|
|
||||||
if (picture->data(nullptr, nullptr)) tempFlag |= RenderUpdateFlag::IgnoreAliasing;
|
|
||||||
}
|
|
||||||
|
|
||||||
tdata = target->pImpl->update(renderer, pTransform, 255, clips, tempFlag);
|
|
||||||
if (method == CompositeMethod::ClipPath) clips.push(tdata);
|
if (method == CompositeMethod::ClipPath) clips.push(tdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
namespace tvg
|
namespace tvg
|
||||||
{
|
{
|
||||||
|
|
||||||
enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255, IgnoreAliasing = 256};
|
enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255};
|
||||||
|
|
||||||
struct Surface
|
struct Surface
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue