evas vector: Added thorvg path setter. 80/246980/4
authorMichal Szczecinski <m.szczecinsk@partner.samsung.com>
Wed, 4 Nov 2020 19:57:44 +0000 (20:57 +0100)
committerHermet Park <chuneon.park@samsung.com>
Tue, 10 Nov 2020 10:08:02 +0000 (10:08 +0000)
Implementation of thorvg path setter is needed for
render properly edje vector parts.

Change-Id: Ibcbe4488e5ae46557ce1e5a896db4adbc28fa8e7

src/lib/evas/canvas/efl_canvas_vg_shape.c

index 31795a4..0976a54 100644 (file)
@@ -100,6 +100,18 @@ _get_shape_data(Evas_Vg_Shape *obj)
    return nd->data;
 }
 
+static Tvg_Path_Command
+_get_tvg_command(Evas_Vg_Path_Command cmd)
+{
+   switch(cmd)
+     {
+      case EVAS_VG_PATH_COMMAND_MOVE_TO: return TVG_PATH_COMMAND_MOVE_TO;
+      case EVAS_VG_PATH_COMMAND_LINE_TO: return TVG_PATH_COMMAND_LINE_TO;
+      case EVAS_VG_PATH_COMMAND_CUBIC_TO: return TVG_PATH_COMMAND_CUBIC_TO;
+      default: return TVG_PATH_COMMAND_CLOSE;
+     }
+}
+
 static Evas_Vg_Path_Command
 _get_evas_command(Tvg_Path_Command cmd)
 {
@@ -113,6 +125,40 @@ _get_evas_command(Tvg_Path_Command cmd)
      }
 }
 
+static inline unsigned int
+_get_command_length(Evas_Vg_Path_Command command)
+{
+   switch (command)
+     {
+      case EVAS_VG_PATH_COMMAND_END: return 0;
+      case EVAS_VG_PATH_COMMAND_MOVE_TO: return 2;
+      case EVAS_VG_PATH_COMMAND_LINE_TO: return 2;
+      case EVAS_VG_PATH_COMMAND_CUBIC_TO: return 6;
+      case EVAS_VG_PATH_COMMAND_CLOSE: return 0;
+      case EVAS_VG_PATH_COMMAND_LAST: return 0;
+     }
+   return 0;
+}
+
+static inline void
+_get_path_length(const Evas_Vg_Path_Command *commands,
+                 unsigned int *cmd_length,
+                 unsigned int *pts_length)
+{
+   if (commands)
+     {
+        while (commands[*cmd_length] != EFL_GFX_PATH_COMMAND_TYPE_END)
+          {
+             *pts_length += _get_command_length(commands[*cmd_length]);
+             (*cmd_length)++;
+          }
+     }
+
+   /* Accounting for END command and handle gracefully the NULL case
+      at the same time */
+   (*cmd_length)++;
+}
+
 static void
 _assign_current_point(Efl_Canvas_Vg_Shape_Data *sd, void *cmd EINA_UNUSED, double x, double y)
 {
@@ -1066,8 +1112,43 @@ evas_vg_shape_stroke_join_set(Evas_Vg_Shape *obj, Evas_Vg_Join j)
 EAPI void
 evas_vg_shape_path_set(Evas_Vg_Shape *obj, const Evas_Vg_Path_Command *op, const double *points)
 {
-   //TODO: implement
+   if (!op || !points) return;
+
+#ifdef HAVE_THORVG
+   unsigned int cmd_length = 0;
+   unsigned int pts_length = 0;
+   unsigned int i = 0, k = 0;
+
+   Tvg_Path_Command *commands = NULL;
+   Tvg_Point *pts = NULL;
+
+   _get_path_length(op, &cmd_length, &pts_length);
+
+   commands = malloc(sizeof(Tvg_Path_Command) * (cmd_length - 1));
+   if (!commands) return;
+
+   pts = malloc(sizeof(Tvg_Point) * pts_length / 2);
+   if (!pts) return;
+
+   k = 0;
+
+   for (i = 0; i < pts_length; i += 2)
+     {
+        pts[k].x = points[i];
+        pts[k].y = points[i + 1];
+        k++;
+     }
+
+   i = 0;
+   for (i = 0; i < cmd_length - 1; ++i)
+     {
+        commands[i] = _get_tvg_command(op[i]);
+     }
+
+   tvg_shape_append_path(_get_tvg_shape(obj), commands, cmd_length - 1, pts, pts_length / 2);
+#else
    efl_gfx_path_set(obj, (const Efl_Gfx_Path_Command *)op, points);
+#endif
    efl_canvas_vg_node_change(obj);
 }