common transformation: fix transformation multiply 16/238716/7
authorHermet Park <chuneon.park@samsung.com>
Thu, 16 Jul 2020 11:42:42 +0000 (20:42 +0900)
committerHermet Park <chuneon.park@samsung.com>
Fri, 17 Jul 2020 08:54:21 +0000 (17:54 +0900)
Change-Id: Ibc95fab0abfc07aa7f0c4ff6c74785d4f73d02c7

src/lib/sw_engine/tvgSwFill.cpp
src/lib/sw_engine/tvgSwShape.cpp
src/lib/tvgRender.cpp
src/loaders/svg_loader/tvgSvgSceneBuilder.cpp
test/svgs/duke.svg [new file with mode: 0644]
test/testCustomTransform.cpp

index fd857f9..43514bc 100644 (file)
@@ -100,12 +100,12 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr
         auto cy = (y2 - y1) * 0.5f + y1;
         auto dx = x1 - cx;
         auto dy = y1 - cy;
-        x1 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx;
-        y1 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy;
+        x1 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx;
+        y1 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy;
         dx = x2 - cx;
         dy = y2 - cy;
-        x2 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx;
-        y2 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy;
+        x2 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx;
+        y2 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy;
     }
 
     fill->linear.dx = x2 - x1;
@@ -131,8 +131,8 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr
     if (radius < FLT_EPSILON) return true;
 
     if (transform) {
-        auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e31;
-        auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e32;
+        auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e13;
+        auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e23;
         fill->radial.cx = tx;
         fill->radial.cy = ty;
         radius *= transform->e33;
index 66655b0..026dae0 100644 (file)
@@ -239,8 +239,8 @@ static void _transformOutline(SwOutline* outline, const Matrix* transform)
     for(uint32_t i = 0; i < outline->ptsCnt; ++i) {
         auto dx = static_cast<float>(outline->pts[i].x >> 6);
         auto dy = static_cast<float>(outline->pts[i].y >> 6);
-        auto tx = dx * transform->e11 + dy * transform->e12 + transform->e31;
-        auto ty = dx * transform->e21 + dy * transform->e22 + transform->e32;
+        auto tx = dx * transform->e11 + dy * transform->e12 + transform->e13;
+        auto ty = dx * transform->e21 + dy * transform->e22 + transform->e23;
         auto pt = Point{round(tx), round(ty)};
         outline->pts[i] = TO_SWPOINT(&pt);
     }
index c1212c6..4317aac 100644 (file)
@@ -66,7 +66,6 @@ bool RenderTransform::update()
     //scale
     m.e11 *= factor;
     m.e22 *= factor;
-    m.e33 *= factor;
 
     //rotation
     if (fabsf(degree) > FLT_EPSILON) {
@@ -78,19 +77,19 @@ bool RenderTransform::update()
         auto t12 = m.e11 * -sinVal + m.e12 * cosVal;
         auto t21 = m.e21 * cosVal + m.e22 * sinVal;
         auto t22 = m.e21 * -sinVal + m.e22 * cosVal;
-        auto t31 = m.e31 * cosVal + m.e32 * sinVal;
-        auto t32 = m.e31 * -sinVal + m.e32 * cosVal;
+        auto t13 = m.e13 * cosVal + m.e23 * sinVal;
+        auto t23 = m.e13 * -sinVal + m.e23 * cosVal;
 
         m.e11 = t11;
         m.e12 = t12;
         m.e21 = t21;
         m.e22 = t22;
-        m.e31 = t31;
-        m.e32 = t32;
+        m.e13 = t13;
+        m.e23 = t23;
     }
 
-    m.e31 += x;
-    m.e32 += y;
+    m.e13 += x;
+    m.e23 += y;
 
     return true;
 }
