diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am index e1afdc7444..6b708a3c56 100644 --- a/src/Makefile_Edje.am +++ b/src/Makefile_Edje.am @@ -176,8 +176,7 @@ bin/edje/edje_cc_parse.c \ bin/edje/edje_cc_mem.c \ bin/edje/edje_cc_handlers.c \ bin/edje/edje_cc_sources.c \ -bin/edje/edje_multisense_convert.c \ -bin/edje/edje_svg_loader.c +bin/edje/edje_multisense_convert.c bin_edje_edje_cc_CPPFLAGS = -I$(top_builddir)/src/lib/efl $(EDJE_COMMON_CPPFLAGS) @EDJE_LUA_CFLAGS@ bin_edje_edje_cc_LDADD = $(USE_EDJE_BIN_LIBS) @EDJE_LUA_LIBS@ bin_edje_edje_cc_DEPENDENCIES = \ diff --git a/src/bin/edje/edje_cc.h b/src/bin/edje/edje_cc.h index e887bf4c3e..9e3c9a88d3 100644 --- a/src/bin/edje/edje_cc.h +++ b/src/bin/edje/edje_cc.h @@ -297,9 +297,6 @@ int get_param_index(char *str); void color_tree_root_free(void); void convert_color_code(char *str, int *r, int *g, int *b, int *a); -Svg_Node* _svg_load(Eina_File *f, const char *key EINA_UNUSED); - - /* global vars */ extern Eina_List *ext_dirs; extern Eina_List *img_dirs; diff --git a/src/bin/edje/edje_svg_loader.c b/src/bin/edje/edje_svg_loader.c deleted file mode 100644 index 03088ca638..0000000000 --- a/src/bin/edje/edje_svg_loader.c +++ /dev/null @@ -1,2048 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#include -#include -#include -#include - -#ifndef A_VAL -#ifndef WORDS_BIGENDIAN -/* x86 */ -#define A_VAL(p) (((uint8_t *)(p))[3]) -#define R_VAL(p) (((uint8_t *)(p))[2]) -#define G_VAL(p) (((uint8_t *)(p))[1]) -#define B_VAL(p) (((uint8_t *)(p))[0]) -#define AR_VAL(p) ((uint16_t *)(p)[1]) -#define GB_VAL(p) ((uint16_t *)(p)[0]) -#else -/* ppc */ -#define A_VAL(p) (((uint8_t *)(p))[0]) -#define R_VAL(p) (((uint8_t *)(p))[1]) -#define G_VAL(p) (((uint8_t *)(p))[2]) -#define B_VAL(p) (((uint8_t *)(p))[3]) -#define AR_VAL(p) ((uint16_t *)(p)[0]) -#define GB_VAL(p) ((uint16_t *)(p)[1]) -#endif -#endif - -#define ARGB_JOIN(a,r,g,b) \ - (((a) << 24) + ((r) << 16) + ((g) << 8) + (b)) - - -typedef Svg_Node *(*Factory_Method)(Svg_Node *parent, const char *buf, unsigned buflen); - -typedef Svg_Style_Gradient *(*Gradient_Factory_Method)(const char *buf, unsigned buflen); - -typedef struct _Evas_SVG_Loader Evas_SVG_Loader; -struct _Evas_SVG_Loader -{ - Eina_Array *stack; - Svg_Node *doc; - Svg_Node *def; - Svg_Style_Gradient *gradient; - int level; - Eina_Bool result:1; -}; - -char * -_skip_space(const char *str, const char *end) -{ - while (((end != NULL && str < end) || (end == NULL && *str != '\0')) && isspace(*str)) - ++str; - return (char *)str; -} - -static inline Eina_Stringshare * -_copy_id(const char* str) -{ - if (str == NULL) return NULL; - - return eina_stringshare_add(str); -} - -static const char * -_skipcomma(const char *content) -{ - content = _skip_space(content, NULL); - if (*content == ',') return content + 1; - return content; -} - -static inline Eina_Bool -_parse_number(const 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 inline double -_to_double(const char *str) -{ - char *end = NULL; - - return strtod(str, &end); -} - -static inline int -_to_opacity(const char *str) -{ - char *end = NULL; - int a = 0; - double opacity = strtod(str, &end); - - if (*end == '\0') - a = lrint(opacity * 255); - return a; -} - -#define _PARSE_TAG(Type, Short_Name, Tags_Array, Default) \ - static Type _to_##Short_Name(const char *str) \ - { \ - unsigned int i; \ - \ - for (i = 0; i < sizeof (Tags_Array) / sizeof (Tags_Array[0]); i++) \ - if (!strcmp(str, Tags_Array[i].tag)) \ - return Tags_Array[i].Short_Name; \ - return Default; \ - } -/* parse the line cap used during stroking a path. - * Value: butt | round | square | inherit - * Initial: butt - * https://www.w3.org/TR/SVG/painting.html - */ -static struct { - Efl_Gfx_Cap line_cap; - const char *tag; -} line_cap_tags[] = { - { EFL_GFX_CAP_BUTT, "butt" }, - { EFL_GFX_CAP_ROUND, "round" }, - { EFL_GFX_CAP_SQUARE, "square" } -}; - -_PARSE_TAG(Efl_Gfx_Cap, line_cap, line_cap_tags, EFL_GFX_CAP_LAST); - -/* parse the line join used during stroking a path. - * Value: miter | round | bevel | inherit - * Initial: miter - * https://www.w3.org/TR/SVG/painting.html - */ -static struct { - Efl_Gfx_Join line_join; - const char *tag; -} line_join_tags[] = { - { EFL_GFX_JOIN_MITER, "miter" }, - { EFL_GFX_JOIN_ROUND, "round" }, - { EFL_GFX_JOIN_BEVEL, "bevel" } -}; - -_PARSE_TAG(Efl_Gfx_Join, line_join, line_join_tags, EFL_GFX_JOIN_LAST); - -/* parse the fill rule used during filling a path. - * Value: nonzero | evenodd | inherit - * Initial: nonzero - * https://www.w3.org/TR/SVG/painting.html - */ - -static struct { - Efl_Gfx_Fill_Rule fill_rule; - const char *tag; -} fill_rule_tags[] = { - { EFL_GFX_FILL_RULE_ODD_EVEN, "evenodd" } -}; - -_PARSE_TAG(Efl_Gfx_Fill_Rule, fill_rule, fill_rule_tags, EFL_GFX_FILL_RULE_WINDING); - -#if 0 -// unused at the moment -/* parse the dash pattern used during stroking a path. - * Value: none | | inherit - * Initial: none - * https://www.w3.org/TR/SVG/painting.html - */ -static inline void -_parse_dash_array(const char *str, Efl_Gfx_Dash** dash, int *length) -{ - double tmp[30]; - char *end = NULL; - int leni, gapi, count = 0, index = 0; - - while (*str) - { - // skip white space, comma - str = _skipcomma(str); - tmp[count++] = strtod(str, &end); - str = _skipcomma(end); - } - - if (count & 0x1) - { // odd case. - *length = count; - *dash = calloc(*length, sizeof(Efl_Gfx_Dash)); - while (index < count) - { - leni = (2 * index) % count; - gapi = (2 * index + 1) % count; - (*dash)[index].length = tmp[leni]; - (*dash)[index].gap = tmp[gapi]; - } - } - else - { // even case - *length = count/2; - *dash = calloc(*length, sizeof(Efl_Gfx_Dash)); - while (index < count) - { - (*dash)[index].length = tmp[2 * index]; - (*dash)[index].gap = tmp[2 * index + 1]; - } - } -} -#endif - -static Eina_Stringshare * - _id_from_url(const char *url) -{ - char tmp[50]; - int i = 0; - - url = _skip_space(url, NULL); - if ((*url) == '(') - ++url; - url = _skip_space(url, NULL); - if ((*url) == '#') - ++url; - - while ((*url) != ')') - { - tmp[i++] = *url; - ++url; - } - tmp[i] = '\0'; - - return eina_stringshare_add(tmp); -} - -static unsigned char -_color_parser(const char *value, char **end) -{ - double r; - - r = strtod(value + 4, end); - *end = _skip_space(*end, NULL); - if (**end == '%') - r = 255 * r / 100; - *end = _skip_space(*end, NULL); - - if (r < 0 || r > 255) - { - *end = NULL; - return 0; - } - - return lrint(r); -} - -static const struct { - const char *name; - unsigned int value; -} colors[] = { - { "aliceblue", 0xfff0f8ff }, - { "antiquewhite", 0xfffaebd7 }, - { "aqua", 0xff00ffff }, - { "aquamarine", 0xff7fffd4 }, - { "azure", 0xfff0ffff }, - { "beige", 0xfff5f5dc }, - { "bisque", 0xffffe4c4 }, - { "black", 0xff000000 }, - { "blanchedalmond", 0xffffebcd }, - { "blue", 0xff0000ff }, - { "blueviolet", 0xff8a2be2 }, - { "brown", 0xffa52a2a }, - { "burlywood", 0xffdeb887 }, - { "cadetblue", 0xff5f9ea0 }, - { "chartreuse", 0xff7fff00 }, - { "chocolate", 0xffd2691e }, - { "coral", 0xffff7f50 }, - { "cornflowerblue", 0xff6495ed }, - { "cornsilk", 0xfffff8dc }, - { "crimson", 0xffdc143c }, - { "cyan", 0xff00ffff }, - { "darkblue", 0xff00008b }, - { "darkcyan", 0xff008b8b }, - { "darkgoldenrod", 0xffb8860b }, - { "darkgray", 0xffa9a9a9 }, - { "darkgrey", 0xffa9a9a9 }, - { "darkgreen", 0xff006400 }, - { "darkkhaki", 0xffbdb76b }, - { "darkmagenta", 0xff8b008b }, - { "darkolivegreen", 0xff556b2f }, - { "darkorange", 0xffff8c00 }, - { "darkorchid", 0xff9932cc }, - { "darkred", 0xff8b0000 }, - { "darksalmon", 0xffe9967a }, - { "darkseagreen", 0xff8fbc8f }, - { "darkslateblue", 0xff483d8b }, - { "darkslategray", 0xff2f4f4f }, - { "darkslategrey", 0xff2f4f4f }, - { "darkturquoise", 0xff00ced1 }, - { "darkviolet", 0xff9400d3 }, - { "deeppink", 0xffff1493 }, - { "deepskyblue", 0xff00bfff }, - { "dimgray", 0xff696969 }, - { "dimgrey", 0xff696969 }, - { "dodgerblue", 0xff1e90ff }, - { "firebrick", 0xffb22222 }, - { "floralwhite", 0xfffffaf0 }, - { "forestgreen", 0xff228b22 }, - { "fuchsia", 0xffff00ff }, - { "gainsboro", 0xffdcdcdc }, - { "ghostwhite", 0xfff8f8ff }, - { "gold", 0xffffd700 }, - { "goldenrod", 0xffdaa520 }, - { "gray", 0xff808080 }, - { "grey", 0xff808080 }, - { "green", 0xff008000 }, - { "greenyellow", 0xffadff2f }, - { "honeydew", 0xfff0fff0 }, - { "hotpink", 0xffff69b4 }, - { "indianred", 0xffcd5c5c }, - { "indigo", 0xff4b0082 }, - { "ivory", 0xfffffff0 }, - { "khaki", 0xfff0e68c }, - { "lavender", 0xffe6e6fa }, - { "lavenderblush", 0xfffff0f5 }, - { "lawngreen", 0xff7cfc00 }, - { "lemonchiffon", 0xfffffacd }, - { "lightblue", 0xffadd8e6 }, - { "lightcoral", 0xfff08080 }, - { "lightcyan", 0xffe0ffff }, - { "lightgoldenrodyellow", 0xfffafad2 }, - { "lightgray", 0xffd3d3d3 }, - { "lightgrey", 0xffd3d3d3 }, - { "lightgreen", 0xff90ee90 }, - { "lightpink", 0xffffb6c1 }, - { "lightsalmon", 0xffffa07a }, - { "lightseagreen", 0xff20b2aa }, - { "lightskyblue", 0xff87cefa }, - { "lightslategray", 0xff778899 }, - { "lightslategrey", 0xff778899 }, - { "lightsteelblue", 0xffb0c4de }, - { "lightyellow", 0xffffffe0 }, - { "lime", 0xff00ff00 }, - { "limegreen", 0xff32cd32 }, - { "linen", 0xfffaf0e6 }, - { "magenta", 0xffff00ff }, - { "maroon", 0xff800000 }, - { "mediumaquamarine", 0xff66cdaa }, - { "mediumblue", 0xff0000cd }, - { "mediumorchid", 0xffba55d3 }, - { "mediumpurple", 0xff9370d8 }, - { "mediumseagreen", 0xff3cb371 }, - { "mediumslateblue", 0xff7b68ee }, - { "mediumspringgreen", 0xff00fa9a }, - { "mediumturquoise", 0xff48d1cc }, - { "mediumvioletred", 0xffc71585 }, - { "midnightblue", 0xff191970 }, - { "mintcream", 0xfff5fffa }, - { "mistyrose", 0xffffe4e1 }, - { "moccasin", 0xffffe4b5 }, - { "navajowhite", 0xffffdead }, - { "navy", 0xff000080 }, - { "oldlace", 0xfffdf5e6 }, - { "olive", 0xff808000 }, - { "olivedrab", 0xff6b8e23 }, - { "orange", 0xffffa500 }, - { "orangered", 0xffff4500 }, - { "orchid", 0xffda70d6 }, - { "palegoldenrod", 0xffeee8aa }, - { "palegreen", 0xff98fb98 }, - { "paleturquoise", 0xffafeeee }, - { "palevioletred", 0xffd87093 }, - { "papayawhip", 0xffffefd5 }, - { "peachpuff", 0xffffdab9 }, - { "peru", 0xffcd853f }, - { "pink", 0xffffc0cb }, - { "plum", 0xffdda0dd }, - { "powderblue", 0xffb0e0e6 }, - { "purple", 0xff800080 }, - { "red", 0xffff0000 }, - { "rosybrown", 0xffbc8f8f }, - { "royalblue", 0xff4169e1 }, - { "saddlebrown", 0xff8b4513 }, - { "salmon", 0xfffa8072 }, - { "sandybrown", 0xfff4a460 }, - { "seagreen", 0xff2e8b57 }, - { "seashell", 0xfffff5ee }, - { "sienna", 0xffa0522d }, - { "silver", 0xffc0c0c0 }, - { "skyblue", 0xff87ceeb }, - { "slateblue", 0xff6a5acd }, - { "slategray", 0xff708090 }, - { "slategrey", 0xff708090 }, - { "snow", 0xfffffafa }, - { "springgreen", 0xff00ff7f }, - { "steelblue", 0xff4682b4 }, - { "tan", 0xffd2b48c }, - { "teal", 0xff008080 }, - { "thistle", 0xffd8bfd8 }, - { "tomato", 0xffff6347 }, - { "turquoise", 0xff40e0d0 }, - { "violet", 0xffee82ee }, - { "wheat", 0xfff5deb3 }, - { "white", 0xffffffff }, - { "whitesmoke", 0xfff5f5f5 }, - { "yellow", 0xffffff00 }, - { "yellowgreen", 0xff9acd32 } -}; - -static inline void -_to_color(const char *str, int *r, int *g, int *b, Eina_Stringshare** ref) -{ - unsigned int i, len = strlen(str); - char *red, *green, *blue; - unsigned char tr, tg, tb; - - if (len == 4 && str[0] == '#') - { - // case for "#456" should be interprete as "#445566" - if (isxdigit(str[1]) && - isxdigit(str[2]) && - isxdigit(str[3])) - { - char tmp[3] = { '\0', '\0', '\0' }; - tmp[0] = str[1]; tmp[1] = str[1]; *r = strtol(tmp, NULL, 16); - tmp[0] = str[2]; tmp[1] = str[2]; *g = strtol(tmp, NULL, 16); - tmp[0] = str[3]; tmp[1] = str[3]; *b = strtol(tmp, NULL, 16); - } - } - else if (len == 7 && str[0] == '#') - { - if (isxdigit(str[1]) && - isxdigit(str[2]) && - isxdigit(str[3]) && - isxdigit(str[4]) && - isxdigit(str[5]) && - isxdigit(str[6])) - { - char tmp[3] = { '\0', '\0', '\0' }; - tmp[0] = str[1]; tmp[1] = str[2]; *r = strtol(tmp, NULL, 16); - tmp[0] = str[3]; tmp[1] = str[4]; *g = strtol(tmp, NULL, 16); - tmp[0] = str[5]; tmp[1] = str[6]; *b = strtol(tmp, NULL, 16); - } - } - else if (len >= 10 && - (str[0] == 'r' || str[0] == 'R') && - (str[1] == 'g' || str[1] == 'G') && - (str[2] == 'b' || str[2] == 'B') && - str[3] == '(' && - str[len - 1] == ')') - { - tr = _color_parser(str + 4, &red); - if (red && *red == ',') - { - tg = _color_parser(red + 1, &green); - if (green && *green == ',') - { - tb = _color_parser(green + 1, &blue); - if (blue && blue[0] == ')' && blue[1] == '\0') - { - *r = tr; *g = tg; *b = tb; - } - } - } - } - else if (len >= 3 && !strncmp(str, "url",3)) - { - *ref = _id_from_url(str+3); - } - else - { - //handle named color - for (i = 0; i < (sizeof (colors) / sizeof (colors[0])); i++) - if (!strcasecmp(colors[i].name, str)) - { - *r = R_VAL(&(colors[i].value)); - *g = G_VAL(&(colors[i].value)); - *b = B_VAL(&(colors[i].value)); - } - } -} - -static inline char * -parse_numbers_array(char *str, double *points, int *pt_count) -{ - int count = 0; - char *end = NULL; - - str = _skip_space(str, NULL); - while (isdigit(*str) || - *str == '-' || - *str == '+' || - *str == '.') - { - points[count++] = strtod(str, &end); - str = end; - str = _skip_space(str, NULL); - if (*str == ',') - ++str; - //eat the rest of space - str = _skip_space(str, NULL); - } - *pt_count = count; - return str; -} - -typedef enum _Matrix_State -{ - SVG_MATRIX_UNKNOWN, - SVG_MATRIX_MATRIX, - SVG_MATRIX_TRANSLATE, - SVG_MATRIX_ROTATE, - SVG_MATRIX_SCALE, - SVG_MATRIX_SKEWX, - SVG_MATRIX_SKEWY -} Matrix_State; - -#define MATRIX_DEF(Name, Value) \ - { #Name, sizeof (#Name), Value} - -static const struct { - const char *tag; - int sz; - Matrix_State state; -} matrix_tags[] = { - MATRIX_DEF(matrix, SVG_MATRIX_MATRIX), - MATRIX_DEF(translate, SVG_MATRIX_TRANSLATE), - MATRIX_DEF(rotate, SVG_MATRIX_ROTATE), - MATRIX_DEF(scale, SVG_MATRIX_SCALE), - MATRIX_DEF(skewX, SVG_MATRIX_SKEWX), - MATRIX_DEF(skewY, SVG_MATRIX_SKEWY) -}; - -/* parse transform attribute - * https://www.w3.org/TR/SVG/coords.html#TransformAttribute - */ -static Eina_Matrix3 * -_parse_transformation_matrix(const char *value) -{ - unsigned int i; - double points[8]; - int pt_count = 0; - double sx, sy; - Matrix_State state = SVG_MATRIX_UNKNOWN; - Eina_Matrix3 *matrix = calloc(1, sizeof(Eina_Matrix3)); - char *str = (char *)value; - char *end = str + strlen(str); - - eina_matrix3_identity(matrix); - while (str < end) - { - if (isspace(*str) || (*str == ',')) - { - ++str; - continue; - } - for (i = 0; i < sizeof (matrix_tags) / sizeof(matrix_tags[0]); i++) - if (!strncmp(matrix_tags[i].tag, str, matrix_tags[i].sz -1)) - { - state = matrix_tags[i].state; - str += (matrix_tags[i].sz -1); - } - if ( state == SVG_MATRIX_UNKNOWN) - goto error; - - str = _skip_space(str, end); - if (*str != '(') - goto error; - ++str; - str = parse_numbers_array(str, points, &pt_count); - if (*str != ')') - goto error; - ++str; - - if (state == SVG_MATRIX_MATRIX) - { - Eina_Matrix3 tmp; - - if (pt_count != 6) goto error; - - eina_matrix3_identity(&tmp); - eina_matrix3_values_set(&tmp, - points[0], points[2], points[4], - points[1], points[3], points[5], - 0, 0, 1); - eina_matrix3_compose(matrix, &tmp, matrix); - } - else if (state == SVG_MATRIX_TRANSLATE) - { - if (pt_count == 1) - eina_matrix3_translate(matrix, points[0], 0); - else if (pt_count == 2) - eina_matrix3_translate(matrix, points[0], points[1]); - else - goto error; - } - else if (state == SVG_MATRIX_ROTATE) - { - if (pt_count == 1) - { - eina_matrix3_rotate(matrix, points[0] * (M_PI/180.0)); - } - else if (pt_count == 3) - { - eina_matrix3_translate(matrix, points[1], points[2]); - eina_matrix3_rotate(matrix, points[0] * (M_PI/180.0)); - eina_matrix3_translate(matrix, -points[1], -points[2]); - } - else - { - goto error; - } - } - else if (state == SVG_MATRIX_SCALE) - { - if (pt_count < 1 || pt_count > 2) goto error; - - sx = points[0]; - sy = sx; - if (pt_count == 2) - sy = points[1]; - eina_matrix3_scale(matrix, sx, sy); - } - } - error: - return matrix; -} - -#define LENGTH_DEF(Name, Value) \ - { #Name, sizeof (#Name), Value} - -static const struct { - const char *tag; - int sz; - Svg_Length_Type type; -} length_tags[] = { - LENGTH_DEF(%, SVG_LT_PERCENT), - LENGTH_DEF(px, SVG_LT_PX), - LENGTH_DEF(pc, SVG_LT_PC), - LENGTH_DEF(pt, SVG_LT_PT), - LENGTH_DEF(mm, SVG_LT_MM), - LENGTH_DEF(cm, SVG_LT_CM), - LENGTH_DEF(in, SVG_LT_IN) -}; - -static double -parse_length(const char *str, Svg_Length_Type *type) -{ - unsigned int i; - double value; - int sz = strlen(str); - - *type = SVG_LT_PX; - for (i = 0; i < sizeof (length_tags) / sizeof(length_tags[0]); i++) - if (length_tags[i].sz - 1 == sz && !strncmp(length_tags[i].tag, str, sz)) - { - *type = length_tags[i].type; - } - value = strtod(str, NULL); - return value; -} - -static Eina_Bool _parse_style_attr(void *data, const char *key, const char *value); -static Eina_Bool _attr_style_node(void *data, const char *str); - -static Eina_Bool -_attr_parse_svg_node(void *data, const char *key, const char *value) -{ - Svg_Node *node = data; - Svg_Doc_Node *doc = &(node->node.doc); - Svg_Length_Type type; - - // @TODO handle lenght unit. - if (!strcmp(key, "width")) - { - doc->width = parse_length(value, &type); - } - else if (!strcmp(key, "height")) - { - doc->height = parse_length(value, &type); - } - else if (!strcmp(key, "viewBox")) - { - - if (!_parse_number(&value, &doc->vx) && !_parse_number(&value, &doc->vy) && - !_parse_number(&value, &doc->vw) && !_parse_number(&value, &doc->vh)) - { - return EINA_FALSE; - } - } - else if (!strcmp(key, "style")) - { - _attr_style_node(node, value); - } - else - { - _parse_style_attr(node, key, value); - } - return EINA_TRUE; -} - -//https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint -static void -_handle_paint_attr(Svg_Paint* paint, const char *value) -{ - if (!strcmp(value, "none")) - { - // no paint property - paint->none = EINA_TRUE; - return; - } - paint->none = EINA_FALSE; - if (!strcmp(value, "currentColor")) - { - paint->cur_color = EINA_TRUE; - return; - } - _to_color(value, &paint->r, &paint->g, &paint->b, &paint->url); -} - -static void -_handle_color_attr(Svg_Node* node, const char *value) -{ - Svg_Style_Property *style = node->style; - _to_color(value, &style->r, &style->g, &style->b, NULL); -} - -static void -_handle_fill_attr(Svg_Node* node, const char *value) -{ - Svg_Style_Property *style = node->style; - style->fill.flags |= SVG_FILL_FLAGS_PAINT; - _handle_paint_attr(&style->fill.paint, value); -} - -static void -_handle_stroke_attr(Svg_Node* node, const char *value) -{ - Svg_Style_Property *style = node->style; - style->stroke.flags |= SVG_STROKE_FLAGS_PAINT; - _handle_paint_attr(&style->stroke.paint, value); -} - -static void -_handle_stroke_opacity_attr(Svg_Node* node, const char *value) -{ - node->style->stroke.flags |= SVG_STROKE_FLAGS_OPACITY; - node->style->stroke.opacity = _to_opacity(value); -} - -static void -_handle_stroke_width_attr(Svg_Node* node, const char *value) -{ - node->style->stroke.flags |= SVG_STROKE_FLAGS_WIDTH; - node->style->stroke.width = _to_double(value); -} - -static void -_handle_stroke_linecap_attr(Svg_Node* node, const char *value) -{ - node->style->stroke.flags |= SVG_STROKE_FLAGS_CAP; - node->style->stroke.cap = _to_line_cap(value); -} - -static void -_handle_stroke_linejoin_attr(Svg_Node* node, const char *value) -{ - node->style->stroke.flags |= SVG_STROKE_FLAGS_JOIN; - node->style->stroke.join = _to_line_join(value); -} - -static void -_handle_fill_rule_attr(Svg_Node* node, const char *value) -{ - node->style->fill.flags |= SVG_FILL_FLAGS_FILL_RULE; - node->style->fill.fill_rule = _to_fill_rule(value); -} - -static void -_handle_fill_opacity_attr(Svg_Node* node, const char *value) -{ - node->style->fill.flags |= SVG_FILL_FLAGS_OPACITY; - node->style->fill.opacity = _to_opacity(value); -} - -static void -_handle_transform_attr(Svg_Node* node, const char *value) -{ - node->transform = _parse_transformation_matrix(value); -} - - -typedef void (*Style_Method)(Svg_Node *node, const char *value); - -#define STYLE_DEF(Name, Name1) \ - { #Name, sizeof (#Name), _handle_##Name1##_attr} - -static const struct { - const char *tag; - int sz; - Style_Method tag_handler;; -} style_tags[] = { - STYLE_DEF(color, color), - STYLE_DEF(fill, fill), - STYLE_DEF(fill-rule, fill_rule), - STYLE_DEF(fill-opacity, fill_opacity), - STYLE_DEF(stroke, stroke), - STYLE_DEF(stroke-width, stroke_width), - STYLE_DEF(stroke-linejoin, stroke_linejoin), - STYLE_DEF(stroke-linecap, stroke_linecap), - STYLE_DEF(stroke-opacity, stroke_opacity), - STYLE_DEF(transform, transform) -}; - -static Eina_Bool -_parse_style_attr(void *data, const char *key, const char *value) -{ - Svg_Node* node = data; - unsigned int i; - int sz; - - // trim the white space - key = _skip_space(key, NULL); - - value = _skip_space(value, NULL); - - sz = strlen(key); - for (i = 0; i < sizeof (style_tags) / sizeof(style_tags[0]); i++) - if (style_tags[i].sz - 1 == sz && !strncmp(style_tags[i].tag, key, sz)) - { - style_tags[i].tag_handler(node, value); - return EINA_TRUE; - } - - return EINA_TRUE; -} - -static Eina_Bool -_attr_style_node(void *data, const char *str) -{ - eina_simple_xml_attribute_w3c_parse(str, - _parse_style_attr, data); - return EINA_TRUE; -} - -/* parse g node - * https://www.w3.org/TR/SVG/struct.html#Groups - */ -static Eina_Bool -_attr_parse_g_node(void *data, const char *key, const char *value) -{ - Svg_Node *node = data; - - if (!strcmp(key, "style")) - { - return _attr_style_node(node, value); - } - else if (!strcmp(key, "transform")) - { - node->transform = _parse_transformation_matrix(value); - } - else if (!strcmp(key, "id")) - { - node->id = _copy_id(value); - } - else - { - _parse_style_attr(node, key, value); - } - return EINA_TRUE; -} - - -static Svg_Node * -_create_node(Svg_Node *parent, Svg_Node_Type type) -{ - Svg_Node *node = calloc(1, sizeof(Svg_Node)); - - // default fill property - node->style = calloc(1, sizeof(Svg_Style_Property)); - - // update the default value of stroke and fill - //https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint - // default fill color is black - node->style->fill.paint.r = 0; - node->style->fill.paint.g = 0; - node->style->fill.paint.b = 0; - node->style->fill.paint.none = EINA_FALSE; - // default fill opacity is 1 - node->style->fill.opacity = 255; - - // default fill rule is nonzero - node->style->fill.fill_rule = EFL_GFX_FILL_RULE_WINDING; - - // default stroke is none - node->style->stroke.paint.none = EINA_TRUE; - // default stroke opacity is 1 - node->style->stroke.opacity = 255; - // default stroke width is 1 - node->style->stroke.width = 1; - // default line cap is butt - node->style->stroke.cap = EFL_GFX_CAP_BUTT; - // default line join is miter - node->style->stroke.join = EFL_GFX_JOIN_MITER; - node->style->stroke.scale = 1.0; - - node->parent = parent; - node->type = type; - node->child = NULL; - - if (parent) - parent->child = eina_list_append(parent->child, node); - return node; -} - -static Svg_Node * -_create_defs_node(Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, unsigned buflen EINA_UNUSED) -{ - Svg_Node *node = _create_node(NULL, SVG_NODE_DEFS); - eina_simple_xml_attributes_parse(buf, buflen, - NULL, node); - return node; -} - -static Svg_Node * -_create_g_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_G); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_g_node, node); - return node; -} - -static Svg_Node * -_create_svg_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_DOC); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_svg_node, node); - return node; -} - -static Svg_Node * -_create_switch_node(Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, unsigned buflen EINA_UNUSED) -{ - return NULL; -} - -static Eina_Bool -_attr_parse_path_node(void *data, const char *key, const char *value) -{ - Svg_Node *node = data; - Svg_Path_Node *path = &(node->node.path); - - if (!strcmp(key, "d")) - { - path->path = eina_stringshare_add(value); - } - else if (!strcmp(key, "style")) - { - _attr_style_node(node, value); - } - else if (!strcmp(key, "id")) - { - node->id = _copy_id(value); - } - else - { - _parse_style_attr(node, key, value); - } - return EINA_TRUE; -} - -static Svg_Node * -_create_path_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_PATH); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_path_node, node); - return node; -} - -#define CIRCLE_DEF(Name, Field) \ - { #Name, sizeof (#Name), offsetof(Svg_Circle_Node, Field)} - -static const struct { - const char *tag; - int sz; - size_t offset; -} circle_tags[] = { - CIRCLE_DEF(cx, cx), - CIRCLE_DEF(cy, cy), - CIRCLE_DEF(r, r) -}; - -/* parse the attributes for a circle element. - * https://www.w3.org/TR/SVG/shapes.html#CircleElement - */ -static Eina_Bool -_attr_parse_circle_node(void *data, const char *key, const char *value) -{ - Svg_Node *node = data; - Svg_Circle_Node *circle = &(node->node.circle); - unsigned int i; - unsigned char *array; - int sz = strlen(key); - - array = (unsigned char*) circle; - for (i = 0; i < sizeof (circle_tags) / sizeof(circle_tags[0]); i++) - if (circle_tags[i].sz - 1 == sz && !strncmp(circle_tags[i].tag, key, sz)) - { - *((double*) (array + circle_tags[i].offset)) = _to_double(value); - return EINA_TRUE; - } - - if (!strcmp(key, "style")) - { - _attr_style_node(node, value); - } - else if (!strcmp(key, "id")) - { - node->id = _copy_id(value); - } - else - { - _parse_style_attr(node, key, value); - } - return EINA_TRUE; -} - -static Svg_Node * -_create_circle_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_CIRCLE); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_circle_node, node); - return node; -} - -#define ELLIPSE_DEF(Name, Field) \ - { #Name, sizeof (#Name), offsetof(Svg_Ellipse_Node, Field)} - -static const struct { - const char *tag; - int sz; - size_t offset; -} ellipse_tags[] = { - ELLIPSE_DEF(cx,cx), - ELLIPSE_DEF(cy,cy), - ELLIPSE_DEF(rx,rx), - ELLIPSE_DEF(ry,ry) -}; - -/* parse the attributes for an ellipse element. - * https://www.w3.org/TR/SVG/shapes.html#EllipseElement - */ -static Eina_Bool -_attr_parse_ellipse_node(void *data, const char *key, const char *value) -{ - Svg_Node *node = data; - Svg_Ellipse_Node *ellipse = &(node->node.ellipse); - unsigned int i; - unsigned char *array; - int sz = strlen(key); - - array = (unsigned char*) ellipse; - for (i = 0; i < sizeof (ellipse_tags) / sizeof(ellipse_tags[0]); i++) - if (ellipse_tags[i].sz - 1 == sz && !strncmp(ellipse_tags[i].tag, key, sz)) - { - *((double*) (array + ellipse_tags[i].offset)) = _to_double(value); - return EINA_TRUE; - } - - if (!strcmp(key, "id")) - { - node->id = _copy_id(value); - } - else if (!strcmp(key, "style")) - { - _attr_style_node(node, value); - } - else - { - _parse_style_attr(node, key, value); - } - return EINA_TRUE; -} - -static Svg_Node * -_create_ellipse_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_ELLIPSE); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_ellipse_node, node); - return node; -} - -static void -_attr_parse_polygon_points(const char *str, double **points, int *point_count) -{ - double tmp[50]; - int tmp_count=0; - int count = 0; - double num; - double *point_array = NULL, *tmp_array; - - while (_parse_number(&str, &num)) - { - tmp[tmp_count++] = num; - if (tmp_count == 50) - { - tmp_array = realloc(point_array, (count + tmp_count) * sizeof(double)); - if (!tmp_array) goto error_alloc; - point_array = tmp_array; - memcpy(&point_array[count], tmp, tmp_count * sizeof(double)); - count += tmp_count; - tmp_count = 0; - } - } - - if (tmp_count > 0) - { - tmp_array = realloc(point_array, (count + tmp_count) * sizeof(double)); - if (!tmp_array) goto error_alloc; - point_array = tmp_array; - memcpy(&point_array[count], tmp, tmp_count * sizeof(double)); - count += tmp_count; - } - *point_count = count; - *points = point_array; - return; - -error_alloc: - ERR("allocation for point array failed. out of memory"); - abort(); -} - -/* parse the attributes for a polygon element. - * https://www.w3.org/TR/SVG/shapes.html#PolylineElement - */ -static Eina_Bool -_attr_parse_polygon_node(void *data, const char *key, const char *value) -{ - Svg_Node *node = data; - Svg_Polygon_Node *polygon = NULL; - - if (node->type == SVG_NODE_POLYGON) - polygon = &(node->node.polygon); - else - polygon = &(node->node.polyline); - - - if (!strcmp(key, "points")) - { - _attr_parse_polygon_points(value, &polygon->points, &polygon->points_count); - } - else if (!strcmp(key, "style")) - { - _attr_style_node(node, value); - } - else if (!strcmp(key, "id")) - { - node->id = _copy_id(value); - } - else - { - _parse_style_attr(node, key, value); - } - return EINA_TRUE; -} - -static Svg_Node * -_create_polygon_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_POLYGON); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_polygon_node, node); - return node; -} - -static Svg_Node * -_create_polyline_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_POLYLINE); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_polygon_node, node); - return node; -} - -#define RECT_DEF(Name, Field) \ - { #Name, sizeof (#Name), offsetof(Svg_Rect_Node, Field)} - -static const struct { - const char *tag; - int sz; - size_t offset; -} rect_tags[] = { - RECT_DEF(x,x), - RECT_DEF(y, y), - RECT_DEF(width, w), - RECT_DEF(height, h), - RECT_DEF(rx, rx), - RECT_DEF(ry, ry) -}; - -/* parse the attributes for a rect element. - * https://www.w3.org/TR/SVG/shapes.html#RectElement - */ -static Eina_Bool -_attr_parse_rect_node(void *data, const char *key, const char *value) -{ - Svg_Node *node = data; - Svg_Rect_Node *rect = & (node->node.rect); - unsigned int i; - unsigned char *array; - int sz = strlen(key); - - array = (unsigned char*) rect; - for (i = 0; i < sizeof (rect_tags) / sizeof(rect_tags[0]); i++) - if (rect_tags[i].sz - 1 == sz && !strncmp(rect_tags[i].tag, key, sz)) - { - *((double*) (array + rect_tags[i].offset)) = _to_double(value); - return EINA_TRUE; - } - - if (!strcmp(key, "id")) - { - node->id = _copy_id(value); - } - else if (!strcmp(key, "style")) - { - _attr_style_node(node, value); - } - else - { - _parse_style_attr(node, key, value); - } - - if (!EINA_DBL_EQ(rect->rx, 0) && EINA_DBL_EQ(rect->ry, 0)) rect->ry = rect->rx; - if (!EINA_DBL_EQ(rect->ry, 0) && EINA_DBL_EQ(rect->rx, 0)) rect->rx = rect->ry; - - return EINA_TRUE; -} - -static Svg_Node * -_create_rect_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_RECT); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_rect_node, node); - return node; -} - -static Eina_Stringshare * -_id_from_href(const char *href) -{ - href = _skip_space(href, NULL); - if ((*href) == '#') - href++; - return eina_stringshare_add(href); -} - -static Svg_Node* -_get_defs_node(Svg_Node *node) -{ - if (!node) return NULL; - - while (node->parent != NULL) - { - node = node->parent; - } - - if (node->type == SVG_NODE_DOC) - return node->node.doc.defs; - - return NULL; -} - -static Svg_Node* -_find_child_by_id(Svg_Node *node, const char *id) -{ - Eina_List *l; - Svg_Node *child; - - if (!node) return NULL; - - EINA_LIST_FOREACH(node->child, l, child) - { - if ((child->id != NULL) && !strcmp(child->id, id)) - return child; - } - return NULL; -} - -static Eina_List * -_clone_grad_stops(Eina_List *from) -{ - Efl_Gfx_Gradient_Stop *stop; - Eina_List *l; - Eina_List *res = NULL; - - EINA_LIST_FOREACH(from, l, stop) - { - Efl_Gfx_Gradient_Stop *new_stop; - - new_stop = calloc(1, sizeof(Efl_Gfx_Gradient_Stop)); - memcpy(new_stop, stop, sizeof(Efl_Gfx_Gradient_Stop)); - res = eina_list_append(res, new_stop); - } - - return res; -} - -static Svg_Style_Gradient * -_clone_gradient(Svg_Style_Gradient *from) -{ - Svg_Style_Gradient *grad; - - if (!from) return NULL; - - grad= calloc(1, sizeof(Svg_Style_Gradient)); - grad->type = from->type; - grad->id = _copy_id(from->id); - grad->ref = _copy_id(from->ref); - grad->spread = from->spread; - grad->stops = _clone_grad_stops(from->stops); - if (grad->type == SVG_LINEAR_GRADIENT) - { - grad->linear = calloc(1, sizeof(Svg_Linear_Gradient)); - memcpy(grad->linear, from->linear, sizeof(Svg_Linear_Gradient)); - } - else if (grad->type == SVG_RADIAL_GRADIENT) - { - grad->radial = calloc(1, sizeof(Svg_Radial_Gradient)); - memcpy(grad->radial, from->radial, sizeof(Svg_Radial_Gradient)); - } - - return grad; -} - -static void -_copy_attribute(Svg_Node *to, Svg_Node *from) -{ - // copy matrix attribute - if (from->transform) - { - to->transform = calloc(1, sizeof(Eina_Matrix3)); - eina_matrix3_copy(to->transform, from->transform); - } - // copy style attribute; - memcpy(to->style, from->style, sizeof(Svg_Style_Property)); - - // copy node attribute - switch (from->type) - { - case SVG_NODE_CIRCLE: - to->node.circle.cx = from->node.circle.cx; - to->node.circle.cy = from->node.circle.cy; - to->node.circle.r = from->node.circle.r; - break; - case SVG_NODE_ELLIPSE: - to->node.ellipse.cx = from->node.ellipse.cx; - to->node.ellipse.cy = from->node.ellipse.cy; - to->node.ellipse.rx = from->node.ellipse.rx; - to->node.ellipse.ry = from->node.ellipse.ry; - break; - case SVG_NODE_RECT: - to->node.rect.x = from->node.rect.x; - to->node.rect.y = from->node.rect.y; - to->node.rect.w = from->node.rect.w; - to->node.rect.h = from->node.rect.h; - to->node.rect.rx = from->node.rect.rx; - to->node.rect.ry = from->node.rect.ry; - break; - case SVG_NODE_PATH: - to->node.path.path = eina_stringshare_add(from->node.path.path); - break; - case SVG_NODE_POLYGON: - to->node.polygon.points_count = from->node.polygon.points_count; - to->node.polygon.points = calloc(to->node.polygon.points_count, sizeof(double)); - break; - case SVG_NODE_POLYLINE: - to->node.polyline.points_count = from->node.polyline.points_count; - to->node.polyline.points = calloc(to->node.polyline.points_count, sizeof(double)); - break; - default: - break; - } - -} - -static void -_clone_node(Svg_Node *from, Svg_Node *parent) -{ - Svg_Node *new_node; - Eina_List *l; - Svg_Node *child; - - if (!from) return; - - new_node = _create_node(parent, from->type); - _copy_attribute(new_node, from); - - EINA_LIST_FOREACH(from->child, l, child) - { - _clone_node(child, new_node); - } - -} - -static Eina_Bool -_attr_parse_use_node(void *data, const char *key, const char *value) -{ - Svg_Node *defs, *node_from, *node = data; - Eina_Stringshare *id; - - if (!strcmp(key, "xlink:href")) - { - id = _id_from_href(value); - defs = _get_defs_node(node); - node_from = _find_child_by_id(defs, id); - _clone_node(node_from, node); - eina_stringshare_del(id); - } - else - { - _attr_parse_g_node(data, key, value); - } - return EINA_TRUE; -} - -static Svg_Node * -_create_use_node(Svg_Node *parent, const char *buf, unsigned buflen) -{ - Svg_Node *node = _create_node(parent, SVG_NODE_G); - - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_use_node, node); - return node; -} - -#define TAG_DEF(Name) \ - { #Name, sizeof (#Name), _create_##Name##_node } - -static const struct { - const char *tag; - int sz; - Factory_Method tag_handler; -} graphics_tags[] = { - TAG_DEF(use), - TAG_DEF(circle), - TAG_DEF(ellipse), - TAG_DEF(path), - TAG_DEF(polygon), - TAG_DEF(rect), - TAG_DEF(polyline), -}; - -static const struct { - const char *tag; - int sz; - Factory_Method tag_handler; -} group_tags[] = { - TAG_DEF(defs), - TAG_DEF(g), - TAG_DEF(svg), - TAG_DEF(switch) -}; - -#define FIND_FACTORY(Short_Name, Tags_Array) \ - static Factory_Method \ - _find_##Short_Name##_factory(const char *name) \ - { \ - unsigned int i; \ - int sz = strlen(name); \ - \ - for (i = 0; i < sizeof (Tags_Array) / sizeof(Tags_Array[0]); i++) \ - if (Tags_Array[i].sz - 1 == sz && !strncmp(Tags_Array[i].tag, name, sz)) \ - { \ - return Tags_Array[i].tag_handler; \ - } \ - return NULL; \ - } - -FIND_FACTORY(group, group_tags); -FIND_FACTORY(graphics, graphics_tags); - -Efl_Gfx_Gradient_Spread -_parse_spread_value(const char *value) -{ - Efl_Gfx_Gradient_Spread spread = EFL_GFX_GRADIENT_SPREAD_PAD; - - if (!strcmp(value, "reflect")) - { - spread = EFL_GFX_GRADIENT_SPREAD_REFLECT; - } - else if (!strcmp(value, "repeat")) - { - spread = EFL_GFX_GRADIENT_SPREAD_REPEAT; - } - - return spread; -} - -static void -_handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value) -{ - radial->cx = _to_double(value); -} - -static void -_handle_radial_cy_attr(Svg_Radial_Gradient* radial, const char *value) -{ - radial->cy = _to_double(value); -} - -static void -_handle_radial_fx_attr(Svg_Radial_Gradient* radial, const char *value) -{ - radial->fx = _to_double(value); -} - -static void -_handle_radial_fy_attr(Svg_Radial_Gradient* radial, const char *value) -{ - radial->fy = _to_double(value); -} - -static void -_handle_radial_r_attr(Svg_Radial_Gradient* radial, const char *value) -{ - radial->r = _to_double(value); -} - - -typedef void (*Radial_Method)(Svg_Radial_Gradient *radial, const char *value); - -#define RADIAL_DEF(Name) \ - { #Name, sizeof (#Name), _handle_radial_##Name##_attr} - -static const struct { - const char *tag; - int sz; - Radial_Method tag_handler;; -} radial_tags[] = { - RADIAL_DEF(cx), - RADIAL_DEF(cy), - RADIAL_DEF(fx), - RADIAL_DEF(fy), - RADIAL_DEF(r) -}; - -static Eina_Bool -_attr_parse_radial_gradient_node(void *data, const char *key, const char *value) -{ - Svg_Style_Gradient *grad = data; - Svg_Radial_Gradient *radial = grad->radial; - unsigned int i; - int sz = strlen(key); - - for (i = 0; i < sizeof (radial_tags) / sizeof(radial_tags[0]); i++) - if (radial_tags[i].sz - 1 == sz && !strncmp(radial_tags[i].tag, key, sz)) - { - radial_tags[i].tag_handler(radial, value); - return EINA_TRUE; - } - - if (!strcmp(key, "id")) - { - grad->id = _copy_id(value); - } - else if (!strcmp(key, "spreadMethod")) - { - grad->spread = _parse_spread_value(value); - } - else if (!strcmp(key, "xlink:href")) - { - grad->ref = _id_from_href(value); - } - - return EINA_TRUE; -} - -static Svg_Style_Gradient * -_create_radialGradient(const char *buf, unsigned buflen) -{ - Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient)); - - grad->type = SVG_RADIAL_GRADIENT; - grad->radial = calloc(1, sizeof(Svg_Radial_Gradient)); - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_radial_gradient_node, grad); - return grad; - -} - -static Eina_Bool -_attr_parse_stops(void *data, const char *key, const char *value) -{ - Efl_Gfx_Gradient_Stop *stop = data; - - if (!strcmp(key, "offset")) - { - stop->offset = _to_double(value); - } - else if (!strcmp(key, "stop-opacity")) - { - stop->a = _to_opacity(value); - } - else if (!strcmp(key, "stop-color")) - { - _to_color(value, &stop->r, &stop->g, &stop->b, NULL); - } - else if (!strcmp(key, "style")) - { - eina_simple_xml_attribute_w3c_parse(value, - _attr_parse_stops, data); - } - - return EINA_TRUE; -} - -static void -_handle_linear_x1_attr(Svg_Linear_Gradient* linear, const char *value) -{ - linear->x1 = _to_double(value); -} - -static void -_handle_linear_y1_attr(Svg_Linear_Gradient* linear, const char *value) -{ - linear->y1 = _to_double(value); -} - -static void -_handle_linear_x2_attr(Svg_Linear_Gradient* linear, const char *value) -{ - linear->x2 = _to_double(value); -} - -static void -_handle_linear_y2_attr(Svg_Linear_Gradient* linear, const char *value) -{ - linear->y2 = _to_double(value); -} - - -typedef void (*Linear_Method)(Svg_Linear_Gradient *linear, const char *value); - -#define LINEAR_DEF(Name) \ - { #Name, sizeof (#Name), _handle_linear_##Name##_attr} - -static const struct { - const char *tag; - int sz; - Linear_Method tag_handler;; -} linear_tags[] = { - LINEAR_DEF(x1), - LINEAR_DEF(y1), - LINEAR_DEF(x2), - LINEAR_DEF(y2) -}; - -static Eina_Bool -_attr_parse_linear_gradient_node(void *data, const char *key, const char *value) -{ - Svg_Style_Gradient *grad = data; - Svg_Linear_Gradient *linear = grad->linear; - unsigned int i; - int sz = strlen(key); - - for (i = 0; i < sizeof (linear_tags) / sizeof(linear_tags[0]); i++) - if (linear_tags[i].sz - 1 == sz && !strncmp(linear_tags[i].tag, key, sz)) - { - linear_tags[i].tag_handler(linear, value); - return EINA_TRUE; - } - - if (!strcmp(key, "id")) - { - grad->id = _copy_id(value); - } - else if (!strcmp(key, "spreadMethod")) - { - grad->spread = _parse_spread_value(value); - } - else if (!strcmp(key, "xlink:href")) - { - grad->ref = _id_from_href(value); - } - - return EINA_TRUE; -} - -static Svg_Style_Gradient * -_create_linearGradient(const char *buf, unsigned buflen) -{ - Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient)); - - grad->type = SVG_LINEAR_GRADIENT; - grad->linear = calloc(1, sizeof(Svg_Linear_Gradient)); - eina_simple_xml_attributes_parse(buf, buflen, - _attr_parse_linear_gradient_node, grad); - return grad; - -} - -#define GRADIENT_DEF(Name) \ - { #Name, sizeof (#Name), _create_##Name } - -static const struct { - const char *tag; - int sz; - Gradient_Factory_Method tag_handler; -} gradient_tags[] = { - GRADIENT_DEF(linearGradient), - GRADIENT_DEF(radialGradient) -}; - -static Gradient_Factory_Method -_find_gradient_factory(const char *name) -{ - unsigned int i; - int sz = strlen(name); - - for (i = 0; i < sizeof (gradient_tags) / sizeof(gradient_tags[0]); i++) - if (gradient_tags[i].sz - 1 == sz && !strncmp(gradient_tags[i].tag, name, sz)) - { - return gradient_tags[i].tag_handler; - } - return NULL; -} - -static void -_evas_svg_loader_xml_open_parser(Evas_SVG_Loader *loader, - const char *content, unsigned int length) -{ - const char *attrs = NULL; - int attrs_length = 0; - int sz = length; - char tag_name[20] = ""; - Factory_Method method; - Gradient_Factory_Method gradient_method; - Svg_Node *node = NULL, *parent; - loader->level++; - attrs = eina_simple_xml_tag_attributes_find(content, length); - - if (!attrs) - { - // parse the empty tag - attrs = content; - while ((attrs != NULL) && *attrs != '>') - attrs++; - } - - if (attrs) - { - // find out the tag name starting from content till sz length - sz = attrs - content; - attrs_length = length - sz; - while ((sz > 0) && (isspace(content[sz - 1]))) - sz--; - strncpy(tag_name, content, sz); - tag_name[sz] = '\0'; - } - - if ((method = _find_group_factory(tag_name))) - { - //group - if (!loader->doc) - { - if (strcmp(tag_name, "svg")) - return; // Not a valid svg document - node = method(NULL, attrs, attrs_length); - loader->doc = node; - } - else - { - parent = eina_array_data_get(loader->stack, eina_array_count(loader->stack) - 1); - node = method(parent, attrs, attrs_length); - } - eina_array_push(loader->stack, node); - - if (node->type == SVG_NODE_DEFS) - { - loader->doc->node.doc.defs = node; - loader->def = node; - } - } - else if ((method = _find_graphics_factory(tag_name))) - { - parent = eina_array_data_get(loader->stack, eina_array_count(loader->stack) - 1); - node = method(parent, attrs, attrs_length); - } - else if ((gradient_method = _find_gradient_factory(tag_name))) - { - Svg_Style_Gradient *gradient; - gradient = gradient_method(attrs, attrs_length); - if (loader->doc->node.doc.defs) - { - loader->def->node.defs.gradients = eina_list_append(loader->def->node.defs.gradients, gradient); - } - loader->gradient = gradient; - } - else if (!strcmp(tag_name, "stop")) - { - Efl_Gfx_Gradient_Stop *stop = calloc(1, sizeof(Efl_Gfx_Gradient_Stop)); - eina_simple_xml_attributes_parse(attrs, attrs_length, - _attr_parse_stops, stop); - if (loader->gradient) - loader->gradient->stops = eina_list_append(loader->gradient->stops, stop); - } - -} - -#define POP_TAG(Tag) \ - { #Tag, sizeof (#Tag) } - -static const struct { - const char *tag; - size_t sz; -} pop_array[] = { - POP_TAG(g), - POP_TAG(svg), - POP_TAG(defs) -}; - -static void -_evas_svg_loader_xml_close_parser(Evas_SVG_Loader *loader, - const char *content, - unsigned int length EINA_UNUSED) -{ - unsigned int i; - - content = _skip_space(content, NULL); - - for (i = 0; i < sizeof (pop_array) / sizeof (pop_array[0]); i++) - if (!strncmp(content, pop_array[i].tag, pop_array[i].sz - 1)) - { - eina_array_pop(loader->stack); - break ; - } - - loader->level--; -} - -static Eina_Bool -_evas_svg_loader_parser(void *data, Eina_Simple_XML_Type type, - const char *content, - unsigned int offset EINA_UNUSED, unsigned int length) -{ - Evas_SVG_Loader *loader = data; - - switch (type) - { - case EINA_SIMPLE_XML_OPEN: - _evas_svg_loader_xml_open_parser(loader, content, length); - break; - case EINA_SIMPLE_XML_OPEN_EMPTY: - _evas_svg_loader_xml_open_parser(loader, content, length); - break; - case EINA_SIMPLE_XML_CLOSE: - _evas_svg_loader_xml_close_parser(loader, content, length); - break; - case EINA_SIMPLE_XML_DATA: - case EINA_SIMPLE_XML_CDATA: - case EINA_SIMPLE_XML_DOCTYPE_CHILD: - break; - case EINA_SIMPLE_XML_IGNORED: - case EINA_SIMPLE_XML_COMMENT: - case EINA_SIMPLE_XML_DOCTYPE: - break; - - default: - break; - } - - return EINA_TRUE; -} - -static void -_inherit_style(Svg_Style_Property *child, Svg_Style_Property *parent) -{ - if (parent == NULL) - return; - // inherit the property of parent if not present in child. - // fill - if (!(child->fill.flags & SVG_FILL_FLAGS_PAINT)) - { - child->fill.paint.r = parent->fill.paint.r; - child->fill.paint.g = parent->fill.paint.g; - child->fill.paint.b = parent->fill.paint.b; - child->fill.paint.none = parent->fill.paint.none; - child->fill.paint.cur_color = parent->fill.paint.cur_color; - child->fill.paint.url = _copy_id(parent->fill.paint.url); - } - if (!(child->fill.flags & SVG_FILL_FLAGS_OPACITY)) - { - child->fill.opacity = parent->fill.opacity; - } - if (!(child->fill.flags & SVG_FILL_FLAGS_FILL_RULE)) - { - child->fill.fill_rule = parent->fill.fill_rule; - } - // stroke - if (!(child->stroke.flags & SVG_STROKE_FLAGS_PAINT)) - { - child->stroke.paint.r = parent->stroke.paint.r; - child->stroke.paint.g = parent->stroke.paint.g; - child->stroke.paint.b = parent->stroke.paint.b; - child->stroke.paint.none = parent->stroke.paint.none; - child->stroke.paint.cur_color = parent->stroke.paint.cur_color; - child->stroke.paint.url = _copy_id(parent->stroke.paint.url); - } - if (!(child->stroke.flags & SVG_STROKE_FLAGS_OPACITY)) - { - child->stroke.opacity = parent->stroke.opacity; - } - if (!(child->stroke.flags & SVG_STROKE_FLAGS_WIDTH)) - { - child->stroke.width = parent->stroke.width; - } - if (!(child->stroke.flags & SVG_STROKE_FLAGS_CAP)) - { - child->stroke.cap = parent->stroke.cap; - } - if (!(child->stroke.flags & SVG_STROKE_FLAGS_JOIN)) - { - child->stroke.join = parent->stroke.join; - } -} - -void -_update_style(Svg_Node *node, Svg_Style_Property *parent_style) -{ - Eina_List *l; - Svg_Node *child; - - _inherit_style(node->style, parent_style); - - EINA_LIST_FOREACH(node->child, l, child) - { - _update_style(child, node->style); - } -} - -static Svg_Style_Gradient* -_dup_gradient(Eina_List *grad_list, const char *id) -{ - Svg_Style_Gradient *grad; - Svg_Style_Gradient *result = NULL; - Eina_List *l; - - EINA_LIST_FOREACH(grad_list, l, grad) - { - if (!strcmp(grad->id, id)) - { - result = _clone_gradient(grad); - break; - } - } - - if (result && result->ref) - { - EINA_LIST_FOREACH(grad_list, l, grad) - { - if (!strcmp(grad->id, result->ref)) - { - if (!result->stops) - { - result->stops = _clone_grad_stops(grad->stops); - } - //TODO properly inherit other property - break; - } - } - } - - return result; -} - -void -_update_gradient(Svg_Node *node, Eina_List *grad_list) -{ - Eina_List *l; - Svg_Node *child; - - if (node->child) - { - EINA_LIST_FOREACH(node->child, l, child) - { - _update_gradient(child, grad_list); - } - } - else - { - if (node->style->fill.paint.url) - { - node->style->fill.paint.gradient = _dup_gradient(grad_list, node->style->fill.paint.url); - } - else if (node->style->stroke.paint.url) - { - node->style->stroke.paint.gradient = _dup_gradient(grad_list, node->style->stroke.paint.url); - } - } -} - -EAPI Svg_Node * -_svg_load(Eina_File *f, const char *key EINA_UNUSED) -{ - Evas_SVG_Loader loader = { - NULL, NULL, NULL, NULL, 0, EINA_FALSE - }; - const char *content; - unsigned int length; - Svg_Node *defs; - - if (!f) return NULL; - - length = eina_file_size_get(f); - content = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); - if (content) - { - loader.stack = eina_array_new(8); - eina_simple_xml_parse(content, length, EINA_TRUE, - _evas_svg_loader_parser, &loader); - - eina_array_free(loader.stack); - eina_file_map_free(f, (void*) content); - } - - if (loader.doc) - { - _update_style(loader.doc, NULL); - defs = loader.doc->node.doc.defs; - if (defs) - _update_gradient(loader.doc, defs->node.defs.gradients); - } - - return loader.doc; -} diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index a11fd07df6..13f94fc51d 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -89,429 +89,6 @@ Eet_Data_Descriptor *_edje_edd_edje_part_description_vector = NULL; Eet_Data_Descriptor *_edje_edd_edje_part_description_vector_pointer = NULL; -Eet_Data_Descriptor *_edje_edd_edje_rect_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_circle_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_ellipse_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_gradient_stops_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_linear_gradient_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_radial_gradient_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_style_gradient_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_style_property_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_matrix3_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_doc_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_defs_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_g_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_arc_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_path_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_polygon_node = NULL; -Eet_Data_Descriptor *_edje_edd_edje_vg_node = NULL; - -#define FREE_DESCRIPTOR(eed) \ - if (eed) \ - { \ - eet_data_descriptor_free((eed)); \ - (eed) = NULL; \ - } - - -static inline Eet_Data_Descriptor* -_eet_for_rect_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Rect_Node); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Rect_Node, "x", x, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Rect_Node, "y", y, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Rect_Node, "w", w, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Rect_Node, "h", h, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Rect_Node, "rx", rx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Rect_Node, "ry", ry, EET_T_DOUBLE); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_circle_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Circle_Node); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Circle_Node, "cx", cx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Circle_Node, "cy", cy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Circle_Node, "r", r, EET_T_DOUBLE); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_ellipse_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Ellipse_Node); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Ellipse_Node, "cx", cx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Ellipse_Node, "cy", cy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Ellipse_Node, "rx", rx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Ellipse_Node, "ry", ry, EET_T_DOUBLE); - return eet; -} - - -static inline Eet_Data_Descriptor* -_eet_for_gradient_stops(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Efl_Gfx_Gradient_Stop); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Efl_Gfx_Gradient_Stop, "offset", offset, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Efl_Gfx_Gradient_Stop, "r", r, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Efl_Gfx_Gradient_Stop, "g", g, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Efl_Gfx_Gradient_Stop, "b", b, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Efl_Gfx_Gradient_Stop, "a", a, EET_T_INT); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_linear_gradient(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Linear_Gradient); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Linear_Gradient, "x1", x1, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Linear_Gradient, "y1", y1, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Linear_Gradient, "x2", x2, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Linear_Gradient, "y2", y2, EET_T_DOUBLE); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_radial_gradient(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Radial_Gradient); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Radial_Gradient, "cx", cx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Radial_Gradient, "cy", cy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Radial_Gradient, "fx", fx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Radial_Gradient, "fy", fy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Radial_Gradient, "r", r, EET_T_DOUBLE); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_style_gradient(void) -{ - Eet_Data_Descriptor_Class eetc; - - if (_edje_edd_edje_style_gradient_node) return _edje_edd_edje_style_gradient_node; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Style_Gradient); - _edje_edd_edje_style_gradient_node = eet_data_descriptor_stream_new(&eetc); - _edje_edd_edje_gradient_stops_node = _eet_for_gradient_stops(); - _edje_edd_edje_linear_gradient_node = _eet_for_linear_gradient(); - _edje_edd_edje_radial_gradient_node = _eet_for_radial_gradient(); - - EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style_gradient_node, Svg_Style_Gradient, "type", type, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style_gradient_node, Svg_Style_Gradient, "id", id, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style_gradient_node, Svg_Style_Gradient, "spread", spread, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_style_gradient_node, Svg_Style_Gradient, "stops", stops, _edje_edd_edje_gradient_stops_node); - EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_style_gradient_node, Svg_Style_Gradient, "radial", radial, _edje_edd_edje_radial_gradient_node); - EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_style_gradient_node, Svg_Style_Gradient, "linear", linear, _edje_edd_edje_linear_gradient_node); - - return _edje_edd_edje_style_gradient_node; -} - -static inline Eet_Data_Descriptor* -_eet_for_style_property(void) -{ - Eet_Data_Descriptor *eet, *eet_gradient, *eet_dash; - Eet_Data_Descriptor_Class eetc, eetc_dash; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Style_Property); - eet = eet_data_descriptor_stream_new(&eetc); - eet_gradient = _eet_for_style_gradient(); - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc_dash, Efl_Gfx_Dash); - eet_dash = eet_data_descriptor_stream_new(&eetc_dash); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet_dash, Efl_Gfx_Dash, "length", length, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet_dash, Efl_Gfx_Dash, "gap", gap, EET_T_DOUBLE); - - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "r", r, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "g", g, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "b", b, EET_T_INT); - // for fill - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.flags", fill.flags, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.r", fill.paint.r, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.g", fill.paint.g, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.b", fill.paint.b, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.none", fill.paint.none, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.cur_color", fill.paint.cur_color, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_SUB(eet, Svg_Style_Property, "fill.paint.gradient", fill.paint.gradient, eet_gradient); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.url", fill.paint.url, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.opacity", fill.opacity, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.fill_rule", fill.fill_rule, EET_T_INT); - - // for stroke - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.flags", stroke.flags, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.r", stroke.paint.r, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.g", stroke.paint.g, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.b", stroke.paint.b, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.none", stroke.paint.none, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.cur_color", stroke.paint.cur_color, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_SUB(eet, Svg_Style_Property, "stroke.paint.gradient", stroke.paint.gradient, eet_gradient); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.paint.url", stroke.paint.url, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.opacity", stroke.opacity, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.scale", stroke.scale, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.width", stroke.width, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.centered", stroke.centered, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.cap", stroke.cap, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.join", stroke.join, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(eet, Svg_Style_Property, "stroke.dash", stroke.dash, eet_dash); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.dash_count", stroke.dash_count, EET_T_INT); - - return eet; -} - -static Eet_Data_Descriptor* -_eet_for_eina_matrix3(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Eina_Matrix3); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "xx", xx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "xy", xy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "xz", xz, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "yx", yx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "yy", yy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "yz", yz, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "zx", zx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "zy", zy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Eina_Matrix3, "zz", zz, EET_T_DOUBLE); - - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_doc_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Doc_Node); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Doc_Node, "width", width, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Doc_Node, "height", height, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Doc_Node, "vx", vx, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Doc_Node, "vy", vy, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Doc_Node, "vw", vw, EET_T_DOUBLE); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Doc_Node, "vh", vh, EET_T_DOUBLE); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_defs_node(void) -{ - Eet_Data_Descriptor *eet, *eet_gradient; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Defs_Node); - eet = eet_data_descriptor_stream_new(&eetc); - eet_gradient = _eet_for_style_gradient(); - - EET_DATA_DESCRIPTOR_ADD_LIST(eet, Svg_Defs_Node, "gradients", gradients, eet_gradient); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_g_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_G_Node); - eet = eet_data_descriptor_stream_new(&eetc); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_arc_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Arc_Node); - eet = eet_data_descriptor_stream_new(&eetc); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_polygon_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Polygon_Node); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Polygon_Node, "points_count", points_count, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC_VAR_ARRAY(eet, Svg_Polygon_Node, "points", points, EET_T_DOUBLE); - return eet; -} - -static inline Eet_Data_Descriptor* -_eet_for_path_node(void) -{ - Eet_Data_Descriptor *eet; - Eet_Data_Descriptor_Class eetc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Path_Node); - eet = eet_data_descriptor_stream_new(&eetc); - EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Path_Node, "path", path, EET_T_STRING); - return eet; -} - -struct -{ - Svg_Node_Type u; - const char *name; -} eet_mapping[] = { - { SVG_NODE_DOC, "doc" }, - { SVG_NODE_G, "g" }, - { SVG_NODE_DEFS, "defs" }, - { SVG_NODE_ARC, "arc" }, - { SVG_NODE_CIRCLE, "circle" }, - { SVG_NODE_ELLIPSE, "ellipse" }, - { SVG_NODE_POLYGON, "polygon" }, - { SVG_NODE_POLYLINE, "polyline" }, - { SVG_NODE_RECT, "rect" }, - { SVG_NODE_PATH, "path" }, - { SVG_NODE_UNKNOWN, NULL } -}; - -static const char * -/* union - type_get() */ -_union_type_get(const void *data, - Eina_Bool *unknow) -{ - const Svg_Node_Type *u = data; - int i; - - if (unknow) - *unknow = EINA_FALSE; - - for (i = 0; eet_mapping[i].name != NULL; ++i) - if (*u == eet_mapping[i].u) - return eet_mapping[i].name; - - if (unknow) - *unknow = EINA_TRUE; - return NULL; -} /* _union_type_get */ - -static Eina_Bool -_union_type_set(const char *type, - void *data, - Eina_Bool unknow) -{ - Svg_Node_Type *u = data; - int i; - - if (unknow) - return EINA_FALSE; - - for (i = 0; eet_mapping[i].name != NULL; ++i) - if (strcmp(eet_mapping[i].name, type) == 0) - { - *u = eet_mapping[i].u; - return EINA_TRUE; - } - return EINA_FALSE; -} /* _union_type_set */ - -EAPI Eet_Data_Descriptor * -_edje_svg_node_eet(void) -{ - Eet_Data_Descriptor *eet_union; - Eet_Data_Descriptor_Class eetc; - - if (_edje_edd_edje_vg_node) return _edje_edd_edje_vg_node; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eetc, Svg_Node); - _edje_edd_edje_vg_node = eet_data_descriptor_stream_new(&eetc); - - eetc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; - eetc.func.type_get = _union_type_get; - eetc.func.type_set = _union_type_set; - eet_union = eet_data_descriptor_stream_new(&eetc); - - _edje_edd_edje_doc_node = _eet_for_doc_node(); - _edje_edd_edje_g_node = _eet_for_g_node(); - _edje_edd_edje_defs_node = _eet_for_defs_node(); - _edje_edd_edje_arc_node = _eet_for_arc_node(); - _edje_edd_edje_circle_node = _eet_for_circle_node(); - _edje_edd_edje_ellipse_node = _eet_for_ellipse_node(); - _edje_edd_edje_rect_node = _eet_for_rect_node(); - _edje_edd_edje_path_node = _eet_for_path_node(); - _edje_edd_edje_polygon_node = _eet_for_polygon_node(); - _edje_edd_edje_style_property_node = _eet_for_style_property(); - _edje_edd_edje_matrix3_node = _eet_for_eina_matrix3(); - - - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "doc", _edje_edd_edje_doc_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "g", _edje_edd_edje_g_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "defs", _edje_edd_edje_defs_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "arc", _edje_edd_edje_arc_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "circle", _edje_edd_edje_circle_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "ellipse", _edje_edd_edje_ellipse_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "rect", _edje_edd_edje_rect_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "path", _edje_edd_edje_path_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "polygon", _edje_edd_edje_polygon_node); - EET_DATA_DESCRIPTOR_ADD_MAPPING(eet_union, "polyline", _edje_edd_edje_polygon_node); - - EET_DATA_DESCRIPTOR_ADD_UNION(_edje_edd_edje_vg_node, Svg_Node, "node", node, type, eet_union); - - - EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_vg_node, Svg_Node, "child", child, _edje_edd_edje_vg_node); - EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_vg_node, Svg_Node, "id", id, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_vg_node, Svg_Node, "style", style, _edje_edd_edje_style_property_node); - EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_vg_node, Svg_Node, "transform", transform, _edje_edd_edje_matrix3_node); - - return _edje_edd_edje_vg_node; -} - -EAPI void -_edje_svg_node_destroy_eet(void) -{ - FREE_DESCRIPTOR(_edje_edd_edje_rect_node); - FREE_DESCRIPTOR(_edje_edd_edje_circle_node); - FREE_DESCRIPTOR(_edje_edd_edje_ellipse_node); - FREE_DESCRIPTOR(_edje_edd_edje_gradient_stops_node); - FREE_DESCRIPTOR(_edje_edd_edje_linear_gradient_node); - FREE_DESCRIPTOR(_edje_edd_edje_radial_gradient_node); - FREE_DESCRIPTOR(_edje_edd_edje_style_gradient_node); - FREE_DESCRIPTOR(_edje_edd_edje_style_property_node); - FREE_DESCRIPTOR(_edje_edd_edje_matrix3_node); - FREE_DESCRIPTOR(_edje_edd_edje_doc_node); - FREE_DESCRIPTOR(_edje_edd_edje_defs_node); - FREE_DESCRIPTOR(_edje_edd_edje_g_node); - FREE_DESCRIPTOR(_edje_edd_edje_arc_node); - FREE_DESCRIPTOR(_edje_edd_edje_path_node); - FREE_DESCRIPTOR(_edje_edd_edje_polygon_node); - FREE_DESCRIPTOR(_edje_edd_edje_vg_node); -} - /* allocate a description struct. * this initializes clip_to_id as this field will not be present in most * edje files. @@ -751,7 +328,6 @@ _edje_edd_shutdown(void) FREED(_edje_edd_edje_file); FREED(_edje_edd_edje_part_collection); - _edje_svg_node_destroy_eet(); } #define EDJE_DEFINE_POINTER_TYPE(Type, Name) \ diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c index 0a83ff0739..4aebf29726 100644 --- a/src/lib/edje/edje_edit.c +++ b/src/lib/edje/edje_edit.c @@ -3231,9 +3231,6 @@ _edje_edit_real_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type else if (ep->type == EDJE_PART_TYPE_VECTOR) { rp->type = EDJE_PART_TYPE_VECTOR; - rp->typedata.vector = calloc(1, sizeof(Edje_Real_Part_Vector)); - if (rp->typedata.vector) - rp->typedata.vector->cur.svg_id = -1; rp->object = evas_object_vg_add(ed->base.evas); } else if (ep->type == EDJE_PART_TYPE_IMAGE || ep->type == EDJE_PART_TYPE_PROXY) diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index e6d767736d..94f8c0e401 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -27,7 +27,6 @@ struct _Edje_Drag_Items }; void _edje_file_add(Edje *ed, const Eina_File *f); -static void _edje_vector_data_free(Edje *ed); /* START - Nested part support */ #define _edje_smart_nested_type "Evas_Smart_Nested" @@ -986,15 +985,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch if (!rp->typedata.text) memerr = EINA_TRUE; break; - case EDJE_PART_TYPE_VECTOR: - rp->type = EDJE_PART_TYPE_VECTOR; - rp->typedata.vector = calloc(1, sizeof(Edje_Real_Part_Vector)); - if (!rp->typedata.vector) - memerr = EINA_TRUE; - else - rp->typedata.vector->cur.svg_id = -1; - break; - case EDJE_PART_TYPE_GROUP: case EDJE_PART_TYPE_SWALLOW: case EDJE_PART_TYPE_EXTERNAL: @@ -1895,7 +1885,6 @@ _edje_file_del(Edje *ed) _edje_message_del(ed); _edje_block_violate(ed); _edje_var_shutdown(ed); - _edje_vector_data_free(ed); if (!((ed->file) && (ed->collection))) { if (tev) @@ -1977,12 +1966,6 @@ _edje_file_del(Edje *ed) free(rp->typedata.text); rp->typedata.text = NULL; } - else if ((rp->type == EDJE_PART_TYPE_VECTOR) && - (rp->typedata.vector)) - { - free(rp->typedata.vector); - rp->typedata.vector = NULL; - } else if ((rp->type == EDJE_RP_TYPE_SWALLOW) && (rp->typedata.swallow)) { @@ -2682,330 +2665,6 @@ _cb_signal_repeat(void *data, Evas_Object *obj, const char *sig, const char *sou EDJE_MESSAGE_SIGNAL, 0, &emsg); } -static Efl_VG * -_apply_gradient_property(Svg_Style_Gradient *g) -{ - Efl_VG *grad_obj = NULL; - Efl_Gfx_Gradient_Stop *stops, *stop; - int stop_count = 0, i = 0; - Eina_List *l; - - if (g->type == SVG_LINEAR_GRADIENT) - { - grad_obj = efl_add(EFL_VG_GRADIENT_LINEAR_CLASS, NULL); - evas_vg_gradient_linear_start_set(grad_obj, g->linear->x1, g->linear->y1); - evas_vg_gradient_linear_end_set(grad_obj, g->linear->x2, g->linear->y2); - } - else if (g->type == SVG_RADIAL_GRADIENT) - { - grad_obj = efl_add(EFL_VG_GRADIENT_RADIAL_CLASS, NULL); - evas_vg_gradient_radial_center_set(grad_obj, g->radial->cx, g->radial->cy); - evas_vg_gradient_radial_radius_set(grad_obj, g->radial->r); - evas_vg_gradient_radial_focal_set(grad_obj, g->radial->fx, g->radial->fy); - } - else - { - // not a known gradient - return NULL; - } - // apply common prperty - evas_vg_gradient_spread_set(grad_obj, g->spread); - // update the stops - stop_count = eina_list_count(g->stops); - if (stop_count) - { - stops = calloc(stop_count, sizeof(Efl_Gfx_Gradient_Stop)); - i = 0; - EINA_LIST_FOREACH(g->stops, l, stop) - { - stops[i].r = stop->r; - stops[i].g = stop->g; - stops[i].b = stop->b; - stops[i].a = stop->a; - stops[i].offset = stop->offset; - i++; - } - evas_vg_gradient_stop_set(grad_obj, stops, stop_count); - free(stops); - } - return grad_obj; -} - -// vg tree creation -static void -_apply_vg_property(Svg_Node *node, Efl_VG *vg) -{ - Svg_Style_Property *style = node->style; - - // update the vg name - if (node->id) - evas_vg_node_name_set(vg, node->id); - - // apply the transformation - if (node->transform) - evas_vg_node_transformation_set(vg, node->transform); - - if (node->type == SVG_NODE_G) return; - - // apply the fill style property - efl_gfx_shape_fill_rule_set(vg, style->fill.fill_rule); - // if fill property is NULL then do nothing - if (style->fill.paint.none) - { - //do nothing - } - else if (style->fill.paint.gradient) - { - // if the fill has gradient then apply. - evas_vg_shape_fill_set(vg, _apply_gradient_property(style->fill.paint.gradient)); - } - else if (style->fill.paint.cur_color) - { - // apply the current style color - evas_vg_node_color_set(vg, style->r, style->g, - style->b, style->fill.opacity); - } - else - { - // apply the fill color - evas_vg_node_color_set(vg, style->fill.paint.r, style->fill.paint.g, - style->fill.paint.b, style->fill.opacity); - } - - // apply the stroke style property - //@TODO HACK, fix the below api to take the stroke width as pixels - evas_vg_shape_stroke_width_set(vg, style->stroke.width/2.0); - evas_vg_shape_stroke_cap_set(vg, style->stroke.cap); - evas_vg_shape_stroke_join_set(vg, style->stroke.join); - evas_vg_shape_stroke_scale_set(vg, style->stroke.scale); - // if stroke property is NULL then do nothing - if (style->stroke.paint.none) - { - //do nothing - } - else if (style->stroke.paint.gradient) - { - // if the fill has gradient then apply. - evas_vg_shape_stroke_fill_set(vg, _apply_gradient_property(style->stroke.paint.gradient)); - } - else if (style->stroke.paint.url) - { - // apply the color pointed by url - // TODO - } - else if (style->stroke.paint.cur_color) - { - // apply the current style color - evas_vg_shape_stroke_color_set(vg, style->r, style->g, - style->b, style->stroke.opacity); - } - else - { - // apply the stroke color - evas_vg_shape_stroke_color_set(vg, style->stroke.paint.r, style->stroke.paint.g, - style->stroke.paint.b, style->stroke.opacity); - } -} - -static void -_add_polyline(Efl_VG *vg, double *array, int size, Eina_Bool polygon) -{ - int i; - - if (size < 2) return; - - evas_vg_shape_append_move_to(vg, array[0], array[1]); - for (i=2; i < size; i+=2) - evas_vg_shape_append_line_to(vg, array[i], array[i+1]); - - if (polygon) - evas_vg_shape_append_close(vg); -} - -static void -_create_vg_node(Svg_Node *node, Efl_VG *parent) -{ - Efl_VG *vg = NULL; - Svg_Node *child; - Eina_List *l; - - switch (node->type) - { - case SVG_NODE_G: - { - vg = evas_vg_container_add(parent); - _apply_vg_property(node, vg); - EINA_LIST_FOREACH(node->child, l, child) - { - _create_vg_node(child, vg); - } - return; - } - break; - case SVG_NODE_PATH: - vg = evas_vg_shape_add(parent); - evas_vg_shape_append_svg_path(vg, node->node.path.path); - break; - case SVG_NODE_POLYGON: - vg = evas_vg_shape_add(parent); - _add_polyline(vg, node->node.polygon.points, node->node.polygon.points_count, EINA_TRUE); - break; - case SVG_NODE_POLYLINE: - vg = evas_vg_shape_add(parent); - _add_polyline(vg, node->node.polyline.points, node->node.polyline.points_count, EINA_FALSE); - break; - case SVG_NODE_ELLIPSE: - vg = evas_vg_shape_add(parent); - evas_vg_shape_append_arc(vg, node->node.ellipse.cx - node->node.ellipse.rx, - node->node.ellipse.cy - node->node.ellipse.ry, - 2*node->node.ellipse.rx, 2*node->node.ellipse.ry, 0, 360); - evas_vg_shape_append_close(vg); - break; - case SVG_NODE_CIRCLE: - vg = evas_vg_shape_add(parent); - evas_vg_shape_append_circle(vg, node->node.circle.cx, node->node.circle.cy, node->node.circle.r); - break; - case SVG_NODE_RECT: - vg = evas_vg_shape_add(parent); - evas_vg_shape_append_rect(vg, node->node.rect.x, node->node.rect.y, node->node.rect.w, node->node.rect.h, - node->node.rect.rx, node->node.rect.ry); - break; - default: - break; - } - _apply_vg_property(node, vg); -} - -static void -_edje_vector_data_free(Edje *ed) -{ - Edje_Vector_Data *vector; - - EINA_LIST_FREE(ed->vector_cache, vector) - { - if (vector->vg) efl_del(vector->vg); - free(vector); - } -} - -Edje_Vector_Data * -_edje_ref_vector_data(Edje *ed, int svg_id) -{ - Eina_List *l; - Edje_Vector_Data *vector; - char svg_key[20]; - Eet_Data_Descriptor *svg_node_eet; - Svg_Node *child; - Svg_Node *node; - Efl_VG *root = NULL; - - // check in the cache - EINA_LIST_FOREACH(ed->vector_cache, l, vector) - { - if (vector->svg_id == svg_id) - return vector; - } - - // create and put it in the cache. - vector = calloc(1, sizeof(Edje_Vector_Data)); - vector->svg_id = svg_id; - - snprintf(svg_key, sizeof(svg_key), "edje/vectors/%i", svg_id); - svg_node_eet = _edje_svg_node_eet(); - node = eet_data_read(ed->file->ef, svg_node_eet, svg_key); - - if (!node || (node->type != SVG_NODE_DOC)) - { - ERR("Failed to read Data from Eet for svg : %d", svg_id); - root = NULL; - } - else - { - root = evas_vg_container_add(NULL); - EINA_LIST_FOREACH(node->child, l, child) - { - _create_vg_node(child, root); - } - vector->x = node->node.doc.vx; - vector->y = node->node.doc.vy; - vector->w = node->node.doc.vw; - vector->h = node->node.doc.vh; - } - vector->vg = root; - ed->vector_cache = eina_list_append(ed->vector_cache, vector); - _edje_svg_node_free(node); - return vector; -} - -static void -_apply_stroke_scale(Efl_VG *node, double scale) -{ - Efl_VG *child; - Eina_Iterator *itr; - - if (efl_isa(node, EFL_VG_CONTAINER_CLASS)) - { - itr = efl_vg_container_children_get(node); - EINA_ITERATOR_FOREACH(itr, child) - _apply_stroke_scale(child, scale); - eina_iterator_free(itr); - } - else - { - evas_vg_shape_stroke_scale_set(node, scale); - } -} - -void -_apply_transformation(Efl_VG *root, double w, double h, Edje_Vector_Data *vg_data) -{ - double sx, sy, scale; - Eina_Matrix3 m; - - sx = w/vg_data->w; - sy = h/vg_data->h; - scale = sx < sy ? sx: sy; - eina_matrix3_identity(&m); - // allign hcenter and vcenter - //@TODO take care of the preserveaspectratio attribute - eina_matrix3_translate(&m, (w - vg_data->w * scale)/2.0, (h - vg_data->h * scale)/2.0); - eina_matrix3_scale(&m, scale, scale); - eina_matrix3_translate(&m, -vg_data->x, -vg_data->y); - evas_vg_node_transformation_set(root, &m); - _apply_stroke_scale(root, scale); -} - - -void -_edje_dupe_vector_data(Edje *ed, int svg_id, double width, double height, - Edje_Vector_Data *data) -{ - Edje_Vector_Data *vector; - Efl_VG *root; - - vector = _edje_ref_vector_data(ed, svg_id); - if (!vector->vg) - { - data->vg = NULL; - return; - } - - root = evas_vg_container_add(NULL); - efl_vg_dup(root, vector->vg); - - if (!EINA_DBL_EQ(vector->w, 0) && - !EINA_DBL_EQ(vector->h, 0)) - { - _apply_transformation(root, width, height, vector); - } - - data->vg = root; - data->x = vector->x; - data->y = vector->y; - data->w = vector->w; - data->h = vector->h; -} - EAPI Eina_Bool edje_3d_object_add(Evas_Object *obj, Eo **root_node, Eo *scene) { @@ -3061,73 +2720,3 @@ edje_3d_object_add(Evas_Object *obj, Eo **root_node, Eo *scene) return EINA_TRUE; } -static void -_svg_style_gradient_free(Svg_Style_Gradient *grad) -{ - Efl_Gfx_Gradient_Stop *stop; - - if (!grad) return; - - eina_stringshare_del(grad->id); - eina_stringshare_del(grad->ref); - free(grad->radial); - free(grad->linear); - - EINA_LIST_FREE(grad->stops, stop) - { - free(stop); - } - free(grad); -} - -static void -_node_style_free(Svg_Style_Property *style) -{ - if (!style) return; - - _svg_style_gradient_free(style->fill.paint.gradient); - eina_stringshare_del(style->fill.paint.url); - _svg_style_gradient_free(style->stroke.paint.gradient); - eina_stringshare_del(style->stroke.paint.url); - free(style); -} - -EAPI void -_edje_svg_node_free(Svg_Node *node) -{ - Svg_Node *child; - Svg_Style_Gradient *grad; - - if (!node) return; - - EINA_LIST_FREE(node->child, child) - { - _edje_svg_node_free(child); - } - - eina_stringshare_del(node->id); - free(node->transform); - _node_style_free(node->style); - switch (node->type) - { - case SVG_NODE_PATH: - eina_stringshare_del(node->node.path.path); - break; - case SVG_NODE_POLYGON: - case SVG_NODE_POLYLINE: - free(node->node.polygon.points); - break; - case SVG_NODE_DOC: - _edje_svg_node_free(node->node.doc.defs); - break; - case SVG_NODE_DEFS: - EINA_LIST_FREE(node->node.defs.gradients, grad) - { - _svg_style_gradient_free(grad); - } - break; - default: - break; - } - free(node); -} diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 2096362a89..5063b0080b 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -385,8 +385,6 @@ typedef struct _Edje_Part_Limit Edje_Part_Limit; typedef struct _Edje_Part_Description_Vector Edje_Part_Description_Vector; typedef struct _Edje_Part_Description_Spec_Svg Edje_Part_Description_Spec_Svg; typedef struct _Edje_Part_Allowed_Seat Edje_Part_Allowed_Seat; -typedef struct _Edje_Real_Part_Vector Edje_Real_Part_Vector; -typedef struct _Edje_Vector_Data Edje_Vector_Data; typedef struct _Edje Edje; typedef struct _Edje_Real_Part_Text Edje_Real_Part_Text; @@ -1694,7 +1692,6 @@ struct _Edje Eina_List *subobjs; Eina_List *text_insert_filter_callbacks; Eina_List *markup_filter_callbacks; - Eina_List *vector_cache; /* list of Edje_Vector_Data */ Eina_List *groups; @@ -1996,19 +1993,6 @@ struct _Edje_Real_Part_Swallow } swallow_params; // 28 // FIXME: only if type SWALLOW }; -struct _Edje_Vector_Data -{ - int svg_id; - double x, y, w, h; - Eina_Bool preserve_aspect; - Efl_VG *vg; -}; - -struct _Edje_Real_Part_Vector -{ - Edje_Vector_Data cur; -}; - struct _Edje_Real_Part { Edje_Real_Part_State param1; // 32 @@ -2031,7 +2015,6 @@ struct _Edje_Real_Part Edje_Real_Part_Text *text; Edje_Real_Part_Container *container; Edje_Real_Part_Swallow *swallow; - Edje_Real_Part_Vector *vector; } typedata; // 4 FLOAT_T description_pos; // 8 Edje_Rectangle req; // 16 @@ -2248,13 +2231,13 @@ struct _Edje_Patterns int ref; Eina_Bool delete_me : 1; - + size_t patterns_size; size_t max_length; unsigned int finals[]; }; -typedef enum _Edje_User_Defined_Type +typedef enum _Edje_User_Defined_Type { EDJE_USER_SWALLOW, EDJE_USER_BOX_PACK, @@ -3185,278 +3168,6 @@ void _edje_object_part_text_insert(Edje *ed, Edje_Real_Part *rp, const char *tex void _edje_internal_proxy_shutdown(void); -// Svg loader -typedef enum _Svg_Node_Type Svg_Node_Type; -typedef enum _Svg_Length_Type Svg_Length_Type; - -typedef struct _Svg_Node Svg_Node; -typedef struct _Svg_Doc_Node Svg_Doc_Node; -typedef struct _Svg_G_Node Svg_G_Node; -typedef struct _Svg_Defs_Node Svg_Defs_Node; -typedef struct _Svg_Arc_Node Svg_Arc_Node; -typedef struct _Svg_Circle_Node Svg_Circle_Node; -typedef struct _Svg_Ellipse_Node Svg_Ellipse_Node; -typedef struct _Svg_Polygon_Node Svg_Polygon_Node; -typedef struct _Svg_Rect_Node Svg_Rect_Node; -typedef struct _Svg_Path_Node Svg_Path_Node; -typedef struct _Svg_Style_Property Svg_Style_Property; - -typedef struct _Svg_Style_Stroke Svg_Style_Stroke; -typedef struct _Svg_Style_Fill Svg_Style_Fill; -typedef enum _Svg_Fill_Flags Svg_Fill_Flags; -typedef enum _Svg_Stroke_Flags Svg_Stroke_Flags; - - -typedef enum _Svg_Gradient_Type Svg_Gradient_Type; -typedef struct _Svg_Style_Gradient Svg_Style_Gradient; -typedef struct _Svg_Linear_Gradient Svg_Linear_Gradient; -typedef struct _Svg_Radial_Gradient Svg_Radial_Gradient; -typedef struct _Svg_Paint Svg_Paint; - -enum _Svg_Node_Type -{ - SVG_NODE_DOC, - SVG_NODE_G, - SVG_NODE_DEFS, - SVG_NODE_SWITCH, - SVG_NODE_ANIMATION, - SVG_NODE_ARC, - SVG_NODE_CIRCLE, - SVG_NODE_ELLIPSE, - SVG_NODE_IMAGE, - SVG_NODE_LINE, - SVG_NODE_PATH, - SVG_NODE_POLYGON, - SVG_NODE_POLYLINE, - SVG_NODE_RECT, - SVG_NODE_TEXT, - SVG_NODE_TEXTAREA, - SVG_NODE_TSPAN, - SVG_NODE_USE, - SVG_NODE_VIDEO, - SVG_NODE_UNKNOWN -}; - -enum _Svg_Length_Type -{ - SVG_LT_PERCENT, - SVG_LT_PX, - SVG_LT_PC, - SVG_LT_PT, - SVG_LT_MM, - SVG_LT_CM, - SVG_LT_IN, -}; - -struct _Svg_Doc_Node -{ - double width; - double height; - double vx; - double vy; - double vw; - double vh; - Svg_Node *defs; -}; - -struct _Svg_G_Node -{ - -}; - -struct _Svg_Defs_Node -{ - Eina_List *gradients; -}; - -struct _Svg_Arc_Node -{ - -}; - -struct _Svg_Ellipse_Node -{ - double cx; - double cy; - double rx; - double ry; -}; - -struct _Svg_Circle_Node -{ - double cx; - double cy; - double r; -}; - -struct _Svg_Rect_Node -{ - double x; - double y; - double w; - double h; - double rx; - double ry; -}; - -struct _Svg_Path_Node -{ - Eina_Stringshare *path; -}; - -struct _Svg_Polygon_Node -{ - int points_count; - double *points; -}; - - -enum _Svg_Gradient_Type -{ - SVG_LINEAR_GRADIENT, - SVG_RADIAL_GRADIENT -}; -struct _Svg_Linear_Gradient -{ - double x1; - double y1; - double x2; - double y2; -}; - -struct _Svg_Radial_Gradient -{ - double cx; - double cy; - double fx; - double fy; - double r; -}; - -struct _Svg_Style_Gradient -{ - Svg_Gradient_Type type; - Eina_Stringshare *id; - Eina_Stringshare *ref; - Efl_Gfx_Gradient_Spread spread; - Eina_List *stops; // Efl_Gfx_Gradient_Stop - Svg_Radial_Gradient *radial; - Svg_Linear_Gradient *linear; -}; - -struct _Svg_Paint -{ - int r; - int g; - int b; - Eina_Bool none; - Eina_Bool cur_color; - Svg_Style_Gradient *gradient; - Eina_Stringshare *url; -}; - -enum _Svg_Fill_Flags -{ - SVG_FILL_FLAGS_PAINT = 0x1, - SVG_FILL_FLAGS_OPACITY = 0x2, - SVG_FILL_FLAGS_GRADIENT = 0x4, - SVG_FILL_FLAGS_FILL_RULE = 0x8 -}; - -enum _Svg_Stroke_Flags -{ - SVG_STROKE_FLAGS_PAINT = 0x1, - SVG_STROKE_FLAGS_OPACITY = 0x2, - SVG_STROKE_FLAGS_GRADIENT = 0x4, - SVG_STROKE_FLAGS_SCALE = 0x8, - SVG_STROKE_FLAGS_WIDTH = 0x10, - SVG_STROKE_FLAGS_CAP = 0x20, - SVG_STROKE_FLAGS_JOIN = 0x40, - SVG_STROKE_FLAGS_DASH = 0x80, -}; - -struct _Svg_Style_Fill -{ - Svg_Fill_Flags flags; - Svg_Paint paint; - int opacity; - Efl_Gfx_Fill_Rule fill_rule; -}; - -struct _Svg_Style_Stroke -{ - Svg_Stroke_Flags flags; - Svg_Paint paint; - int opacity; - double scale; - double width; - double centered; - Efl_Gfx_Cap cap; - Efl_Gfx_Join join; - Efl_Gfx_Dash *dash; - int dash_count; -}; - -struct _Svg_Style_Property -{ - Svg_Style_Fill fill; - Svg_Style_Stroke stroke; - // the color property indirectly - // used by fill and stroke - int r; - int g; - int b; -}; - -struct _Svg_Node -{ - Svg_Node_Type type; - Svg_Node *parent; - Eina_List *child; - Eina_Stringshare *id; - Svg_Style_Property *style; - Eina_Matrix3 *transform; - union - { - Svg_G_Node g; - Svg_Doc_Node doc; - Svg_Defs_Node defs; - Svg_Arc_Node arc; - Svg_Circle_Node circle; - Svg_Ellipse_Node ellipse; - Svg_Polygon_Node polygon; - Svg_Polygon_Node polyline; - Svg_Rect_Node rect; - Svg_Path_Node path; - }node; -}; - -enum _Svg_Style_Type -{ - SVG_STYLE_QUALITY, - SVG_STYLE_FILL, - SVG_STYLE_VIEWPORT_FILL, - SVG_STYLE_FONT, - SVG_STYLE_STROKE, - SVG_STYLE_SOLID_COLOR, - SVG_STYLE_GRADIENT, - SVG_STYLE_TRANSFORM, - SVG_STYLE_OPACITY, - SVG_STYLE_COMP_OP -}; - -EAPI Eet_Data_Descriptor * _edje_svg_node_eet(void); -void _edje_svg_node_destroy_eet(void); - -void _edje_dupe_vector_data(Edje *ed, int svg_id, double width, double height, - Edje_Vector_Data *data); -void _apply_transformation(Efl_VG *root, double w, double h, - Edje_Vector_Data *vg_data); - -Edje_Vector_Data * _edje_ref_vector_data(Edje *ed, int svg_id); - -EAPI void _edje_svg_node_free(Svg_Node *node); - #ifdef HAVE_EPHYSICS Eina_Bool _edje_ephysics_load(void);