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:
Hermet Park 2021-12-17 17:23:55 +09:00 committed by Hermet Park
parent 05fefcf61f
commit df64a7b0dc
4 changed files with 24 additions and 25 deletions

View file

@ -30,7 +30,7 @@
int32_t dw = surface->stride;
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
int32_t vv = 0, uu = 0;
int32_t minx = 0, maxx = 0;
int32_t minx, maxx;
float dx, u, v, iptr;
uint32_t* buf;
SwSpan* span = nullptr; //used only when rle based.
@ -42,24 +42,36 @@
if (!_arrange(image, region, yStart, yEnd)) return;
//Loop through all lines in the segment
y = yStart;
uint32_t spanIdx = 0;
if (region) {
minx = region->min.x;
maxx = region->max.x;
} 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) {
x1 = _xa;
x2 = _xb;
if (!region) {
minx = span->x;
maxx = span->x + span->len;
minx = INT32_MAX;
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 (x2 > maxx) x2 = maxx;
@ -138,12 +150,9 @@ next:
_ua += _dudya;
_va += _dvdya;
if (span) {
++span;
y = span->y;
} else {
y++;
}
if (!region && spanIdx >= image->rle->size) break;
++y;
}
xa = _xa;
xb = _xb;

View file

@ -111,13 +111,11 @@ struct SwShapeTask : SwTask
//Fill
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
if (visibleFill) {
auto antiAlias = (flags & RenderUpdateFlag::IgnoreAliasing) ? false : true;
/* We assume that if stroke width is bigger than 2,
shape outline below stroke could be full covered by stroke drawing.
Thus it turns off antialising in that condition.
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;
}

View file

@ -223,15 +223,7 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
}
}
if (!compFastTrack) {
//Bad design!: ignore anti-aliasing if the bitmap image is the source of the clip-path!
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);
tdata = target->pImpl->update(renderer, pTransform, 255, clips, pFlag);
if (method == CompositeMethod::ClipPath) clips.push(tdata);
}
}

View file

@ -28,7 +28,7 @@
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
{