common shape: revise RenderTransform for Scene Transformation 12/233612/4
authorHermet Park <chuneon.park@samsung.com>
Sun, 17 May 2020 05:54:55 +0000 (14:54 +0900)
committerHermet Park <chuneon.park@samsung.com>
Sun, 17 May 2020 06:09:20 +0000 (15:09 +0900)
This RenderTransform takes over all transform information.

Change-Id: I21b6a55de05feca56c40f3ff402d18445417463c

src/lib/tvgRenderCommon.h
src/lib/tvgShape.cpp
src/lib/tvgShapeImpl.h

index b21c244..a3bfcb6 100644 (file)
@@ -32,12 +32,27 @@ enum RenderUpdateFlag {None = 0, Path = 1, Fill = 2, Transform = 4, All = 8};
 
 struct RenderTransform
 {
+    //3x3 Matrix Elements
     float e11, e12, e13;
     float e21, e22, e23;
     float e31, e32, e33;
 
-    void identity()
+    float x = 0.0f;
+    float y = 0.0f;
+    float degree = 0.0f;  //rotation degree
+    float factor = 1.0f;  //scale factor
+
+    bool update()
     {
+        constexpr auto PI = 3.141592f;
+
+        //Init Status
+        if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON &&
+            fabsf(degree) <= FLT_EPSILON && fabsf(factor - 1) <= FLT_EPSILON) {
+            return false;
+        }
+
+        //identity
         e11 = 1.0f;
         e12 = 0.0f;
         e13 = 0.0f;
@@ -47,44 +62,38 @@ struct RenderTransform
         e31 = 0.0f;
         e32 = 0.0f;
         e33 = 1.0f;
-    }
 
-    void rotate(float degree)
-    {
-        constexpr auto PI = 3.141592f;
+        //rotation
+        if (fabsf(degree) > FLT_EPSILON) {
+            auto radian = degree / 180.0f * PI;
+            auto cosVal = cosf(radian);
+            auto sinVal = sinf(radian);
+
+            auto t11 = e11 * cosVal + e12 * sinVal;
+            auto t12 = e11 * -sinVal + e12 * cosVal;
+            auto t21 = e21 * cosVal + e22 * sinVal;
+            auto t22 = e21 * -sinVal + e22 * cosVal;
+            auto t31 = e31 * cosVal + e32 * sinVal;
+            auto t32 = e31 * -sinVal + e32 * cosVal;
+
+            e11 = t11;
+            e12 = t12;
+            e21 = t21;
+            e22 = t22;
+            e31 = t31;
+            e32 = t32;
+        }
 
-        if (fabsf(degree) <= FLT_EPSILON) return;
-
-        auto radian = degree / 180.0f * PI;
-        auto cosVal = cosf(radian);
-        auto sinVal = sinf(radian);
-
-        auto t11 = e11 * cosVal + e12 * sinVal;
-        auto t12 = e11 * -sinVal + e12 * cosVal;
-        auto t21 = e21 * cosVal + e22 * sinVal;
-        auto t22 = e21 * -sinVal + e22 * cosVal;
-        auto t31 = e31 * cosVal + e32 * sinVal;
-        auto t32 = e31 * -sinVal + e32 * cosVal;
-
-        e11 = t11;
-        e12 = t12;
-        e21 = t21;
-        e22 = t22;
-        e31 = t31;
-        e32 = t32;
-    }
+        //scale
+        e11 *= factor;
+        e22 *= factor;
+        e33 *= factor;
 
-    void translate(float x, float y)
-    {
+        //translate
         e31 += x;
         e32 += y;
-    }
 
-    void scale(float factor)
-    {
-        e11 *= factor;
-        e22 *= factor;
-        e33 *= factor;
+        return true;
     }
 
     RenderTransform& operator*=(const RenderTransform rhs)
index 6665a55..432a8a6 100644 (file)
@@ -247,12 +247,7 @@ int Shape::scale(float factor) noexcept
     auto impl = pImpl.get();
     assert(impl);
 
-    if (fabsf(factor - impl->scale) <= FLT_EPSILON) return -1;
-
-    impl->scale = factor;
-    impl->flag |= RenderUpdateFlag::Transform;
-
-    return 0;
+    return impl->scale(factor);
 }
 
 
