summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubhransu Mohanty <sub.mohanty@samsung.com>2015-08-28 10:12:44 +0900
committerCedric BAIL <cedric@osg.samsung.com>2015-10-20 15:22:31 -0700
commit84b6b4c0406b0ca3a2fe62aaffeb0467cb085bf7 (patch)
treeafd1419984f2a87af4d77b429b4ddf374232643e
parentfe10889ec7c16ab8b34a37730a5ddda160ab3f24 (diff)
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>
-rw-r--r--src/lib/efl/interfaces/efl_gfx_shape.c159
1 files 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 b054ca7923..6b5d05d045 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,
873} 873}
874 874
875static char * 875static char *
876_strcomma(const char *content) 876_skipcomma(const char *content)
877{ 877{
878 while (*content && isspace(*content)) content++; 878 while (*content && isspace(*content)) content++;
879 if (*content != ',') return NULL; 879 if (*content == ',') return (char*) content + 1;
880 return (char*) content + 1; 880 return (char*) content;
881} 881}
882 882
883static inline Eina_Bool 883static inline Eina_Bool
@@ -889,21 +889,30 @@ _next_isnumber(const char *content)
889 return content != tmp; 889 return content != tmp;
890} 890}
891 891
892static inline Eina_Bool
893_parse_number(char **content, double *number)
894{
895 char *end = NULL;
896 *number = strtod(*content, &end);
897 // if the start of string is not number
898 if ((*content) == end) return EINA_FALSE;
899 //skip comma if any
900 *content = _skipcomma(end);
901 return EINA_TRUE;
902}
903
892static Eina_Bool 904static Eina_Bool
893_efl_gfx_path_parse_pair(const char *content, char **end, double *x, double *y) 905_efl_gfx_path_parse_pair(const char *content, char **end, double *x, double *y)
894{ 906{
895 /* "x,y" */ 907 char *str = (char *) content;
896 char *end1 = NULL;
897 char *end2 = NULL;
898 908
899 *x = strtod(content, &end1); 909 if (_parse_number(&str, x))
900 end1 = _strcomma(end1); 910 if (_parse_number(&str, y))
901 if (!end1) return EINA_FALSE; 911 {
902 *y = strtod(end1, &end2); 912 *end = str;
903 if (end1 == end2) return EINA_FALSE; 913 return EINA_TRUE;
904 914 }
905 *end = end2; 915 return EINA_FALSE;
906 return EINA_TRUE;
907} 916}
908 917
909static Eina_Bool 918static Eina_Bool
@@ -979,31 +988,18 @@ _efl_gfx_path_parse_six(const char *content, char **end,
979 double *ctrl_x0, double *ctrl_y0, 988 double *ctrl_x0, double *ctrl_y0,
980 double *ctrl_x1, double *ctrl_y1) 989 double *ctrl_x1, double *ctrl_y1)
981{ 990{
982 /* "x,y ctrl_x0,ctrl_y0 ctrl_x1,ctrl_y1" */ 991 char *str = (char *) content;
983 char *end1 = NULL; 992 if (_parse_number(&str, ctrl_x0))
984 char *end2 = NULL; 993 if (_parse_number(&str, ctrl_y0))
985 994 if (_parse_number(&str, ctrl_x1))
986 *ctrl_x0 = strtod(content, &end1); 995 if (_parse_number(&str, ctrl_y1))
987 end1 = _strcomma(end1); 996 if (_parse_number(&str, x))
988 if (!end1) return EINA_FALSE; 997 if (_parse_number(&str, y))
989 *ctrl_y0 = strtod(end1, &end2); 998 {
990 if (end1 == end2) return EINA_FALSE; 999 *end = str;
991 1000 return EINA_TRUE;
992 *ctrl_x1 = strtod(end2, &end2); 1001 }
993 end2 = _strcomma(end2); 1002 return EINA_FALSE;
994 if (!end2) return EINA_FALSE;
995 *ctrl_y1 = strtod(end2, &end1);
996 if (end1 == end2) return EINA_FALSE;
997
998 *x = strtod(end1, &end2);
999 end2 = _strcomma(end2);
1000 if (!end2) return EINA_FALSE;
1001 *y = strtod(end2, &end1);
1002 if (end1 == end2) return EINA_FALSE;
1003
1004 *end = end1;
1005
1006 return EINA_TRUE;
1007} 1003}
1008 1004
1009static Eina_Bool 1005static Eina_Bool
@@ -1030,8 +1026,11 @@ _efl_gfx_path_parse_six_to(const char *content, char **end,
1030 { 1026 {
1031 x += *current_x; 1027 x += *current_x;
1032 y += *current_y; 1028 y += *current_y;
1029 ctrl_x0 += *current_x;
1030 ctrl_y0 += *current_y;
1031 ctrl_x1 += *current_x;
1032 ctrl_y1 += *current_y;
1033 } 1033 }
1034
1035 func(obj, pd, x, y, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1); 1034 func(obj, pd, x, y, ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1);
1036 content = *end; 1035 content = *end;
1037 1036
@@ -1048,25 +1047,17 @@ _efl_gfx_path_parse_quad(const char *content, char **end,
1048 double *x, double *y, 1047 double *x, double *y,
1049 double *ctrl_x0, double *ctrl_y0) 1048 double *ctrl_x0, double *ctrl_y0)
1050{ 1049{
1051 /* "x,y ctrl_x0,ctrl_y0" */ 1050 char *str = (char *) content;
1052 char *end1 = NULL; 1051
1053 char *end2 = NULL; 1052 if (_parse_number(&str, ctrl_x0))
1054 1053 if (_parse_number(&str, ctrl_y0))
1055 *ctrl_x0 = strtod(content, &end1); 1054 if (_parse_number(&str, x))
1056 end1 = _strcomma(end1); 1055 if (_parse_number(&str, y))
1057 if (!end1) return EINA_FALSE; 1056 {
1058 *ctrl_y0 = strtod(end1, &end2); 1057 *end = str;
1059 if (end1 == end2) return EINA_FALSE; 1058 return EINA_TRUE;
1060 1059 }
1061 *x = strtod(end2, &end1); 1060 return EINA_FALSE;
1062 end1 = _strcomma(end2);
1063 if (!end1) return EINA_FALSE;
1064 *y = strtod(end1, &end2);
1065 if (end1 == end2) return EINA_FALSE;
1066
1067 *end = end2;
1068
1069 return EINA_TRUE;
1070} 1061}
1071 1062
1072static Eina_Bool 1063static Eina_Bool
@@ -1113,34 +1104,32 @@ _efl_gfx_path_parse_arc(const char *content, char **end,
1113 double *radius, 1104 double *radius,
1114 Eina_Bool *large_arc, Eina_Bool *sweep) 1105 Eina_Bool *large_arc, Eina_Bool *sweep)
1115{ 1106{
1116 /* "rx,ry r large-arc-flag,sweep-flag x,y" */ 1107 char *str = (char *) content;
1117 char *end1 = NULL; 1108 char *end1 = NULL;
1118 char *end2 = NULL; 1109 char *end2 = NULL;
1119 1110
1120 *rx = strtod(content, &end1); 1111 if (_parse_number(&str, rx))
1121 end1 = _strcomma(end1); 1112 if (_parse_number(&str, ry))
1122 if (!end1) return EINA_FALSE; 1113 if (_parse_number(&str, radius))
1123 *ry = strtod(end1, &end2); 1114 {
1124 if (end1 == end2) return EINA_FALSE; 1115 // large_arc
1125 1116 *large_arc = strtol(str, &end1, 10) ? EINA_TRUE : EINA_FALSE;
1126 *radius = strtod(end2, &end1); 1117 if (!end1 || (str == end1)) return EINA_FALSE;
1127 if (end1 == end2) return EINA_FALSE; 1118 end1 = _skipcomma(end1);
1128 1119
1129 *large_arc = strtol(end1, &end2, 10) ? EINA_TRUE : EINA_FALSE; 1120 // sweeo
1130 end1 = _strcomma(end2); 1121 *sweep = strtol(end2, &end1, 10) ? EINA_TRUE : EINA_FALSE;
1131 if (!end1) return EINA_FALSE; 1122 if (!end1 || (end1 == end2)) return EINA_FALSE;
1132 *sweep = strtol(end1, &end2, 10) ? EINA_TRUE : EINA_FALSE; 1123 str = _skipcomma(end1);
1133 if (end1 == end2) return EINA_FALSE; 1124
1134 1125 if (_parse_number(&str, x))
1135 *x = strtod(end2, &end1); 1126 if (_parse_number(&str, y))
1136 end1 = _strcomma(end2); 1127 {
1137 if (!end1) return EINA_FALSE; 1128 *end = str;
1138 *y = strtod(end1, &end2); 1129 return EINA_TRUE;
1139 if (end1 == end2) return EINA_FALSE; 1130 }
1140 1131 }
1141 *end = end2; 1132 return EINA_FALSE;
1142
1143 return EINA_TRUE;
1144} 1133}
1145 1134
1146static Eina_Bool 1135static Eina_Bool
@@ -1367,7 +1356,7 @@ _efl_gfx_shape_append_svg_path(Eo *obj, Efl_Gfx_Shape_Data *pd,
1367 return ; 1356 return ;
1368 break; 1357 break;
1369 default: 1358 default:
1370 return ; 1359 return;
1371 } 1360 }
1372 } 1361 }
1373} 1362}