jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=2a31883f5a53b15128a49aee17b737ec0ee1d9c2

commit 2a31883f5a53b15128a49aee17b737ec0ee1d9c2
Author: subhransu mohanty <sub.moha...@samsung.com>
Date:   Wed Jan 17 14:20:15 2018 +0900

    efl/vg: Refactor the svg path handling and interpolation.
    
    Summary:
    This patch is taken from the tizen branch
    
    1. Take care when the locale is different than POSIX.
    See: strtod, strtol
    
    2. Interpolate  all the property of a shape.
    
    Reviewers: jpeg
    
    Subscribers: cedric, jpeg
    
    Differential Revision: https://phab.enlightenment.org/D5740
---
 src/lib/efl/interfaces/efl_gfx_path.c | 858 +++++++++++++++++-----------------
 1 file changed, 424 insertions(+), 434 deletions(-)

diff --git a/src/lib/efl/interfaces/efl_gfx_path.c 
b/src/lib/efl/interfaces/efl_gfx_path.c
index 2901373ddc..4d8ed3c6ca 100644
--- a/src/lib/efl/interfaces/efl_gfx_path.c
+++ b/src/lib/efl/interfaces/efl_gfx_path.c
@@ -5,6 +5,7 @@
 #include <math.h>
 #include <float.h>
 #include <ctype.h>
+#include <locale.h>
 
 #include <Efl.h>
 
@@ -21,6 +22,7 @@ struct _Efl_Gfx_Path_Data
 
    unsigned int commands_count;
    unsigned int points_count;
+   char *path_data;
    Eina_Bool convex;
 };
 
@@ -273,6 +275,48 @@ interpolate(double from, double to, double pos_map)
    return (from * (1.0 - pos_map)) + (to * pos_map);
 }
 
+static inline int
+interpolatei(int from, int to, double pos_map)
+{
+   return (from * (1.0 - pos_map)) + (to * pos_map);
+}
+
+typedef struct _Efl_Gfx_Property Efl_Gfx_Property;
+struct _Efl_Gfx_Property
+{
+   double scale;
+   double w;
+   double centered;
+
+   Efl_Gfx_Cap c;
+   Efl_Gfx_Join j;
+
+   const Efl_Gfx_Dash *dash;
+   unsigned int dash_length;
+
+   int r, g, b, a;
+   int fr, fg, fb, fa;
+};
+
+static inline void
+_efl_gfx_property_get(const Eo *obj, Efl_Gfx_Property *property)
+{
+
+   property->scale = efl_gfx_shape_stroke_scale_get(obj);
+   efl_gfx_shape_stroke_color_get(obj, &property->r, &property->g, 
&property->b, &property->a);
+   efl_gfx_color_get(obj, &property->fr, &property->fg, &property->fb, 
&property->fa);
+   property->w = efl_gfx_shape_stroke_width_get(obj);
+   property->centered = efl_gfx_shape_stroke_location_get(obj);
+   efl_gfx_shape_stroke_dash_get(obj, &property->dash, &property->dash_length);
+   property->c = efl_gfx_shape_stroke_cap_get(obj);
+   property->j = efl_gfx_shape_stroke_join_get(obj);
+}
+
+
+
+static void _path_interpolation(Eo *obj, Efl_Gfx_Path_Data *pd, char *from, 
char *to, double pos);
+static void _efl_gfx_path_reset(Eo *obj, Efl_Gfx_Path_Data *pd);
+
 EOLIAN static Eina_Bool
 _efl_gfx_path_interpolate(Eo *obj, Efl_Gfx_Path_Data *pd,
                            const Eo *from, const Eo *to, double pos_map)
