updated copyright.
[platform/core/graphics/tizenvg.git] / src / lib / sw_engine / tvgSwShape.cpp
index 411c59b..82d812e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved.
 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -19,6 +19,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+
 #include "tvgSwCommon.h"
 #include "tvgBezier.h"
 #include <float.h>
@@ -64,7 +65,7 @@ static bool _growOutlineContour(SwOutline& outline, uint32_t n)
 {
     if (outline.reservedCntrsCnt >= outline.cntrsCnt + n) return false;
     outline.reservedCntrsCnt = outline.cntrsCnt + n;
-    outline.cntrs = static_cast<uint16_t*>(realloc(outline.cntrs, outline.reservedCntrsCnt * sizeof(uint16_t)));
+    outline.cntrs = static_cast<uint32_t*>(realloc(outline.cntrs, outline.reservedCntrsCnt * sizeof(uint32_t)));
     return true;
 }
 
@@ -297,7 +298,7 @@ static SwOutline* _genDashOutline(const Shape* sdata, const Matrix* transform)
     auto outlineCntrsCnt = 0;
 
     for (uint32_t i = 0; i < cmdCnt; ++i) {
-        switch(*(cmds + i)) {
+        switch (*(cmds + i)) {
             case PathCommand::Close: {
                 ++outlinePtsCnt;
                 break;
@@ -326,7 +327,7 @@ static SwOutline* _genDashOutline(const Shape* sdata, const Matrix* transform)
     _growOutlineContour(*dash.outline, outlineCntrsCnt * 20);
 
     while (cmdCnt-- > 0) {
-        switch(*cmds) {
+        switch (*cmds) {
             case PathCommand::Close: {
                 _dashLineTo(dash, &dash.ptStart, transform);
                 break;
@@ -360,14 +361,11 @@ static SwOutline* _genDashOutline(const Shape* sdata, const Matrix* transform)
 }
 
 
-static bool _fastTrack(const SwOutline* outline, SwBBox& bbox)
+static bool _axisAlignedRect(const SwOutline* outline)
 {
-    //Fast Track: Othogonal rectangle?
+    //Fast Track: axis-aligned 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,42 +374,14 @@ 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;
 }
 
 
 
-static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transform, SwMpool* mpool, unsigned tid)
+static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transform, SwMpool* mpool, unsigned tid, bool hasComposite)
 {
     const PathCommand* cmds = nullptr;
     auto cmdCnt = sdata->pathCommands(&cmds);
@@ -428,7 +398,7 @@ static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transf
     auto closeCnt = 0;
 
     for (uint32_t i = 0; i < cmdCnt; ++i) {
-        switch(*(cmds + i)) {
+        switch (*(cmds + i)) {
             case PathCommand::Close: {
                 ++outlinePtsCnt;
                 ++closeCnt;
@@ -471,7 +441,7 @@ static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transf
 
     //Generate Outlines
     while (cmdCnt-- > 0) {
-        switch(*cmds) {
+        switch (*cmds) {
             case PathCommand::Close: {
                 _outlineClose(*outline);
                 break;
@@ -500,6 +470,7 @@ static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transf
     outline->fillRule = sdata->fillRule();
     shape->outline = outline;
 
+    shape->fastTrack = (!hasComposite && _axisAlignedRect(shape->outline));
     return true;
 }
 
@@ -508,10 +479,10 @@ static bool _genOutline(SwShape* shape, const Shape* sdata, const Matrix* transf
 /* External Class Implementation                                        */
 /************************************************************************/
 
-bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform,  const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
+bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform,  const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite)
 {
-    if (!_genOutline(shape, sdata, transform, mpool, tid)) return false;
-    if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion)) return false;
+    if (!_genOutline(shape, sdata, transform, mpool, tid, hasComposite)) return false;
+    if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->fastTrack)) return false;
 
     //Keep it for Rasterization Region
     shape->bbox = renderRegion;
@@ -533,14 +504,14 @@ bool shapePrepared(const SwShape* shape)
 }
 
 
-bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, bool antiAlias, bool hasComposite)
+bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, bool antiAlias)
 {
     //FIXME: Should we draw it?
     //Case: Stroke Line
     //if (shape.outline->opened) return true;
 
     //Case A: Fast Track Rectangle Drawing
-    if (!hasComposite && (shape->rect = _fastTrack(shape->outline, shape->bbox))) return true;
+    if (shape->fastTrack) return true;
 
     //Case B: Normal Shape RLE Drawing
     if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, antiAlias))) return true;
@@ -560,7 +531,7 @@ void shapeReset(SwShape* shape)
 {
     rleReset(shape->rle);
     rleReset(shape->strokeRle);
-    shape->rect = false;
+    shape->fastTrack = false;
     shape->bbox.reset();
 }
 
@@ -613,7 +584,7 @@ bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transfo
     //Normal Style stroke
     } else {
         if (!shape->outline) {
-            if (!_genOutline(shape, sdata, transform, mpool, tid)) return false;
+            if (!_genOutline(shape, sdata, transform, mpool, tid, false)) return false;
         }
         shapeOutline = shape->outline;
     }
@@ -624,12 +595,8 @@ bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transfo
     }
 
     strokeOutline = strokeExportOutline(shape->stroke, mpool, tid);
-    if (!strokeOutline) {
-        ret = false;
-        goto fail;
-    }
 
-    if (!mathUpdateOutlineBBox(strokeOutline, clipRegion, renderRegion)) {
+    if (!mathUpdateOutlineBBox(strokeOutline, clipRegion, renderRegion, false)) {
         ret = false;
         goto fail;
     }