evas: proper image scaling 91/268691/3 accepted/tizen/unified/20220526.143700 submit/tizen/20220525.023233
authormgrudzinska <m.grudzinska@samsung.com>
Wed, 29 Dec 2021 23:59:30 +0000 (00:59 +0100)
committerChun <jykeon@samsung.com>
Wed, 25 May 2022 02:05:07 +0000 (02:05 +0000)
In the case an image is cached, the scaling should depend
on the SVG's preserveAspectRatio attribute. If the tvg loader
is used, this value is known only inside TVG, so the transformation
matrix established in EFL can not be applied and the scaling has to
be done in TVG.

Change-Id: I620fcb29d262bad278274815bd8a22dea1d587c8

src/lib/evas/canvas/efl_canvas_vg_container.c
src/lib/evas/canvas/efl_canvas_vg_image.c
src/lib/evas/canvas/efl_canvas_vg_node.c
src/lib/evas/canvas/efl_canvas_vg_node.eo
src/lib/evas/canvas/evas_vg_private.h
src/lib/evas/vg/evas_vg_cache.c

index 39acadc..5dcc27a 100644 (file)
@@ -44,6 +44,13 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *obj,
 
    EFL_CANVAS_VG_COMPUTE_MATRIX(cTransform, pTransform, nd);
 
+   // TIZEN_ONLY(20220330): evas: proper image scaling
+   if (nd->m_geometric)
+     {
+        if (cTransform) eina_matrix3_compose(nd->m_geometric, cTransform, cTransform);
+        else cTransform = nd->m_geometric;
+     }
+
    EINA_LIST_FOREACH(cd->children, l, child)
      {
         Efl_Canvas_Vg_Node_Data *cnd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
index e37a93b..2b10039 100644 (file)
@@ -40,6 +40,8 @@ _efl_canvas_vg_image_render_pre(EINA_UNUSED Evas_Object_Protected_Data *vg_pd,
              trans_mat.e23 += nd->y;
              tvg_paint_set_transform(pd->picture, &trans_mat);
           }
+        // TIZEN_ONLY(20220330): evas: proper image scaling
+        if (nd->w_geometric > 0 || nd->h_geometric > 0) tvg_picture_set_size(pd->picture, nd->w_geometric, nd->h_geometric);
 
         efl_gfx_color_get(obj, NULL, NULL, NULL, &alpha);
         EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, alpha, nd);
index 8ed14f2..91a87a7 100644 (file)
@@ -42,6 +42,45 @@ _node_change(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd)
    efl_canvas_vg_object_change(nd->vd);
 }
 
+// TIZEN_ONLY(20220330): evas: proper image scaling
+static void
+_efl_canvas_vg_node_geometric_data_set(Eo *obj,
+                                       Efl_Canvas_Vg_Node_Data *pd,
+                                       const Eina_Matrix3 *m,
+                                       double w,
+                                       double h)
+{
+   if (pd->intp)
+     {
+        free(pd->intp);
+        pd->intp = NULL;
+     }
+
+   if (m)
+     {
+        if (!pd->m_geometric)
+          {
+             pd->m_geometric = malloc(sizeof (Eina_Matrix3));
+             if (!pd->m_geometric) return;
+          }
+        memcpy(pd->m_geometric, m, sizeof (Eina_Matrix3));
+     }
+   else
+     {
+        free(pd->m_geometric);
+        pd->m_geometric = NULL;
+     }
+
+   pd->w_geometric = w;
+   pd->h_geometric = h;
+
+   /* NOTE: _node_change function is only executed
+            when pd->flags is EFL_GFX_CHANGE_FLAG_NONE to prevent duplicate calls.*/
+   _node_change(obj, pd);
+   pd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
+}
+
+
 static void
 _efl_canvas_vg_node_transformation_set(Eo *obj,
                                        Efl_Canvas_Vg_Node_Data *pd,
@@ -278,6 +317,12 @@ _efl_canvas_vg_node_efl_object_destructor(Eo *obj, Efl_Canvas_Vg_Node_Data *pd)
         free(pd->m);
         pd->m = NULL;
      }
+   // TIZEN_ONLY(20220330): evas: proper image scaling
+   if (pd->m_geometric)
+     {
+        free(pd->m_geometric);
+        pd->m_geometric = NULL;
+     }
    if (pd->intp)
      {
         free(pd->intp);
@@ -690,7 +735,15 @@ _efl_canvas_vg_node_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Node_Da
         nd->m = malloc(sizeof(Eina_Matrix3));
         if (nd->m) memcpy(nd->m, pd->m, sizeof(Eina_Matrix3));
      }
+   // TIZEN_ONLY(20220330): evas: proper image scaling
+   if (pd->m_geometric)
+     {
+        nd->m_geometric = malloc(sizeof(Eina_Matrix3));
+        if (nd->m_geometric) memcpy(nd->m_geometric, pd->m_geometric, sizeof(Eina_Matrix3));
+     }
 
+   nd->w_geometric = pd->w_geometric;
+   nd->h_geometric = pd->h_geometric;
    nd->x = pd->x;
    nd->y = pd->y;
    nd->r = pd->r;
index 69d3648..5b488d4 100644 (file)
@@ -5,6 +5,20 @@ abstract @beta Efl.Canvas.Vg.Node extends Efl.Object
 {
    [[Efl vector graphics abstract class]]
    methods {
+      // TIZEN_ONLY(20220330): evas: proper image scaling
+      @property geometric_data {
+         [[The transformation matrix, the width and the height of the node object in case it was cached.
+
+           Note: Pass $null to cancel the applied transformation matrix.
+         ]]
+         set {
+         }
+         values {
+            m: ptr(const(Eina.Matrix3)); [[Transformation matrix.]]
+            w: double; [[Width of the node object.]]
+            h: double; [[Height of the node object.]]
+         }
+      }
       @property transformation {
          [[The transformation matrix to be used for this node object.
 
index fa5839b..c94bd8a 100644 (file)
@@ -79,6 +79,10 @@ struct _Efl_Canvas_Vg_Node_Data
    int r, g, b, a;
    Efl_Gfx_Change_Flag flags;
 
+   // TIZEN_ONLY(20220330): evas: proper image scaling
+   double w_geometric, h_geometric;
+   Eina_Matrix3 *m_geometric;
+
    Eina_Bool visibility : 1;
 };
 
index d7e1c4b..97812bc 100644 (file)
@@ -253,7 +253,8 @@ _local_transform(Efl_VG *root, double w, double h, Vg_File_Data *vfd)
         eina_matrix3_scale(&m, sx, sy);
         eina_matrix3_translate(&m, -vfd->view_box.x, -vfd->view_box.y);
      }
-   efl_canvas_vg_node_transformation_set(root, &m);
+   // TIZEN_ONLY(20220330): evas: proper image scaling
+   efl_canvas_vg_node_geometric_data_set(root, &m, w, h);
 }
 
 void