sw_engine: refactoring

The rasterization region was rearranged in the case of fastTrack,
but its validation and boundaries weren't check, causing segf in some
cases. Fixed.
This commit is contained in:
Mira Grudzinska 2021-10-29 01:14:12 +02:00 committed by Hermet Park
parent ba25cb80eb
commit 362d2dfd0f
4 changed files with 25 additions and 44 deletions

View file

@ -298,7 +298,7 @@ SwFixed mathLength(const SwPoint& pt);
bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
SwPoint mathTransform(const Point* to, const Matrix* transform);
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion);
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool rect);
bool mathInverse(const Matrix* m, Matrix* invM);
bool mathMultiply(const Matrix* lhs, Matrix* rhs);
bool mathIdentity(const Matrix* m);

View file

@ -75,7 +75,7 @@ static bool _genOutline(SwImage* image, const Matrix* transform, SwMpool* mpool,
bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
{
if (!_genOutline(image, transform, mpool, tid)) return false;
return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion);
return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, false);
}

View file

@ -443,7 +443,7 @@ SwPoint mathTransform(const Point* to, const Matrix* transform)
}
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion)
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool rect)
{
if (!outline) return false;
@ -467,10 +467,21 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
if (yMin > pt->y) yMin = pt->y;
if (yMax < pt->y) yMax = pt->y;
}
renderRegion.min.x = xMin >> 6;
renderRegion.max.x = (xMax + 63) >> 6;
renderRegion.min.y = yMin >> 6;
renderRegion.max.y = (yMax + 63) >> 6;
//Since no antialiasing is applied in the Fast Track case,
//the rasterization region has to be rearranged.
//https://github.com/Samsung/thorvg/issues/916
if (rect) {
renderRegion.min.x = static_cast<SwCoord>(round(xMin / 64.0f));
renderRegion.max.x = static_cast<SwCoord>(round(xMax / 64.0f));
renderRegion.min.y = static_cast<SwCoord>(round(yMin / 64.0f));
renderRegion.max.y = static_cast<SwCoord>(round(yMax / 64.0f));
} else {
renderRegion.min.x = xMin >> 6;
renderRegion.max.x = (xMax + 63) >> 6;
renderRegion.min.y = yMin >> 6;
renderRegion.max.y = (yMax + 63) >> 6;
}
renderRegion.max.x = (renderRegion.max.x < clipRegion.max.x) ? renderRegion.max.x : clipRegion.max.x;
renderRegion.max.y = (renderRegion.max.y < clipRegion.max.y) ? renderRegion.max.y : clipRegion.max.y;

View file

@ -360,14 +360,11 @@ static SwOutline* _genDashOutline(const Shape* sdata, const Matrix* transform)
}
static bool _fastTrack(const SwOutline* outline, SwBBox& bbox)
static bool _fastTrack(const SwOutline* outline)
{
//Fast Track: Othogonal rectangle?
//Fast Track: Orthogonal rectangle?
if (outline->ptsCnt != 5) return false;
/* NOTICE: If the antialiased pixels matter, we can turn off the fast track
in case the pixels have the pixel fraction. */
auto pt1 = outline->pts + 0;
auto pt2 = outline->pts + 1;
auto pt3 = outline->pts + 2;
@ -376,35 +373,7 @@ static bool _fastTrack(const SwOutline* outline, SwBBox& bbox)
auto a = SwPoint{pt1->x, pt3->y};
auto b = SwPoint{pt3->x, pt1->y};
//Matched!
if ((*pt2 == a && *pt4 == b) || (*pt2 == b && *pt4 == a)) {
//Since no antialiasing is applied in the Fast Track case,
//the rasterization region has to be rearranged.
//https://github.com/Samsung/thorvg/issues/916
auto corner1 = outline->pts;
auto corner3 = outline->pts + 2;
auto xMin = corner1->x;
auto xMax = corner3->x;
if (xMin > xMax) {
xMax = xMin;
xMin = corner3->x;
}
auto yMin = corner1->y;
auto yMax = corner3->y;
if (yMin > yMax) {
yMax = yMin;
yMin = corner3->y;
}
bbox.min.x = static_cast<SwCoord>(round(xMin / 64.0f));
bbox.max.x = static_cast<SwCoord>(round(xMax / 64.0f));
bbox.min.y = static_cast<SwCoord>(round(yMin / 64.0f));
bbox.max.y = static_cast<SwCoord>(round(yMax / 64.0f));
return true;
}
if ((*pt2 == a && *pt4 == b) || (*pt2 == b && *pt4 == a)) return true;
return false;
}
@ -500,6 +469,7 @@ static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transf
outline->fillRule = sdata->fillRule();
shape->outline = outline;
shape->rect = _fastTrack(shape->outline);
return true;
}
@ -511,7 +481,7 @@ static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transf
bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
{
if (!_genOutline(shape, sdata, transform, mpool, tid)) return false;
if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion)) return false;
if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->rect)) return false;
//Keep it for Rasterization Region
shape->bbox = renderRegion;
@ -540,7 +510,7 @@ bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, bool antiAlias,
//if (shape.outline->opened) return true;
//Case A: Fast Track Rectangle Drawing
if (!hasComposite && (shape->rect = _fastTrack(shape->outline, shape->bbox))) return true;
if (!hasComposite && shape->rect) return true;
//Case B: Normal Shape RLE Drawing
if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, antiAlias))) return true;
@ -629,7 +599,7 @@ bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transfo
goto fail;
}
if (!mathUpdateOutlineBBox(strokeOutline, clipRegion, renderRegion)) {
if (!mathUpdateOutlineBBox(strokeOutline, clipRegion, renderRegion, false)) {
ret = false;
goto fail;
}