@@ -280,68 +324,112 @@ _efl_gfx_path_interpolate(Eo *obj, Efl_Gfx_Path_Data *pd,
    Efl_Gfx_Path_Change_Event ev = { EFL_GFX_CHANGE_FLAG_PATH };
    Efl_Gfx_Path_Data *from_pd, *to_pd;
    Efl_Gfx_Path_Command *cmds;
+   Efl_Gfx_Property property_from, property_to;
+   Efl_Gfx_Dash *dash = NULL;
    double *pts;
    unsigned int i, j;
 
    from_pd = efl_data_scope_get(from, EFL_GFX_PATH_MIXIN);
    to_pd = efl_data_scope_get(to, EFL_GFX_PATH_MIXIN);
-
    if (!efl_isa(from, EFL_GFX_PATH_MIXIN) || !efl_isa(to, EFL_GFX_PATH_MIXIN))
      return EINA_FALSE;
-
    if (pd == from_pd || pd == to_pd) return EINA_FALSE;
 
-   if (!_efl_gfx_path_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;
+   _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;
 
-   pts = realloc(pd->points, sizeof (double) * from_pd->points_count);
-   if (!pts && from_pd->points_count)
+   if (from_pd->path_data && to_pd->path_data)
      {
-        free(cmds);
-        return EINA_FALSE;
+        _efl_gfx_path_reset(obj, pd);
+        _path_interpolation(obj, pd, from_pd->path_data, to_pd->path_data, 
pos_map);
      }
-
-   pd->commands = cmds;
-   pd->points = pts;
-
-   if (cmds)
+   else
      {
-        memcpy(cmds, from_pd->commands,
-               sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
+        if (!_efl_gfx_path_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;
 
-        if (pts)
+        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;
+             memcpy(cmds, from_pd->commands,
+                    sizeof (Efl_Gfx_Path_Command) * from_pd->commands_count);
 
-             for (i = 0; cmds[i] != EFL_GFX_PATH_COMMAND_TYPE_END; i++)
+             if (pts)
                {
-                  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++;
-                    }
+                  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,
+                                         pos_map);
+        pd->current_ctrl.y = interpolate(from_pd->current_ctrl.y,
+                                         to_pd->current_ctrl.y,
+                                         pos_map);
+   }
+
+   if (property_to.dash_length)
+     {
+        dash = malloc(sizeof (Efl_Gfx_Dash) * property_to.dash_length);
+        if (!dash) return EINA_FALSE;
+
+        for (i = 0; i < property_to.dash_length; i++)
+          {
+             dash[i].length = interpolate(property_from.dash[i].length,
+                                          property_to.dash[i].length, pos_map);
+             dash[i].gap = interpolate(property_from.dash[i].gap,
+                                       property_to.dash[i].gap, pos_map);
+          }
      }
 
-   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, pos_map);
-   pd->current_ctrl.y = interpolate(from_pd->current_ctrl.y,
-                                    to_pd->current_ctrl.y, pos_map);
+   efl_gfx_shape_stroke_scale_set(obj, interpolate(property_from.scale, 
property_to.scale, pos_map));
+   efl_gfx_shape_stroke_color_set(obj, interpolatei(property_from.r, 
property_to.r, pos_map),
+                                      interpolatei(property_from.g, 
property_to.g, pos_map),
+                                      interpolatei(property_from.b, 
property_to.b, pos_map),
+                                      interpolatei(property_from.a, 
property_to.a, pos_map));
+    efl_gfx_color_set(obj, interpolatei(property_from.fr, property_to.fr, 
pos_map),
+                           interpolatei(property_from.fg, property_to.fg, 
pos_map),
+                           interpolatei(property_from.fb, property_to.fb, 
pos_map),
+                           interpolatei(property_from.fa, property_to.fa, 
pos_map));
+    efl_gfx_shape_stroke_width_set(obj, interpolate(property_from.w, 
property_to.w, pos_map));
+    efl_gfx_shape_stroke_location_set(obj, interpolate(property_from.centered, 
property_to.centered, pos_map));
+    efl_gfx_shape_stroke_dash_set(obj, dash, property_to.dash_length);
+    efl_gfx_shape_stroke_cap_set(obj, pos_map < 0.5 ? property_from.c : 
property_to.c);
+    efl_gfx_shape_stroke_join_set(obj, pos_map < 0.5 ? property_from.j : 
property_to.j);
 
-   efl_event_callback_legacy_call(obj, EFL_GFX_PATH_EVENT_CHANGED, &ev);
+    efl_event_callback_legacy_call(obj, EFL_GFX_PATH_EVENT_CHANGED, &ev);
 
    return EINA_TRUE;
 }
@@ -371,6 +459,8 @@ _efl_gfx_path_reset(Eo *obj, Efl_Gfx_Path_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;
@@ -1128,453 +1218,353 @@ _parse_number(char **content, double *number)
 {
    char *end = NULL;
    *number = strtod(*content, &end);
-   // if the start of string is not number 
+   // if the start of string is not number
    if ((*content) == end) return EINA_FALSE;
    //skip comma if any
    *content = _skipcomma(end);
    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_Path_Data *pd,
-                            double *current_x, double *current_y,
-                            void (*func)(Eo *obj, Efl_Gfx_Path_Data *pd,
-                                         double x, double y),
-                            Eina_Bool rel)
+static int
+_number_count(char cmd)
 {
-   double x, y;
-
-   *end = (char*) content;
-
-   do
+   int count = 0;
+   switch (cmd)
      {
-        if (!_efl_gfx_path_parse_pair(content, end, &x, &y))
-          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 Eina_Bool
-_efl_gfx_path_parse_double_to(const char *content, char **end,
-                              Eo *obj, Efl_Gfx_Path_Data *pd,
-                              double *current, double current_x,
-                              double current_y,
-                              void (*func)(Eo *obj, Efl_Gfx_Path_Data *pd,
-                                           double d, double current_x,
-                                           double current_y),
-                              Eina_Bool rel)
+static void
+process_command(Eo *obj, Efl_Gfx_Path_Data *pd, char cmd, double *arr, int 
count, double *cur_x, double *cur_y)
 {
-   double d;
-   Eina_Bool first = EINA_FALSE;
-
-   *end = (char*) content;
-   do
+   int i;
+   switch (cmd)
      {
-        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;
-     }
-   while (1); // This is an optimisation as we have only one parameter.
-
-   return EINA_TRUE;
+      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_path_append_move_to(obj, pd, arr[0], arr[1]);
+           *cur_x = arr[0];
+           *cur_y = arr[1];
+           break;
+        }
+      case 'l':
+      case 'L':
+        {
+           _efl_gfx_path_append_line_to(obj, pd, arr[0], arr[1]);
+           *cur_x = arr[0];
+           *cur_y = arr[1];
+           break;
+        }
+      case 'c':
+      case 'C':
+        {
+           _efl_gfx_path_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_path_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_path_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_path_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_path_append_close(obj, pd);
+           break;
+        }
+      case 'a':
+      case 'A':
+        {
+           _efl_gfx_path_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_path_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_six(const char *content, char **end,
-                        double *x, double *y,
-                        double *ctrl_x0, double *ctrl_y0,
-                        double *ctrl_x1, double *ctrl_y1)
+static char *
+_next_command(char *path, char *cmd, double *arr, int *count)
 {
-   char *str = (char *) content;
+   int i=0, large, sweep;
 
-   if (_parse_number(&str, ctrl_x0))
+   path = _skipcomma(path);
+   if (isalpha(*path))
      {
-        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;
-                              }
-                         }
-                    }
-               }
-          }
+        *cmd = *path;
+        path++;
+        *count = _number_count(*cmd);
      }
-
-   return EINA_FALSE;
-}
-
-static Eina_Bool
-_efl_gfx_path_parse_six_to(const char *content, char **end,
-                           Eo *obj, Efl_Gfx_Path_Data *pd,
-                           double *current_x, double *current_y,
-                           void (*func)(Eo *obj, Efl_Gfx_Path_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)
      {
-        if (!_efl_gfx_path_parse_six(content, end, &x, &y, &ctrl_x0, &ctrl_y0,
-                                     &ctrl_x1, &ctrl_y1))
-          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_Path_Data *pd,
-                            double *current_x, double *current_y,
-                            void (*func)(Eo *obj, Efl_Gfx_Path_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)
+static void
+_path_interpolation(Eo *obj, Efl_Gfx_Path_Data *pd,
+                     char *from, char *to, double pos)
 {
-   char *str = (char *) content;
-   char *end1 = NULL;
-   char *end2 = NULL;
+   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;
+
+   if (!from || !to)
+     return;
 
-   if (_parse_number(&str, rx))
+   cur_locale = setlocale(LC_NUMERIC, NULL);
+   if (cur_locale)
+     cur_locale = strdup(cur_locale);
+   setlocale(LC_NUMERIC, "POSIX");
+
+   while ((from[0] != '\0') && (to[0] != '\0'))
      {
-        if (_parse_number(&str, ry))
+        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)
           {
-             if (_parse_number(&str, radius))
+             if (from_count == 7)
                {
-                  // large_arc
-                  *large_arc = strtol(str, &end1, 10) ? EINA_TRUE : EINA_FALSE;
-                  if (!end1 || (str == end1)) return EINA_FALSE;
-                  end1 = _skipcomma(end1);
-
-                  // sweep
-                  *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;
-                      }
+                  //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);
           }
-     }
-   return EINA_FALSE;
-}
-
-static Eina_Bool
-_efl_gfx_path_parse_arc_to(const char *content, char **end,
-                           Eo *obj, Efl_Gfx_Path_Data *pd,
-                           double *current_x, double *current_y,
-                           void (*func)(Eo *obj, Efl_Gfx_Path_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
-
-   *end = (char*) content;
-
-   do
-     {
-        Eina_Bool r;
-
-        r = _efl_gfx_path_parse_arc(content, end, &x, &y, &rx, &ry, &angle,
-                                    &large_arc, &sweep);
-        if (!r) return EINA_FALSE;
-
-        if (rel)
+        else
           {
-             x += *current_x;
-             y += *current_y;
+             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;
+error:
+   setlocale(LC_NUMERIC, cur_locale);
+   if (cur_locale)
+     free(cur_locale);
 }
 
 EOLIAN static void
 _efl_gfx_path_append_svg_path(Eo *obj, Efl_Gfx_Path_Data *pd,
-                               const char *svg_path_data)
+                              const char *svg_path_data)
 {
-   double current_x = 0, current_y = 0;
-
-   //FIXME: const char *svg_path_data ???
-   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 (!path)
+     return;
 
-   if (!content) return;
+   cur_locale = setlocale(LC_NUMERIC, NULL);
+   if (cur_locale)
+     cur_locale = strdup(cur_locale);
+   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_path_append_move_to,
-                                               EINA_FALSE))
-                return;
-              break;
-           case 'm':
-              if (!_efl_gfx_path_parse_pair_to(&content[1], &content, obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_path_append_move_to,
-                                               EINA_TRUE))
-                return;
-              break;
-           case 'z':
-           case 'Z':
-              _efl_gfx_path_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_path_append_line_to,
-                                               EINA_FALSE))
-                return;
-              break;
-           case 'l':
-              if (!_efl_gfx_path_parse_pair_to(&content[1], &content, obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_path_append_line_to,
-                                               EINA_TRUE))
-                return;
-              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))
-                return;
-              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))
-                return;
-              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))
-                return;
-              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))
-                return;
-              break;
-           case 'C':
-              if (!_efl_gfx_path_parse_six_to(&content[1], &content, obj, pd,
-                                              &current_x, &current_y,
-                                              _efl_gfx_path_append_cubic_to,
-                                              EINA_FALSE))
-                return;
-              break;
-           case 'c':
-              if (!_efl_gfx_path_parse_six_to(&content[1], &content, obj, pd,
-                                              &current_x, &current_y,
-                                              _efl_gfx_path_append_cubic_to,
-                                              EINA_TRUE))
-                return;
-              break;
-           case 'S':
-              if (!_efl_gfx_path_parse_quad_to(&content[1], &content, obj, pd,
-                                               &current_x, &current_y,
-                                               _efl_gfx_path_append_scubic_to,
-                                               EINA_FALSE))
-                return;
-              break;
-           case 's':
-              if (!_efl_gfx_path_parse_quad_to(&content[1], &content,
-                                               obj, pd, &current_x, &current_y,
-                                               _efl_gfx_path_append_scubic_to,
-                                               EINA_TRUE))
-                return;
-              break;
-           case 'Q':
-              if (!_efl_gfx_path_parse_quad_to(&content[1], &content,
-                                               obj, pd, &current_x, &current_y,
-                                               
_efl_gfx_path_append_quadratic_to,
-                                               EINA_FALSE))
-                return;
-              break;
-           case 'q':
-              if (!_efl_gfx_path_parse_quad_to(&content[1], &content,
-                                               obj, pd, &current_x, &current_y,
-                                               
_efl_gfx_path_append_quadratic_to,
-                                               EINA_TRUE))
-                return;
-              break;
-           case 'T':
-              if (!_efl_gfx_path_parse_pair_to(&content[1], &content,
-                                               obj, pd, &current_x, &current_y,
-                                               
_efl_gfx_path_append_squadratic_to,
-                                               EINA_FALSE))
-                return;
-              break;
-           case 't':
-              if (!_efl_gfx_path_parse_pair_to(&content[1], &content,
-                                               obj, pd, &current_x, &current_y,
-                                               
_efl_gfx_path_append_squadratic_to,
-                                               EINA_TRUE))
-                return;
-              break;
-           case 'A':
-              if (!_efl_gfx_path_parse_arc_to(&content[1], &content,
-                                              obj, pd, &current_x, &current_y,
-                                              _efl_gfx_path_append_arc_to,
-                                              EINA_FALSE))
-                return;
-              break;
-           case 'a':
-              if (!_efl_gfx_path_parse_arc_to(&content[1], &content,
-                                              obj, pd, &current_x, &current_y,
-                                              _efl_gfx_path_append_arc_to,
-                                              EINA_TRUE))
-                return;
-              break;
-           default:
-              return;
+             //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);
      }
+
+error:
+   setlocale(LC_NUMERIC, cur_locale);
+   if (cur_locale)
+     free(cur_locale);
 }
 
 EOLIAN static void

-- 


Reply via email to