Revert "Revert "efl/interface: refactored svg_path() api as well as added arc animation"" 00/91400/1
authorShinwoo Kim <cinoo.kim@samsung.com>
Fri, 7 Oct 2016 08:31:59 +0000 (17:31 +0900)
committerShinwoo Kim <cinoo.kim@samsung.com>
Fri, 7 Oct 2016 08:32:19 +0000 (17:32 +0900)
This reverts commit 7b1f471fe87455e9f9b673aee9e82cb0edadeb89.

Change-Id: I34a121ad2bf346c5fd90b60aaa7beda5d022fee6

src/lib/efl/interfaces/efl_gfx_shape.c

index 7ffcda5..a5b7097 100644 (file)
@@ -28,6 +28,7 @@ struct _Efl_Gfx_Shape_Data
 
    unsigned int commands_count;
    unsigned int points_count;
+   char *path_data;
    Eina_Bool convex;
 };
 
@@ -315,6 +316,9 @@ _efl_gfx_property_get(const Eo *obj, Efl_Gfx_Property *property)
          property->j = efl_gfx_shape_stroke_join_get());
 }
 
+static void _path_interpolation(Eo *obj, Efl_Gfx_Shape_Data *pd, char *from, char *to, double pos);
+static void _efl_gfx_shape_reset(Eo *obj, Efl_Gfx_Shape_Data *pd);
+
 static Eina_Bool
 _efl_gfx_shape_interpolate(Eo *obj, Efl_Gfx_Shape_Data *pd,
                            const Eo *from, const Eo *to, double pos_map)
@@ -331,61 +335,70 @@ _efl_gfx_shape_interpolate(Eo *obj, Efl_Gfx_Shape_Data *pd,
    if (!eo_isa(from, EFL_GFX_SHAPE_MIXIN) ||
        !eo_isa(to, EFL_GFX_SHAPE_MIXIN)) return EINA_FALSE;
    if (pd == from_pd || pd == to_pd) return EINA_FALSE;
-   if (!_efl_gfx_shape_equal_commands_internal(from_pd, to_pd))
-     return EINA_FALSE;
+
 
    _efl_gfx_property_get(from, &property_from);
    _efl_gfx_property_get(to, &property_to);
 
    if (property_from.dash_length != property_to.dash_length) return EINA_FALSE;
 
-   cmds = realloc(pd->commands,
-                  sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
-   if (!cmds && from_pd->commands_count) return EINA_FALSE;
-   pd->commands = cmds;
-
-   pts = realloc(pd->points,
-                 sizeof (double) * from_pd->points_count);
-   if (!pts && from_pd->points_count) return EINA_FALSE;
-   pd->points = pts;
-
-   if (cmds)
+   if (from_pd->path_data && to_pd->path_data)
      {
-        memcpy(cmds, from_pd->commands,
-               sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
-
-        if (pts)
+        _efl_gfx_shape_reset(obj, pd);
+        _path_interpolation(obj, pd, from_pd->path_data, to_pd->path_data, pos_map);
+     }
+   else
+     {
+        if (!_efl_gfx_shape_equal_commands_internal(from_pd, to_pd))
+          return EINA_FALSE;
+        cmds = realloc(pd->commands,
+                       sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
+        if (!cmds && from_pd->commands_count) return EINA_FALSE;
+        pd->commands = cmds;
+
+        pts = realloc(pd->points,
+                      sizeof (double) * from_pd->points_count);
+        if (!pts && from_pd->points_count) return EINA_FALSE;
+        pd->points = pts;
+
+        if (cmds)
           {
-             double *to_pts = to_pd->points;
-             double *from_pts = from_pd->points;
-
-             for (i = 0; cmds[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
-               for (j = 0; j < _efl_gfx_path_command_length(cmds[i]); j++)
-                 {
-                    *pts = interpolate(*from_pts, *to_pts, pos_map);
-
-                    pts++;
-                    from_pts++;
-                    to_pts++;
-                 }
+             memcpy(cmds, from_pd->commands,
+                    sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
+
+             if (pts)
+               {
+                  double *to_pts = to_pd->points;
+                  double *from_pts = from_pd->points;
+
+                  for (i = 0; cmds[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
+                    for (j = 0; j < _efl_gfx_path_command_length(cmds[i]); j++)
+                      {
+                         *pts = interpolate(*from_pts, *to_pts, pos_map);
+
+                         pts++;
+                         from_pts++;
+                         to_pts++;
+                      }
+               }
           }
-     }
 
-   pd->points_count = from_pd->points_count;
-   pd->commands_count = from_pd->commands_count;
-
-   pd->current.x = interpolate(from_pd->current.x,
-                               to_pd->current.x,
-                               pos_map);
-   pd->current.y = interpolate(from_pd->current.y,
-                               to_pd->current.y,
-                               pos_map);
-   pd->current_ctrl.x = interpolate(from_pd->current_ctrl.x,
-                                    to_pd->current_ctrl.x,
+        pd->points_count = from_pd->points_count;
+        pd->commands_count = from_pd->commands_count;
+
+        pd->current.x = interpolate(from_pd->current.x,
+                                    to_pd->current.x,
                                     pos_map);
-   pd->current_ctrl.y = interpolate(from_pd->current_ctrl.y,
-                                    to_pd->current_ctrl.y,
+        pd->current.y = interpolate(from_pd->current.y,
+                                    to_pd->current.y,
                                     pos_map);
+        pd->current_ctrl.x = interpolate(from_pd->current_ctrl.x,
+                                         to_pd->current_ctrl.x,
+                                         pos_map);
+        pd->current_ctrl.y = interpolate(from_pd->current_ctrl.y,
+                                         to_pd->current_ctrl.y,
+                                         pos_map);
+   }
 
    if (property_to.dash_length)
      {
@@ -447,6 +460,8 @@ _efl_gfx_shape_reset(Eo *obj, Efl_Gfx_Shape_Data *pd)
    free(pd->points);
    pd->points = NULL;
    pd->points_count = 0;
+   free(pd->path_data);
+   pd->path_data = NULL;
 
    pd->current.x = 0;
    pd->current.y = 0;
@@ -1182,15 +1197,6 @@ _skipcomma(const char *content)
 }
 
 static inline Eina_Bool
-_next_isnumber(const char *content)
-{
-   char *tmp = NULL;
-
-   (void) strtod(content, &tmp);
-   return content != tmp;
-}
-
-static inline Eina_Bool
 _parse_number(char **content, double *number)
 {
    char *end = NULL;
@@ -1202,286 +1208,319 @@ _parse_number(char **content, double *number)
    return EINA_TRUE;
 }
 
-static Eina_Bool
-_efl_gfx_path_parse_pair(const char *content, char **end, double *x, double *y)
+static inline Eina_Bool
+_parse_long(char **content, int *number)
 {
-   char *str = (char *) content;
-
-   if (_parse_number(&str, x))
-     if (_parse_number(&str, y))
-       {
-          *end = str;
-          return EINA_TRUE;
-       }
-   return EINA_FALSE;
+   char *end = NULL;
+   *number = strtol(*content, &end, 10) ? 1 : 0;
+   // if the start of string is not number 
+   if ((*content) == end) return EINA_FALSE;
+   *content = _skipcomma(end);
+   return EINA_TRUE;
 }
 
-static Eina_Bool
-_efl_gfx_path_parse_pair_to(const char *content, char **end,
-                            Eo *obj, Efl_Gfx_Shape_Data *pd,
-                            double *current_x, double *current_y,
-                            void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd, double x, double y),
-                            Eina_Bool rel)
-{
-   double x, y;
 
-   *end = (char*) content;
-   do
+static int
+_number_count(char cmd)
+{
+   int count = 0;
+   switch (cmd)
      {
-        Eina_Bool r;
-
-        r = _efl_gfx_path_parse_pair(content, end, &x, &y);
-        if (!r) return EINA_FALSE;
-
-        if (rel)
-          {
-             x += *current_x;
-             y += *current_y;
-          }
-        func(obj, pd, x, y);
-        content = *end;
-
-        *current_x = x;
-        *current_y = y;
-     }
-   while (_next_isnumber(content));
-
-   return EINA_TRUE;
+      case 'M':
+      case 'm':
+      case 'L':
+      case 'l':
+        {
+           count = 2;
+           break;
+        }
+      case 'C':
+      case 'c':
+      case 'E':
+      case 'e':
+        {
+           count = 6;
+           break;
+        }
+      case 'H':
+      case 'h':
+      case 'V':
+      case 'v':
+        {
+           count = 1;
+           break;
+        }
+      case 'S':
+      case 's':
+      case 'Q':
+      case 'q':
+      case 'T':
+      case 't':
+        {
+           count = 4;
+           break;
+        }
+      case 'A':
+      case 'a':
+        {
+           count = 7;
+           break;
+        }
+      default:
+         break;
+      }
+   return count;
+}
+
+static void 
+process_command(Eo *obj, Efl_Gfx_Shape_Data *pd, char cmd, double *arr, int count, double *cur_x, double *cur_y)
+{
+   int i;
+   switch (cmd)
+     {
+      case 'm':
+      case 'l':
+      case 'c':
+      case 's':
+      case 'q':
+      case 't':
+        {
+           for(i=0; i<count; i += 2)
+             {
+                arr[i] = arr[i] + *cur_x;
+                arr[i+1] = arr[i+1] + *cur_y;
+             }
+           break;
+        }
+      case 'h':
+        {
+           arr[0] = arr[0] + *cur_x;
+           break;
+        }
+      case 'v':
+        {
+           arr[0] = arr[0] + *cur_y;
+           break;
+        }
+      case 'a':
+        {
+           arr[5] = arr[5] + *cur_x;
+           arr[6] = arr[6] + *cur_y;
+           break;
+        }
+      default:
+         break;
+      }
+
+   switch (cmd)
+     {
+      case 'm':
+      case 'M':
+        {
+           _efl_gfx_shape_append_move_to(obj, pd, arr[0], arr[1]);
+           *cur_x = arr[0];
+           *cur_y = arr[1];
+           break;
+        }
+      case 'l':
+      case 'L':
+        {
+           _efl_gfx_shape_append_line_to(obj, pd, arr[0], arr[1]);
+           *cur_x = arr[0];
+           *cur_y = arr[1];
+           break;
+        }
+      case 'c':
+      case 'C':
+        {
+           _efl_gfx_shape_append_cubic_to(obj, pd, arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]);
+           *cur_x = arr[4];
+           *cur_y = arr[5];
+           break;
+        }
+      case 's':
+      case 'S':
+        {
+           _efl_gfx_shape_append_scubic_to(obj, pd, arr[2], arr[3], arr[0], arr[1]);
+           *cur_x = arr[2];
+           *cur_y = arr[3];
+           break;
+        }
+      case 'q':
+      case 'Q':
+        {
+           _efl_gfx_shape_append_quadratic_to(obj, pd, arr[2], arr[3], arr[0], arr[1]);
+           *cur_x = arr[2];
+           *cur_y = arr[3];
+           break;
+        }
+      case 't':
+      case 'T':
+        {
+           _efl_gfx_shape_append_move_to(obj, pd, arr[0], arr[1]);
+           *cur_x = arr[0];
+           *cur_y = arr[1];
+           break;
+        }
+      case 'h':
+      case 'H':
+        {
+           _efl_gfx_path_append_horizontal_to(obj, pd, arr[0], *cur_x, *cur_y);
+           *cur_x = arr[0];
+           break;
+        }
+      case 'v':
+      case 'V':
+        {
+           _efl_gfx_path_append_vertical_to(obj, pd, arr[0], *cur_x, *cur_y);
+           *cur_y = arr[0];
+           break;
+        }
+      case 'z':
+      case 'Z':
+        {
+           _efl_gfx_shape_append_close(obj, pd);
+           break;
+        }
+      case 'a':
+      case 'A':
+        {
+           _efl_gfx_shape_append_arc_to(obj, pd, arr[5], arr[6], arr[0], arr[1], arr[2], arr[3], arr[4]);
+           *cur_x = arr[5];
+           *cur_y = arr[6];
+           break;
+        }
+      case 'E':
+      case 'e':
+        {
+           _efl_gfx_shape_append_arc(obj, pd, arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]);
+           break;
+        }
+      default:
+         break;
+      }
 }
-
-static Eina_Bool
-_efl_gfx_path_parse_double_to(const char *content, char **end,
-                              Eo *obj, Efl_Gfx_Shape_Data *pd,
-                              double *current, double current_x, double current_y,
-                              void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd, double d, double current_x, double current_y),
-                              Eina_Bool rel)
+static char *
+_next_command(char *path, char *cmd, double *arr, int *count)
 {
-   double d;
-   Eina_Bool first = EINA_FALSE;
+   int i=0, large, sweep;
 
-   *end = (char*) content;
-   do
+   path = _skipcomma(path);
+   if (isalpha(*path))
      {
-        d = strtod(content, end);
-        if (content == *end)
-          return first;
-        first = EINA_TRUE;
-
-        if (rel)
-          {
-             d += *current;
-          }
-
-        func(obj, pd, d, current_x, current_y);
-        content = *end;
-
-        *current = d;
+        *cmd = *path;
+        path++;
+        *count = _number_count(*cmd);
      }
-   while (1); // This is an optimisation as we have only one parameter.
-
-   return EINA_TRUE;
-}
-
-static Eina_Bool
-_efl_gfx_path_parse_six(const char *content, char **end,
-                        double *x, double *y,
-                        double *ctrl_x0, double *ctrl_y0,
-                        double *ctrl_x1, double *ctrl_y1)
-{
-   char *str = (char *) content;
-   if (_parse_number(&str, ctrl_x0))
-     if (_parse_number(&str, ctrl_y0))
-       if (_parse_number(&str, ctrl_x1))
-         if (_parse_number(&str, ctrl_y1))
-           if (_parse_number(&str, x))
-             if (_parse_number(&str, y))
-               {
-                  *end = str;
-                  return EINA_TRUE;
-               }
-   return EINA_FALSE;
-}
-
-static Eina_Bool
-_efl_gfx_path_parse_six_to(const char *content, char **end,
-                           Eo *obj, Efl_Gfx_Shape_Data *pd,
-                           double *current_x, double *current_y,
-                           void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd, double ctrl_x0, double ctrl_y0, double ctrl_x1, double ctrl_y1, double x, double y),
-                           Eina_Bool rel)
-{
-   double x, y, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1;
-
-   *end = (char*) content;
-   do
+   if ( *count == 7)
      {
-        Eina_Bool r;
-
-        r = _efl_gfx_path_parse_six(content, end,
-                                    &x, &y,
-                                    &ctrl_x0, &ctrl_y0,
-                                    &ctrl_x1, &ctrl_y1);
-        if (!r) return EINA_FALSE;
-
-        if (rel)
-          {
-             x += *current_x;
-             y += *current_y;
-             ctrl_x0 += *current_x;
-             ctrl_y0 += *current_y;
-             ctrl_x1 += *current_x;
-             ctrl_y1 += *current_y;
-          }
-        func(obj, pd, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1, x, y);
-        content = *end;
-
-        *current_x = x;
-        *current_y = y;
+        // special case for arc command
+        if(_parse_number(&path, &arr[0]))
+          if(_parse_number(&path, &arr[1]))
+            if(_parse_number(&path, &arr[2]))
+               if(_parse_long(&path, &large))
+                  if(_parse_long(&path, &sweep))
+                     if(_parse_number(&path, &arr[5]))
+                        if(_parse_number(&path, &arr[6]))
+                          {
+                             arr[3] = large;
+                             arr[4] = sweep;
+                             return path;
+                          }
+         *count = 0;
+         return NULL;
      }
-   while (_next_isnumber(content));
-
-   return EINA_TRUE;
-}
-
-static Eina_Bool
-_efl_gfx_path_parse_quad(const char *content, char **end,
-                         double *x, double *y,
-                         double *ctrl_x0, double *ctrl_y0)
-{
-   char *str = (char *) content;
-
-   if (_parse_number(&str, ctrl_x0))
-     if (_parse_number(&str, ctrl_y0))
-       if (_parse_number(&str, x))
-         if (_parse_number(&str, y))
-           {
-              *end = str;
-              return EINA_TRUE;
-           }
-   return EINA_FALSE;
-}
-
-static Eina_Bool
-_efl_gfx_path_parse_quad_to(const char *content, char **end,
-                            Eo *obj, Efl_Gfx_Shape_Data *pd,
-                            double *current_x, double *current_y,
-                            void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd,
-                                         double x, double y, double ctrl_x0, double ctrl_y0),
-                            Eina_Bool rel)
-{
-   double x, y, ctrl_x0, ctrl_y0;
-
-   *end = (char*) content;
-   do
+   for (i = 0; i < *count; i++)
      {
-        Eina_Bool r;
-
-        r = _efl_gfx_path_parse_quad(content, end,
-                                     &x, &y,
-                                     &ctrl_x0, &ctrl_y0);
-        if (!r) return EINA_FALSE;
-
-        if (rel)
+        if (!_parse_number(&path, &arr[i]))
           {
-             x += *current_x;
-             y += *current_y;
-             ctrl_x0 += *current_x;
-             ctrl_y0 += *current_y;
+             *count = 0;
+             return NULL;
           }
-        func(obj, pd, x, y, ctrl_x0, ctrl_y0);
-        content = *end;
-
-        *current_x = x;
-        *current_y = y;
+        path = _skipcomma(path);
      }
-   while (_next_isnumber(content));
-
-   return EINA_TRUE;
+   return path;
 }
 
-static Eina_Bool
-_efl_gfx_path_parse_arc(const char *content, char **end,
-                        double *x, double *y,
-                        double *rx, double *ry,
-                        double *radius,
-                        Eina_Bool *large_arc, Eina_Bool *sweep)
-{
-   char *str = (char *) content;
-   char *end1 = NULL;
-   char *end2 = NULL;
-
-   if (_parse_number(&str, rx))
-     if (_parse_number(&str, ry))
-       if (_parse_number(&str, radius))
-         {
-            // large_arc
-            *large_arc = strtol(str, &end1, 10) ? EINA_TRUE : EINA_FALSE;
-            if (!end1 || (str == end1)) return EINA_FALSE;
-            end1 = _skipcomma(end1);
-
-            // sweeo
-            *sweep = strtol(end1, &end2, 10) ? EINA_TRUE : EINA_FALSE;
-            if (!end2 || (end1 == end2)) return EINA_FALSE;
-            str = _skipcomma(end2);
-
-            if (_parse_number(&str, x))
-              if (_parse_number(&str, y))
-                {
-                   *end = str;
-                   return EINA_TRUE;
-                }
-         }
-   return EINA_FALSE;
-}
-
-static Eina_Bool
-_efl_gfx_path_parse_arc_to(const char *content, char **end,
-                           Eo *obj, Efl_Gfx_Shape_Data *pd,
-                           double *current_x, double *current_y,
-                           void (*func)(Eo *obj, Efl_Gfx_Shape_Data *pd,
-                                        double x, double y, double rx, double ry, double angle,
-                                        Eina_Bool large_arc, Eina_Bool sweep),
-                           Eina_Bool rel)
-{
-   double x, y, rx, ry, angle;
-   Eina_Bool large_arc, sweep; // FIXME: handle those flag
+static void
+_path_interpolation(Eo *obj, Efl_Gfx_Shape_Data *pd,
+                     char *from, char *to, double pos)
+{
+   int i;
+   double from_arr[7], to_arr[7];
+   int from_count=0, to_count=0;
+   double cur_x=0, cur_y=0;
+   char from_cmd= 0, to_cmd = 0;
+   char *cur_locale;
 
-   *end = (char*) content;
-   do
-     {
-        Eina_Bool r;
+   if (!from || !to)
+     return;
 
-        r = _efl_gfx_path_parse_arc(content, end,
-                                    &x, &y,
-                                    &rx, &ry,
-                                    &angle,
-                                    &large_arc, &sweep);
-        if (!r) return EINA_FALSE;
+// TIZEN_ONLY(20160420): efl/interface: update locale before parsing svg path
+   cur_locale = setlocale(LC_NUMERIC, NULL);
+   if (cur_locale)
+     cur_locale = strdup(cur_locale);
+   setlocale(LC_NUMERIC, "POSIX");
+//
 
-        if (rel)
+   while ((from[0] != '\0') && (to[0] != '\0'))
+     {
+        from = _next_command(from, &from_cmd, from_arr, &from_count);
+        to = _next_command(to, &to_cmd, to_arr, &to_count);
+        if (from_cmd == to_cmd)
           {
-             x += *current_x;
-             y += *current_y;
+             if (from_count == 7)
+               {
+                  //special case for arc command
+                  i=0;
+                  from_arr[i] = interpolate(from_arr[i], to_arr[i], pos);
+                  i=1;
+                  from_arr[i] = interpolate(from_arr[i], to_arr[i], pos);
+                  i=2;
+                  from_arr[i] = interpolate(from_arr[i], to_arr[i], pos);
+                  i=5;
+                  from_arr[i] = interpolate(from_arr[i], to_arr[i], pos);
+                  i=6;
+                  from_arr[i] = interpolate(from_arr[i], to_arr[i], pos);
+               }
+             else
+               {
+                  for(i=0; i < from_count; i++)
+                    {
+                       from_arr[i] = interpolate(from_arr[i], to_arr[i], pos);
+                    }
+               }
+            process_command(obj, pd, from_cmd, from_arr, from_count, &cur_x, &cur_y);
+          }
+        else
+          {
+             //printf("Error path dosen't match\n");
+             goto error;
           }
-
-        func(obj, pd, x, y, rx, ry, angle, large_arc, sweep);
-        content = *end;
-
-        *current_x = x;
-        *current_y = y;
      }
-   while (_next_isnumber(content));
 
-   return EINA_TRUE;
+// TIZEN_ONLY(20160420): efl/interface: update locale before parsing svg path
+error:
+   setlocale(LC_NUMERIC, cur_locale);
+   if (cur_locale)
+     free(cur_locale);
+//
 }
 
 static void
 _efl_gfx_shape_append_svg_path(Eo *obj, Efl_Gfx_Shape_Data *pd,
                                const char *svg_path_data)
 {
-   double current_x = 0, current_y = 0;
-   char *content = (char*) svg_path_data;
+   double number_array[7];
+   int number_count = 0;
+   double cur_x=0, cur_y=0;
+   char cmd= 0;
+   char *path = (char *) svg_path_data;
+   Eina_Bool arc = EINA_FALSE;
    char *cur_locale;
-   if (!content) return ;
+
+   if (!path)
+     return;
 
 // TIZEN_ONLY(20160420): efl/interface: update locale before parsing svg path
    cur_locale = setlocale(LC_NUMERIC, NULL);
@@ -1490,183 +1529,28 @@ _efl_gfx_shape_append_svg_path(Eo *obj, Efl_Gfx_Shape_Data *pd,
    setlocale(LC_NUMERIC, "POSIX");
 //
 
-   while (content[0] != '\0')
+   while ((path[0] != '\0'))
      {
-        while (isspace(content[0])) content++;
-
-        switch (content[0])
+        path = _next_command(path, &cmd, number_array, &number_count);
+        if (!path)
           {
-           case 'M':
-              if (!_efl_gfx_path_parse_pair_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_move_to,
-                                               EINA_FALSE))
-                goto error;
-              break;
-           case 'm':
-              if (!_efl_gfx_path_parse_pair_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_move_to,
-                                               EINA_TRUE))
-                goto error;
-              break;
-           case 'z':
-           case 'Z':
-              _efl_gfx_shape_append_close(obj, pd);
-              content++;
-              break;
-           case 'L':
-              if (!_efl_gfx_path_parse_pair_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_line_to,
-                                               EINA_FALSE))
-                goto error;
-              break;
-           case 'l':
-              if (!_efl_gfx_path_parse_pair_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_line_to,
-                                               EINA_TRUE))
-                goto error;
-              break;
-           case 'H':
-              if (!_efl_gfx_path_parse_double_to(&content[1],
-                                                 &content,
-                                                 obj, pd,
-                                                 &current_x, current_x, current_y,
-                                                 _efl_gfx_path_append_horizontal_to,
-                                                 EINA_FALSE))
-                goto error;
-              break;
-           case 'h':
-              if (!_efl_gfx_path_parse_double_to(&content[1],
-                                                 &content,
-                                                 obj, pd,
-                                                 &current_x, current_x, current_y,
-                                                 _efl_gfx_path_append_horizontal_to,
-                                                 EINA_TRUE))
-                goto error;
-              break;
-           case 'V':
-              if (!_efl_gfx_path_parse_double_to(&content[1],
-                                                 &content,
-                                                 obj, pd,
-                                                 &current_y, current_x, current_y,
-                                                 _efl_gfx_path_append_vertical_to,
-                                                 EINA_FALSE))
-                goto error;
-              break;
-           case 'v':
-              if (!_efl_gfx_path_parse_double_to(&content[1],
-                                                 &content,
-                                                 obj, pd,
-                                                 &current_y, current_x, current_y,
-                                                 _efl_gfx_path_append_vertical_to,
-                                                 EINA_TRUE))
-                goto error;
-              break;
-           case 'C':
-              if (!_efl_gfx_path_parse_six_to(&content[1],
-                                              &content,
-                                              obj, pd,
-                                              &current_x, &current_y,
-                                              _efl_gfx_shape_append_cubic_to,
-                                              EINA_FALSE))
-                goto error;
-              break;
-           case 'c':
-              if (!_efl_gfx_path_parse_six_to(&content[1],
-                                              &content,
-                                              obj, pd,
-                                              &current_x, &current_y,
-                                              _efl_gfx_shape_append_cubic_to,
-                                              EINA_TRUE))
-                goto error;
-              break;
-           case 'S':
-              if (!_efl_gfx_path_parse_quad_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_scubic_to,
-                                               EINA_FALSE))
-                goto error;
-              break;
-           case 's':
-              if (!_efl_gfx_path_parse_quad_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_scubic_to,
-                                               EINA_TRUE))
-                goto error;
-              break;
-           case 'Q':
-              if (!_efl_gfx_path_parse_quad_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_quadratic_to,
-                                               EINA_FALSE))
-                goto error;
-              break;
-           case 'q':
-              if (!_efl_gfx_path_parse_quad_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_quadratic_to,
-                                               EINA_TRUE))
-                goto error;
-              break;
-           case 'T':
-              if (!_efl_gfx_path_parse_pair_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_squadratic_to,
-                                               EINA_FALSE))
-                goto error;
-              break;
-           case 't':
-              if (!_efl_gfx_path_parse_pair_to(&content[1],
-                                               &content,
-                                               obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_shape_append_squadratic_to,
-                                               EINA_TRUE))
-                goto error;
-              break;
-           case 'A':
-              if (!_efl_gfx_path_parse_arc_to(&content[1],
-                                              &content,
-                                              obj, pd,
-                                              &current_x, &current_y,
-                                              _efl_gfx_shape_append_arc_to,
-                                              EINA_FALSE))
-                goto error;
-              break;
-           case 'a':
-              if (!_efl_gfx_path_parse_arc_to(&content[1],
-                                              &content,
-                                              obj, pd,
-                                              &current_x, &current_y,
-                                              _efl_gfx_shape_append_arc_to,
-                                              EINA_TRUE))
-                goto error;
-              break;
-           default:
-              goto error;
+             //printf("Error parsing command\n");
+             goto error;
           }
+        process_command(obj, pd, cmd, number_array, number_count, &cur_x, &cur_y);
+        if (!arc && (cmd == 'a') || (cmd == 'A') ||
+            (cmd == 'e') || (cmd == 'E'))
+          arc = EINA_TRUE;
+     }
+   if (arc)
+     {
+        // need to keep the path for interpolation
+        if (pd->path_data)
+          free(pd->path_data);
+        pd->path_data = malloc(strlen(svg_path_data) + 1);
+        strcpy(pd->path_data, svg_path_data);
      }
+
 // TIZEN_ONLY(20160420): efl/interface: update locale before parsing svg path
 error:
    setlocale(LC_NUMERIC, cur_locale);