@@ -105,17 +104,17 @@ RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransfo
 {
     assert(lhs && rhs);
 
-    auto dx = rhs->x * lhs->factor;
-    auto dy = rhs->y * lhs->factor;
-    auto tx = dx * lhs->m.e11 + dy * lhs->m.e12 + lhs->m.e13;
-    auto ty = dx * lhs->m.e21 + dy * lhs->m.e22 + lhs->m.e23;
+    m.e11 = lhs->m.e11 * rhs->m.e11 + lhs->m.e12 * rhs->m.e21 + lhs->m.e13 * rhs->m.e31;
+    m.e12 = lhs->m.e11 * rhs->m.e12 + lhs->m.e12 * rhs->m.e22 + lhs->m.e13 * rhs->m.e32;
+    m.e13 = lhs->m.e11 * rhs->m.e13 + lhs->m.e12 * rhs->m.e23 + lhs->m.e13 * rhs->m.e33;
 
-    x = lhs->x + tx;
-    y = lhs->y + ty;
-    degree = lhs->degree + rhs->degree;
-    factor = lhs->factor * rhs->factor;
+    m.e21 = lhs->m.e21 * rhs->m.e11 + lhs->m.e22 * rhs->m.e21 + lhs->m.e23 * rhs->m.e31;
+    m.e22 = lhs->m.e21 * rhs->m.e12 + lhs->m.e22 * rhs->m.e22 + lhs->m.e23 * rhs->m.e32;
+    m.e23 = lhs->m.e21 * rhs->m.e13 + lhs->m.e22 * rhs->m.e23 + lhs->m.e23 * rhs->m.e33;
 
-    update();
+    m.e31 = lhs->m.e31 * rhs->m.e11 + lhs->m.e32 * rhs->m.e21 + lhs->m.e33 * rhs->m.e31;
+    m.e32 = lhs->m.e31 * rhs->m.e12 + lhs->m.e32 * rhs->m.e22 + lhs->m.e33 * rhs->m.e32;
+    m.e33 = lhs->m.e31 * rhs->m.e13 + lhs->m.e32 * rhs->m.e23 + lhs->m.e33 * rhs->m.e33;
 }
 
 #endif //_TVG_RENDER_CPP_
index c651368..53f0093 100644 (file)
 
 #include "tvgSvgSceneBuilder.h"
 
-
-static void _getTransformationData(Matrix* m, float* tx, float* ty, float* s, float* z)
-{
-    float rz, si, cs, zcs, zsi;
-
-    *tx = m->e13;
-    *ty = m->e23;
-
-    cs = m->e11;
-    si = m->e21;
-    rz = atan2(si, cs);
-    *z = rz * (180.0f / M_PI);
-    zcs = cosf(-1.0f * rz);
-    zsi = sinf(-1.0f * rz);
-    m->e11 = m->e11 * zcs + m->e12 * zsi;
-    m->e22 = m->e21 * (-1 * zsi) + m->e22 * zcs;
-    *s = m->e11 > m->e22 ? m->e11 : m->e22;
-}
-
-
 unique_ptr<LinearGradient> _applyLinearGradientProperty(SvgStyleGradient* g, Shape* vg, float rx, float ry, float rw, float rh)
 {
     Fill::ColorStop* stops;
@@ -225,15 +205,7 @@ void _applyProperty(SvgNode* node, Shape* vg, float vx, float vy, float vw, floa
 {
     SvgStyleProperty* style = node->style;
 
-    //Apply the transformation
-    if (node->transform) {
-         float tx = 0, ty = 0, s = 0, z = 0;
-         _getTransformationData(node->transform, &tx, &ty, &s, &z);
-         vg->scale(s);
-         vg->rotate(z);
-         vg->translate(tx, ty);
-    }
-
+    if (node->transform) vg->transform(*node->transform);
     if (node->type == SvgNodeType::Doc) return;
 
     //If fill property is nullptr then do nothing
@@ -359,13 +331,7 @@ unique_ptr<Scene> _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw,
 {
     if (node->type == SvgNodeType::Doc || node->type == SvgNodeType::G) {
         auto scene = Scene::gen();
-        if (node->transform) {
-            float tx = 0, ty = 0, s = 0, z = 0;
-            _getTransformationData(node->transform, &tx, &ty, &s, &z);
-            scene->scale(s);
-            scene->rotate(z);
-            scene->translate(tx, ty);
-        }
+        if (node->transform) scene->transform(*node->transform);
         node->style->opacity = (node->style->opacity * parentOpacity) / 255.0f;
         for (auto child : node->child) {
             child->style->opacity = (child->style->opacity * node->style->opacity) / 255.0f;
diff --git a/test/svgs/duke.svg b/test/svgs/duke.svg
new file mode 100644 (file)
index 0000000..64cdcf8
--- /dev/null
@@ -0,0 +1,25 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75 136">
+<path d="M1190 2982 c-38-31-31-179 17-347 14-49-50 34-89 115-59 126
+-75 138-139 104-89-45-31-286 106-438 37-41 37-56 2-56-64-1-147
+-63-147-111 0-68 36-95 107-78 72 17 110 12 162-18 59-36 99-53 121
+-53 70 0 98-274 36-339-77-80-124-64-211 69-235 363-871 1021-794
+823 6-16 15-109 21-208 8-154 7-237-7-510-1-22-5-71-9-110-3
+-38-8-99-11-135-16-193-59-311-172-463-89-120-103-199-62-333
+46-147 32-217-65-342-86-110-34-240 74-182 15 8 16-2 16-118-1
+-208 99-262 252-137 459 378 583 383 820 37 106-155 165-182 267-123 179
+103 150 755-55 1272-72 180-71 272 6 419 l38 71-1 147 c0 177 4 192 76
+262 82 80 99 158 65 300-25 105-22 166 16 269 47 130 23 186-68 161-65
+-17-142-154-142-253 0-42-37 30-49 96-23 120-43 186-61 202-30 27
+-91 31-120 7z m-342-1094 c74-22 122-90 122-170 0-77-7-87-54-86-83
+2-183-78-173-139 14-82-172-40-237 54-127 183 105 413 342 341z m315
+-214 c237-426 341-786 342-1179 0-460-61-531-239-277-251 358-453
+367-824 35-124-110-190-136-208-80-7 22-7 235 0 272 2 11 7 45 10 75
+4 30 8 66 11 80 2 14 9 52 14 85 109 661 160 849 214 789 199-228 612 2 545
+303-6 28-4 32 15 36 38 7 40 4 120-139z m-900-522 c3-4-5-61-18-127
+-13-66-25-131-27-145-6-36-39 38-46 101-7 76 66 213 91 171z"
+transform="translate(0,136) scale(0.045181,-0.045181)"/>
+<ellipse rx="12" ry="10" transform="rotate(-24) translate(5.4,68.3)"
+fill="#F00" opacity="0.7"/>
+<ellipse rx="3.5" ry="2" transform="rotate(-33) translate(-9,61)" fill="#FFF"
+opacity="0.7"/>
+</svg>
index f95e41e..4803ef1 100644 (file)
@@ -61,19 +61,19 @@ void tvgUpdateCmds(tvg::Canvas* canvas, float progress)
     auto t12 = m.e11 * -sinVal + m.e12 * cosVal;
     auto t21 = m.e21 * cosVal + m.e22 * sinVal;
     auto t22 = m.e21 * -sinVal + m.e22 * cosVal;
-    auto t31 = m.e31 * cosVal + m.e32 * sinVal;
-    auto t32 = m.e31 * -sinVal + m.e32 * cosVal;
+    auto t13 = m.e31 * cosVal + m.e32 * sinVal;
+    auto t23 = m.e31 * -sinVal + m.e32 * cosVal;
 
     m.e11 = t11;
     m.e12 = t12;
     m.e21 = t21;
     m.e22 = t22;
-    m.e31 = t31;
-    m.e32 = t32;
+    m.e13 = t13;
+    m.e23 = t23;
 
     //translate
-    m.e31 = progress * 300.0f + 300.0f;
-    m.e32 = progress * -100.0f + 300.0f;
+    m.e13 = progress * 300.0f + 300.0f;
+    m.e23 = progress * -100.0f + 300.0f;
 
     pShape->transform(m);