forked from enlightenment/efl
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 <cedric@osg.samsung.com>
This commit is contained in:
parent
fe10889ec7
commit
84b6b4c040
|
@ -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;
|
||||
char *str = (char *) content;
|
||||
|
||||
*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;
|
||||
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;
|
||||
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);
|
||||
|
||||
*radius = strtod(end2, &end1);
|
||||
if (end1 == end2) return EINA_FALSE;
|
||||
// sweeo
|
||||
*sweep = strtol(end2, &end1, 10) ? EINA_TRUE : EINA_FALSE;
|
||||
if (!end1 || (end1 == end2)) return EINA_FALSE;
|
||||
str = _skipcomma(end1);
|
||||
|
||||
*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, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue