common paint: improve rotation condition precision
authorHermet Park <chuneon.park@samsung.com>
Fri, 12 Nov 2021 10:06:41 +0000 (19:06 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Tue, 16 Nov 2021 08:37:47 +0000 (17:37 +0900)
cover the four cases: 0, 90, 180, 270 degrees...

src/lib/sw_engine/tvgSwImage.cpp
src/lib/sw_engine/tvgSwMath.cpp
src/lib/tvgMath.h
src/lib/tvgPaint.cpp

index 2233f7e..b19078e 100644 (file)
@@ -74,15 +74,34 @@ 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 outline)
 {
-    if (outline || mathRotated(transform)) {
+    if (outline || !mathRightAngle(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<SwCoord>(round(transform->e13));
-        renderRegion.max.x = renderRegion.min.x + static_cast<SwCoord>(image->w);
-        renderRegion.min.y = static_cast<SwCoord>(round(transform->e23));
-        renderRegion.max.y= renderRegion.min.y + static_cast<SwCoord>(image->h);
+        auto w = static_cast<float>(image->w);
+        auto h = static_cast<float>(image->h);
+
+        Point pt[4] = {{0 ,0}, {w, 0}, {w, h}, {0, h}};
+        for (int i = 0; i < 4; i++) mathMultiply(&pt[i], transform);
+
+        auto xMin = pt[0].x;
+        auto xMax = pt[0].x;
+        auto yMin = pt[0].y;
+        auto yMax = pt[0].y;
+
+        for (uint32_t i = 1; i < 4; ++i) {
+            if (xMin > pt[i].x) xMin = pt[i].x;
+            if (xMax < pt[i].x) xMax = pt[i].x;
+            if (yMin > pt[i].y) yMin = pt[i].y;
+            if (yMax < pt[i].y) yMax = pt[i].y;
+        }
+
+        renderRegion.min.x = static_cast<SwCoord>(xMin);
+        renderRegion.max.x = static_cast<SwCoord>(round(xMax));
+        renderRegion.min.y = static_cast<SwCoord>(yMin);
+        renderRegion.max.y = static_cast<SwCoord>(round(yMax));
+
         return mathClipBBox(clipRegion, renderRegion);
     }
 }
index e7470c7..7a3529b 100644 (file)
@@ -478,7 +478,7 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
 
     ++pt;
 
-    for(uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
+    for (uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
         if (xMin > pt->x) xMin = pt->x;
         if (xMax < pt->x) xMax = pt->x;
         if (yMin > pt->y) yMin = pt->y;
index 81c9744..2a3d40b 100644 (file)
 #include <math.h>
 #include "tvgCommon.h"
 
-static inline bool mathRotated(const Matrix* m)
+static inline bool mathRightAngle(const Matrix* m)
 {
-    if (fabs(m->e12) > FLT_EPSILON || fabs(m->e21 > FLT_EPSILON) || (m->e11 < -FLT_EPSILON) || (m->e22 < -FLT_EPSILON)) return true;
-
-    else return false;
+   auto radian = fabsf(atan2(m->e21, m->e11));
+   if (radian < FLT_EPSILON || fabsf(radian - float(M_PI_2)) < FLT_EPSILON || fabsf(radian - float(M_PI)) < FLT_EPSILON) return true;
+   return false;
 }
 
 
index b437ccd..16e9ab0 100644 (file)
@@ -46,10 +46,10 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
     if (rTransform) rTransform->update();
 
     //No Rotation?
-    if (pTransform && (fabs(pTransform->m.e12) > FLT_EPSILON || fabs(pTransform->m.e21 > FLT_EPSILON))) return false;
-    if (rTransform && (fabs(rTransform->m.e12) > FLT_EPSILON || fabs(rTransform->m.e21 > FLT_EPSILON))) return false;
+    if (pTransform && !mathRightAngle(&pTransform->m)) return false;
+    if (rTransform && !mathRightAngle(&rTransform->m)) return false;
 
-    //Axis-Aligned Rectangle?
+    //Perpendicular Rectangle?
     auto pt1 = pts + 0;
     auto pt2 = pts + 1;
     auto pt3 = pts + 2;