evas: add utility function to build path.
authorCedric BAIL <cedric@osg.samsung.com>
Fri, 3 Apr 2015 14:13:00 +0000 (16:13 +0200)
committerCedric BAIL <cedric@osg.samsung.com>
Fri, 3 Apr 2015 14:13:00 +0000 (16:13 +0200)
src/Makefile_Evas.am
src/lib/evas/canvas/evas_vg_utils.c [new file with mode: 0644]

index d2410e3..ba1f525 100644 (file)
@@ -218,7 +218,8 @@ lib/evas/canvas/evas_vg_container.c \
 lib/evas/canvas/evas_vg_root_node.c \
 lib/evas/canvas/evas_vg_gradient.c \
 lib/evas/canvas/evas_vg_gradient_linear.c \
-lib/evas/canvas/evas_vg_gradient_radial.c
+lib/evas/canvas/evas_vg_gradient_radial.c \
+lib/evas/canvas/evas_vg_utils.c
 
 # Engine
 lib_evas_libevas_la_SOURCES += \
diff --git a/src/lib/evas/canvas/evas_vg_utils.c b/src/lib/evas/canvas/evas_vg_utils.c
new file mode 100644 (file)
index 0000000..ec09fe7
--- /dev/null
@@ -0,0 +1,198 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+static unsigned int
+evas_vg_path_command_length(Evas_VG_Path_Command command)
+{
+   switch (command)
+     {
+      case EVAS_VG_PATH_COMMAND_TYPE_END: return 0;
+      case EVAS_VG_PATH_COMMAND_TYPE_MOVE_TO: return 2;
+      case EVAS_VG_PATH_COMMAND_TYPE_LINE_TO: return 2;
+      case EVAS_VG_PATH_COMMAND_TYPE_QUADRATIC_TO: return 4;
+      case EVAS_VG_PATH_COMMAND_TYPE_SQUADRATIC_TO: return 2;
+      case EVAS_VG_PATH_COMMAND_TYPE_CUBIC_TO: return 6;
+      case EVAS_VG_PATH_COMMAND_TYPE_SCUBIC_TO: return 4;
+      case EVAS_VG_PATH_COMMAND_TYPE_ARC_TO: return 5;
+      case EVAS_VG_PATH_COMMAND_TYPE_CLOSE: return 0;
+      case EVAS_VG_PATH_COMMAND_TYPE_LAST: return 0;
+     }
+   return 0;
+}
+
+static inline Eina_Bool
+evas_vg_path_grow(Evas_VG_Path_Command command,
+                  Evas_VG_Path_Command **commands, double **points,
+                  double **offset_point)
+{
+   Evas_VG_Path_Command *cmd_tmp;
+   double *pts_tmp;
+   unsigned int cmd_length = 0, pts_length = 0;
+
+   if (command)
+     {
+        while (commands[cmd_length] != EVAS_VG_PATH_COMMAND_TYPE_END)
+          {
+             pts_length += evas_vg_path_command_length((*commands)[cmd_length]);
+             cmd_length++;
+          }
+     }
+   // Accounting for END command and handle gracefully the NULL case at the same time
+   cmd_length++;
+
+   if (evas_vg_path_command_length(command))
+     {
+        pts_length += evas_vg_path_command_length(command);
+        pts_tmp = realloc(*points, pts_length * sizeof (double));
+        if (!pts_tmp) return EINA_FALSE;
+
+        *points = pts_tmp;
+        *offset_point = *points + pts_length - evas_vg_path_command_length(command);
+     }
+
+   cmd_tmp = realloc(*commands,
+                     (cmd_length + 1) * sizeof (Evas_VG_Path_Command));
+   if (!cmd_tmp) return EINA_FALSE;
+   *commands = cmd_tmp;
+
+   // Append the command
+   cmd_tmp[cmd_length - 1] = command;
+   // NULL terminate the stream
+   cmd_tmp[cmd_length] = EVAS_VG_PATH_COMMAND_TYPE_END;
+
+   return EINA_TRUE;
+}
+
+void
+evas_vg_path_append_move_to(Evas_VG_Path_Command **commands, double **points,
+                            double x, double y)
+{
+   double *offset_point;
+
+   if (!evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_MOVE_TO,
+                          commands, points, &offset_point))
+     return ;
+
+   offset_point[0] = x;
+   offset_point[1] = y;
+}
+
+void
+evas_vg_path_append_line_to(Evas_VG_Path_Command **commands, double **points,
+                            double x, double y)
+{
+   double *offset_point;
+
+   if (!evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_LINE_TO,
+                          commands, points, &offset_point))
+     return ;
+
+   offset_point[0] = x;
+   offset_point[1] = y;
+}
+
+void
+evas_vg_path_append_quadratic_to(Evas_VG_Path_Command **commands, double **points,
+                                 double x, double y, double ctrl_x, double ctrl_y)
+{
+   double *offset_point;
+
+   if (!evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_QUADRATIC_TO,
+                          commands, points, &offset_point))
+     return ;
+
+   offset_point[0] = x;
+   offset_point[1] = y;
+   offset_point[2] = ctrl_x;
+   offset_point[3] = ctrl_y;
+}
+
+void
+evas_vg_path_append_squadratic_to(Evas_VG_Path_Command **commands, double **points,
+                                  double x, double y)
+{
+   double *offset_point;
+
+   if (!evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_SQUADRATIC_TO,
+                          commands, points, &offset_point))
+     return ;
+
+   offset_point[0] = x;
+   offset_point[1] = y;
+}
+
+void
+evas_vg_path_append_cubic_to(Evas_VG_Path_Command **commands, double **points,
+                             double x, double y,
+                             double ctrl_x0, double ctrl_y0,
+                             double ctrl_x1, double ctrl_y1)
+{
+   double *offset_point;
+
+   if (!evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_CUBIC_TO,
+                          commands, points, &offset_point))
+     return ;
+
+   offset_point[0] = x;
+   offset_point[1] = y;
+   offset_point[2] = ctrl_x0;
+   offset_point[3] = ctrl_y0;
+   offset_point[4] = ctrl_x1;
+   offset_point[5] = ctrl_y1;
+}
+
+void
+evas_vg_path_append_scubic_to(Evas_VG_Path_Command **commands, double **points,
+                              double x, double y,
+                              double ctrl_x, double ctrl_y)
+{
+   double *offset_point;
+
+   if (!evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_SCUBIC_TO,
+                          commands, points, &offset_point))
+     return ;
+
+   offset_point[0] = x;
+   offset_point[1] = y;
+   offset_point[2] = ctrl_x;
+   offset_point[3] = ctrl_y;
+}
+
+void
+evas_vg_path_append_arc_to(Evas_VG_Path_Command **commands, double **points,
+                           double x, double y,
+                           double rx, double ry,
+                           double angle)
+{
+   double *offset_point;
+
+   if (!evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_ARC_TO,
+                          commands, points, &offset_point))
+     return ;
+
+   offset_point[0] = x;
+   offset_point[1] = y;
+   offset_point[2] = rx;
+   offset_point[3] = ry;
+   offset_point[4] = angle;
+}
+
+void
+evas_vg_path_append_close(Evas_VG_Path_Command **commands, double **points)
+{
+   double *offset_point;
+
+   evas_vg_path_grow(EVAS_VG_PATH_COMMAND_TYPE_ARC_TO,
+                     commands, points, &offset_point);
+}
+
+void
+evas_vg_path_append_circle(Evas_VG_Path_Command **commands, double **points,
+                           double x, double y, double radius)
+{
+   evas_vg_path_append_move_to(commands, points, x, y - radius);
+   evas_vg_path_append_arc_to(commands, points, x + radius, y, radius, radius, 0);
+   evas_vg_path_append_arc_to(commands, points, x, y + radius, radius, radius, 0);
+   evas_vg_path_append_arc_to(commands, points, x - radius, y, radius, radius, 0);
+   evas_vg_path_append_arc_to(commands, points, x, y - radius, radius, radius, 0);
+}