cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=84b6b4c0406b0ca3a2fe62aaffeb0467cb085bf7
commit 84b6b4c0406b0ca3a2fe62aaffeb0467cb085bf7 Author: Subhransu Mohanty <[email protected]> Date: Fri Aug 28 10:12:44 2015 +0900 efl/gfx: fix svg path parsing logic. 1. according to svg path specification, path string may or may not contain ',' as the separator with current parsing logic we were expecting a ',' after each segment. 2. relative cubic bezier parsing was wrong as we were not adding the current value to all 4 points. 3. refactored the parse_pair, parse_six and parse_quad to use same helper function path1: "M7.279,2h35.442C45.637,2,48,4.359,48,7.271v35.455C48,45.639,45.637,48,42.723,48H7.279C4.362,47.997,2,45.639,2,42.727V7.271C2,4.359,4.362,2,7.279,2z" path2: "M-2.073-7h36.147C36.796-7,39-4.793,39-2.073v36.146C39,36.796,36.796,39,34.074,39H-2.073C-4.793,39-7,36.796-7,34.072V-2.073C-7-4.793-4.793-7-2.073-7z" Signed-off-by: Cedric BAIL <[email protected]> --- src/lib/efl/interfaces/efl_gfx_shape.c | 159 +++++++++++++++------------------ 1 file changed, 74 insertions(+), 85 deletions(-) diff --git a/src/lib/efl/interfaces/efl_gfx_shape.c b/src/lib/efl/interfaces/efl_gfx_shape.c index b054ca7..6b5d05d 100644 --- a/src/lib/efl/interfaces/efl_gfx_shape.c +++ b/src/lib/efl/interfaces/efl_gfx_shape.c @@ -873,11 +873,11 @@ _efl_gfx_path_append_vertical_to(Eo *obj, Efl_Gfx_Shape_Data *pd, } static char * -_strcomma(const char *content) +_skipcomma(const char *content) { while (*content && isspace(*content)) content++; - if (*content != ',') return NULL; - return (char*) content + 1; + if (*content == ',') return (char*) content + 1; + return (char*) content; } static inline Eina_Bool @@ -889,21 +889,30 @@ _next_isnumber(const char *content) return content != tmp; } +static inline Eina_Bool +_parse_number(char **content, double *number) +{ + char *end = NULL; + *number = strtod(*content, &end); + // 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) { - /* "x,y" */ - char *end1 = NULL; - char *end2 = NULL; + char *str = (char *) content; - *x = strtod(content, &end1); - end1 = _strcomma(end1); - if (!end1) return EINA_FALSE; - *y = strtod(end1, &end2); - if (end1 == end2) return EINA_FALSE; - - *end = end2; - return EINA_TRUE; + if (_parse_number(&str, x)) + if (_parse_number(&str, y)) + { + *end = str; + return EINA_TRUE; + } + return EINA_FALSE; } static Eina_Bool @@ -979,31 +988,18 @@ _efl_gfx_path_parse_six(const char *content, char **end, double *ctrl_x0, double *ctrl_y0, double *ctrl_x1, double *ctrl_y1) { - /* "x,y ctrl_x0,ctrl_y0 ctrl_x1,ctrl_y1" */ - char *end1 = NULL; - char *end2 = NULL; - - *ctrl_x0 = strtod(content, &end1); - end1 = _strcomma(end1); - if (!end1) return EINA_FALSE; - *ctrl_y0 = strtod(end1, &end2); - if (end1 == end2) return EINA_FALSE; - - *ctrl_x1 = strtod(end2, &end2); - end2 = _strcomma(end2); - if (!end2) return EINA_FALSE; - *ctrl_y1 = strtod(end2, &end1); - if (end1 == end2) return EINA_FALSE; - - *x = strtod(end1, &end2); - end2 = _strcomma(end2); - if (!end2) return EINA_FALSE; - *y = strtod(end2, &end1); - if (end1 == end2) return EINA_FALSE; - - *end = end1; - - return EINA_TRUE; + 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 @@ -1030,8 +1026,11 @@ _efl_gfx_path_parse_six_to(const char *content, char **end, { 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, x, y, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1); content = *end; @@ -1048,25 +1047,17 @@ _efl_gfx_path_parse_quad(const char *content, char **end, double *x, double *y, double *ctrl_x0, double *ctrl_y0) { - /* "x,y ctrl_x0,ctrl_y0" */ - char *end1 = NULL; - char *end2 = NULL; - - *ctrl_x0 = strtod(content, &end1); - end1 = _strcomma(end1); - if (!end1) return EINA_FALSE; - *ctrl_y0 = strtod(end1, &end2); - if (end1 == end2) return EINA_FALSE; - - *x = strtod(end2, &end1); - end1 = _strcomma(end2); - if (!end1) return EINA_FALSE; - *y = strtod(end1, &end2); - if (end1 == end2) return EINA_FALSE; - - *end = end2; - - return EINA_TRUE; + 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 @@ -1113,34 +1104,32 @@ _efl_gfx_path_parse_arc(const char *content, char **end, double *radius, Eina_Bool *large_arc, Eina_Bool *sweep) { - /* "rx,ry r large-arc-flag,sweep-flag x,y" */ + char *str = (char *) content; char *end1 = NULL; char *end2 = NULL; - *rx = strtod(content, &end1); - end1 = _strcomma(end1); - if (!end1) return EINA_FALSE; - *ry = strtod(end1, &end2); - if (end1 == end2) return EINA_FALSE; - - *radius = strtod(end2, &end1); - if (end1 == end2) return EINA_FALSE; - - *large_arc = strtol(end1, &end2, 10) ? EINA_TRUE : EINA_FALSE; - end1 = _strcomma(end2); - if (!end1) return EINA_FALSE; - *sweep = strtol(end1, &end2, 10) ? EINA_TRUE : EINA_FALSE; - if (end1 == end2) return EINA_FALSE; - - *x = strtod(end2, &end1); - end1 = _strcomma(end2); - if (!end1) return EINA_FALSE; - *y = strtod(end1, &end2); - if (end1 == end2) return EINA_FALSE; - - *end = end2; - - return EINA_TRUE; + 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(end2, &end1, 10) ? EINA_TRUE : EINA_FALSE; + if (!end1 || (end1 == end2)) return EINA_FALSE; + str = _skipcomma(end1); + + if (_parse_number(&str, x)) + if (_parse_number(&str, y)) + { + *end = str; + return EINA_TRUE; + } + } + return EINA_FALSE; } static Eina_Bool @@ -1367,7 +1356,7 @@ _efl_gfx_shape_append_svg_path(Eo *obj, Efl_Gfx_Shape_Data *pd, return ; break; default: - return ; + return; } } } --
