From 48faa69c75e94606394f9a91d30d904ded152783 Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Fri, 29 Oct 2021 01:14:12 +0200 Subject: [PATCH] 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. --- src/lib/sw_engine/tvgSwCommon.h | 2 +- src/lib/sw_engine/tvgSwImage.cpp | 2 +- src/lib/sw_engine/tvgSwMath.cpp | 21 ++++++++++++++----- src/lib/sw_engine/tvgSwShape.cpp | 44 +++++++--------------------------------- 4 files changed, 25 insertions(+), 44 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 42bb91e..7ac774e 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -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); diff --git a/src/lib/sw_engine/tvgSwImage.cpp b/src/lib/sw_engine/tvgSwImage.cpp index fb4ba34..abfe38c 100644 --- a/src/lib/sw_engine/tvgSwImage.cpp +++ b/src/lib/sw_engine/tvgSwImage.cpp @@ -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); } diff --git a/src/lib/sw_engine/tvgSwMath.cpp b/src/lib/sw_engine/tvgSwMath.cpp index 1f59039..61dc801 100644 --- a/src/lib/sw_engine/tvgSwMath.cpp +++ b/src/lib/sw_engine/tvgSwMath.cpp @@ -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(round(xMin / 64.0f)); + renderRegion.max.x = static_cast(round(xMax / 64.0f)); + renderRegion.min.y = static_cast(round(yMin / 64.0f)); + renderRegion.max.y = static_cast(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; diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index 411c59b..0354c35 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -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(round(xMin / 64.0f)); - bbox.max.x = static_cast(round(xMax / 64.0f)); - bbox.min.y = static_cast(round(yMin / 64.0f)); - bbox.max.y = static_cast(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; } -- 2.7.4