diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 31b6e3b8..3dad781e 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -300,6 +300,7 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw 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 fastTrack); +bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee); void shapeReset(SwShape* shape); bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite); @@ -322,7 +323,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); void strokeFree(SwStroke* stroke); -bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); +bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline); bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias); void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); void imageReset(SwImage* image); diff --git a/src/lib/sw_engine/tvgSwImage.cpp b/src/lib/sw_engine/tvgSwImage.cpp index 2ef024d1..2233f7e5 100644 --- a/src/lib/sw_engine/tvgSwImage.cpp +++ b/src/lib/sw_engine/tvgSwImage.cpp @@ -19,7 +19,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include +#include "tvgMath.h" #include "tvgSwCommon.h" /************************************************************************/ @@ -72,10 +72,19 @@ 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) +bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline) { - if (!_genOutline(image, transform, mpool, tid)) return false; - return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, false); + if (outline || mathRotated(transform)) { + if (!_genOutline(image, transform, mpool, tid)) return false; + return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, false); + //Fast Track, don't need outlines. + } else { + renderRegion.min.x = static_cast(round(transform->e13)); + renderRegion.max.x = renderRegion.min.x + static_cast(image->w); + renderRegion.min.y = static_cast(round(transform->e23)); + renderRegion.max.y= renderRegion.min.y + static_cast(image->h); + return mathClipBBox(clipRegion, renderRegion); + } } diff --git a/src/lib/sw_engine/tvgSwMath.cpp b/src/lib/sw_engine/tvgSwMath.cpp index 22bc97f0..e7470c74 100644 --- a/src/lib/sw_engine/tvgSwMath.cpp +++ b/src/lib/sw_engine/tvgSwMath.cpp @@ -442,6 +442,24 @@ SwPoint mathTransform(const Point* to, const Matrix* transform) } +bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee) +{ + clipee.max.x = (clipee.max.x < clipper.max.x) ? clipee.max.x : clipper.max.x; + clipee.max.y = (clipee.max.y < clipper.max.y) ? clipee.max.y : clipper.max.y; + clipee.min.x = (clipee.min.x > clipper.min.x) ? clipee.min.x : clipper.min.x; + clipee.min.y = (clipee.min.y > clipper.min.y) ? clipee.min.y : clipper.min.y; + + //Check valid region + if (clipee.max.x - clipee.min.x < 1 && clipee.max.y - clipee.min.y < 1) return false; + + //Check boundary + if (clipee.min.x >= clipper.max.x || clipee.min.y >= clipper.max.y || + clipee.max.x <= clipper.min.x || clipee.max.y <= clipper.min.y) return false; + + return true; +} + + bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack) { if (!outline) return false; @@ -466,7 +484,6 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S if (yMin > pt->y) yMin = pt->y; if (yMax < pt->y) yMax = pt->y; } - //Since no antialiasing is applied in the Fast Track case, //the rasterization region has to be rearranged. //https://github.com/Samsung/thorvg/issues/916 @@ -481,18 +498,5 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S 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; - renderRegion.min.x = (renderRegion.min.x > clipRegion.min.x) ? renderRegion.min.x : clipRegion.min.x; - renderRegion.min.y = (renderRegion.min.y > clipRegion.min.y) ? renderRegion.min.y : clipRegion.min.y; - - //Check valid region - if (renderRegion.max.x - renderRegion.min.x < 1 && renderRegion.max.y - renderRegion.min.y < 1) return false; - - //Check boundary - if (renderRegion.min.x >= clipRegion.max.x || renderRegion.min.y >= clipRegion.max.y || - renderRegion.max.x <= clipRegion.min.x || renderRegion.max.y <= clipRegion.min.y) return false; - - return true; + return mathClipBBox(clipRegion, renderRegion); } \ No newline at end of file diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index b50aa625..8cc0b8e4 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -192,10 +192,11 @@ struct SwImageTask : SwTask if (!image.data || image.w == 0 || image.h == 0) goto end; image.stride = image.w; //same, pixel buffer size. - if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end; + auto clipPath = (clips.count > 0) ? true : false; - //Clip Path? - if (clips.count > 0) { + if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid, clipPath)) goto end; + + if (clipPath) { if (!imageGenRle(&image, pdata, bbox, false)) goto end; if (image.rle) { for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { diff --git a/src/lib/tvgMath.h b/src/lib/tvgMath.h index 363fd30b..b9a0488d 100644 --- a/src/lib/tvgMath.h +++ b/src/lib/tvgMath.h @@ -28,6 +28,12 @@ #include #include "tvgCommon.h" +static inline bool mathRotated(const Matrix* m) +{ + if (fabs(m->e12) > FLT_EPSILON || fabs(m->e21 > FLT_EPSILON)) return true; + else return false; +} + static inline bool mathIdentity(const Matrix* m) {