@@ -261,12 +256,7 @@ int Shape::rotate(float degree) noexcept
     auto impl = pImpl.get();
     assert(impl);
 
-    if (fabsf(degree - impl->rotate) <= FLT_EPSILON) return -1;
-
-    impl->rotate = degree;
-    impl->flag |= RenderUpdateFlag::Transform;
-
-    return 0;
+    return impl->rotate(degree);
 }
 
 
@@ -275,13 +265,7 @@ int Shape::translate(float x, float y) noexcept
     auto impl = pImpl.get();
     assert(impl);
 
-    if (fabsf(x - impl->x) <= FLT_EPSILON && fabsf(y - impl->y) <= FLT_EPSILON) return -1;
-
-    impl->x = x;
-    impl->y = y;
-    impl->flag |= RenderUpdateFlag::Transform;
-
-    return 0;
+    return impl->translate(x, y);
 }
 
 
index 6b81dc0..e552a3b 100644 (file)
@@ -38,13 +38,11 @@ struct Shape::Impl
     ShapeFill *fill = nullptr;
     ShapeStroke *stroke = nullptr;
     ShapePath *path = nullptr;
+    RenderTransform *transform = nullptr;
     uint8_t color[4] = {0, 0, 0, 0};    //r, g, b, a
-    float scale = 1;
-    float rotate = 0;
-    float x = 0;
-    float y = 0;
-    void *edata = nullptr;              //engine data
     size_t flag = RenderUpdateFlag::None;
+    void *edata = nullptr;              //engine data
+
 
     Impl() : path(new ShapePath)
     {
@@ -55,6 +53,7 @@ struct Shape::Impl
         if (path) delete(path);
         if (stroke) delete(stroke);
         if (fill) delete(fill);
+        if (transform) delete(transform);
     }
 
     bool dispose(Shape& shape, RenderMethod& renderer)
@@ -70,16 +69,13 @@ struct Shape::Impl
     bool update(Shape& shape, RenderMethod& renderer)
     {
         if (flag & RenderUpdateFlag::Transform) {
-            RenderTransform transform;
-            transform.identity();
-            transform.rotate(rotate);
-            transform.scale(scale);
-            transform.translate(x, y);
-            edata = renderer.prepare(shape, edata, &transform, static_cast<RenderUpdateFlag>(flag));
-        } else {
-            edata = renderer.prepare(shape, edata, nullptr, static_cast<RenderUpdateFlag>(flag));
+            assert(transform);
+            if (!transform->update()) {
+                delete(transform);
+                transform = nullptr;
+            }
         }
-
+        edata = renderer.prepare(shape, edata, transform, static_cast<RenderUpdateFlag>(flag));
         flag = RenderUpdateFlag::None;
 
         if (edata) return true;
@@ -91,6 +87,52 @@ struct Shape::Impl
         assert(path);
         return path->bounds(x, y, w, h);
     }
+
+    bool scale(float factor)
+    {
+        if (transform) {
+            if (fabsf(factor - transform->factor) <= FLT_EPSILON) return -1;
+        } else {
+            if (fabsf(factor) <= FLT_EPSILON) return -1;
+            transform = new RenderTransform();
+            assert(transform);
+        }
+        transform->factor = factor;
+        flag |= RenderUpdateFlag::Transform;
+
+        return 0;
+    }
+
+    bool rotate(float degree)
+    {
+        if (transform) {
+            if (fabsf(degree - transform->degree) <= FLT_EPSILON) return -1;
+        } else {
+            if (fabsf(degree) <= FLT_EPSILON) return -1;
+            transform = new RenderTransform();
+            assert(transform);
+        }
+        transform->degree = degree;
+        flag |= RenderUpdateFlag::Transform;
+
+        return 0;
+    }
+
+    bool translate(float x, float y)
+    {
+        if (transform) {
+            if (fabsf(x - transform->x) <= FLT_EPSILON && fabsf(y - transform->y) <= FLT_EPSILON) return -1;
+        } else {
+            if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return -1;
+            transform = new RenderTransform();
+            assert(transform);
+        }
+        transform->x = x;
+        transform->y = y;
+        flag |= RenderUpdateFlag::Transform;
+
+        return 0;
+    }
 };
 
 #endif //_TVG_SHAPE_IMPL_H_
\ No newline at end of file