cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=698135b8e4a59ef08dc0c0e957ef073df2ef5296

commit 698135b8e4a59ef08dc0c0e957ef073df2ef5296
Author: Subhransu Mohanty <sub.moha...@samsung.com>
Date:   Wed Jun 8 10:26:38 2016 -0700

    edje: add svg support to parse and store a svg file as a vector object in 
.edj.
    
    Summary:
    This is the svg loader which will parse the svg file and store it in a 
intermediate structure.
    It provides the helper function to get EET descriptor to save the structure 
into eet file.
    
    NOTE: Not all svg attributes are handled yet. but most common attributes 
are handled .
    
    Reviewers: Hermet, cedric
    
    Subscribers: Hermet, cedric, jpeg
    
    Differential Revision: https://phab.enlightenment.org/D3868
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 src/Makefile_Edje.am           |    3 +-
 src/bin/edje/edje_cc.h         |    3 +
 src/bin/edje/edje_svg_loader.c | 1472 ++++++++++++++++++++++++++++++++++++++++
 src/lib/edje/edje_data.c       |  409 +++++++++++
 src/lib/edje/edje_private.h    |  225 ++++++
 5 files changed, 2111 insertions(+), 1 deletion(-)

diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am
index 8dc400c..f85f7d9 100644
--- a/src/Makefile_Edje.am
+++ b/src/Makefile_Edje.am
@@ -163,7 +163,8 @@ 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_multisense_convert.c \
+bin/edje/edje_svg_loader.c
 bin_edje_edje_cc_CPPFLAGS = -I$(top_builddir)/src/lib/efl 
$(EDJE_COMMON_CPPFLAGS)
 bin_edje_edje_cc_LDADD =  $(USE_EDJE_BIN_LIBS)
 bin_edje_edje_cc_DEPENDENCIES = \
diff --git a/src/bin/edje/edje_cc.h b/src/bin/edje/edje_cc.h
index a097d8e..ad930c9 100644
--- a/src/bin/edje/edje_cc.h
+++ b/src/bin/edje/edje_cc.h
@@ -257,6 +257,9 @@ 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
new file mode 100644
index 0000000..2ab2b4d
--- /dev/null
+++ b/src/bin/edje/edje_svg_loader.c
@@ -0,0 +1,1472 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <edje_private.h>
+#include <ctype.h>
+
+#include <Eet.h>
+#include <Eina.h>
+#include <Evas.h>
+#include <eina_matrix.h>
+
+#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 char *
+_copy_id(const char* str)
+{
+   char *id = malloc(strlen(str));
+
+   strcpy(id, str);
+   return id;
+}
+
+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;
+}
+
+/* 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 inline Efl_Gfx_Cap
+_to_line_cap(const char *str)
+{
+   Efl_Gfx_Cap cap = EFL_GFX_CAP_LAST;
+
+   if (!strcmp(str, "butt"))
+     {
+        cap = EFL_GFX_CAP_BUTT;
+     }
+   else if (!strcmp(str, "round"))
+     {
+        cap = EFL_GFX_CAP_ROUND;
+     }
+   else if (!strcmp(str, "square"))
+     {
+        cap = EFL_GFX_CAP_SQUARE;
+     }
+   return cap;
+}
+
+/* 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 inline Efl_Gfx_Join
+_to_line_join(const char *str)
+{
+   Efl_Gfx_Join join = EFL_GFX_JOIN_LAST;
+
+   if (!strcmp(str, "miter"))
+     {
+        join = EFL_GFX_JOIN_MITER;
+     }
+   else if (!strcmp(str, "round"))
+     {
+        join = EFL_GFX_JOIN_ROUND;
+     }
+   else if (!strcmp(str, "bevel"))
+     {
+        join = EFL_GFX_JOIN_BEVEL;
+     }
+   return join;
+}
+
+/* parse the fill rule used during filling a path.
+ * Value:   nonzero | evenodd | inherit
+ * Initial:    nonzero
+ * https://www.w3.org/TR/SVG/painting.html
+ */
+static inline Efl_Gfx_Fill_Rule
+_to_fill_rule(const char *str)
+{
+   Efl_Gfx_Fill_Rule rule = EFL_GFX_FILL_RULE_WINDING;
+
+   if (!strcmp(str, "evenodd"))
+     {
+        rule = EFL_GFX_FILL_RULE_ODD_EVEN;
+     }
+   return rule;
+}
+
+/* parse the dash pattern used during stroking a path.
+ * Value:   none | <dasharray> | 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];
+          }
+     }
+}
+
+static char *
+ _id_from_url(const char *url)
+{
+   char tmp[50];
+   int i = 0;
+   char * id;
+
+   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';
+   id = malloc(strlen(tmp));
+   strcpy(id, tmp);
+   return id;
+}
+
+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 inline void
+_to_color(const char *str, int *r, int *g, int *b, char** ref)
+{
+   unsigned int len = strlen(str);
+   char *red, *green, *blue;
+   unsigned char tr, tg, tb;
+
+   if (len == 4 && str[0] == '#')
+     {
+        if (isxdigit(str[1]) &&
+            isxdigit(str[2]) &&
+            isxdigit(str[3]))
+          {
+             char tmp[2] = { '\0', '\0' };
+             tmp[0] = str[1]; *r = strtol(tmp, NULL, 16);
+             tmp[0] = str[2]; *g = strtol(tmp, NULL, 16);
+             tmp[0] = 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
+     {
+      // TODO handle named color
+     }
+}
+
+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 sz, 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;
+          }
+        sz = end - str;
+        for (i = 0; i < sizeof (matrix_tags) / sizeof(matrix_tags[0]); i++)
+          if (matrix_tags[i].sz - 1 == sz && !strncmp(matrix_tags[i].tag, str, 
sz))
+            {
+               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]);
+               }
+             else if (pt_count == 3)
+               {
+                  eina_matrix3_translate(matrix, points[1], points[2]);
+                  eina_matrix3_rotate(matrix, points[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 
+Efl_Gfx_Fill_Rule
+_parse_fill_rule(const char *str)
+{
+   Efl_Gfx_Fill_Rule fill = EFL_GFX_FILL_RULE_WINDING;
+
+   if (!strcmp(str, "evenodd"))
+     {
+        fill = EFL_GFX_FILL_RULE_ODD_EVEN;
+     }
+   return fill;
+}
+
+static Eina_Bool
+_attr_parse_svg_node(void *data, const char *key, const char *value)
+{
+   Svg_Doc_Node *node = data;
+   Svg_Length_Type type;
+
+   // @TODO handle lenght unit.
+   if (!strcmp(key, "width"))
+     {
+        node->width = parse_length(value, &type);
+     }
+   else if (!strcmp(key, "height"))
+     {
+        node->height = parse_length(value, &type);
+     }
+   else if (!strcmp(key, "viewBox"))
+     {
+        if (_parse_number(&value, &node->vx))
+          if (_parse_number(&value, &node->vy))
+            if (_parse_number(&value, &node->vw))
+              _parse_number(&value, &node->vh);
+     }
+   return EINA_TRUE;
+}
+
+static void
+_handle_color_attr(Svg_Node* node, const char *value)
+{
+   Svg_Style_Property *style = node->style;
+   char *use = NULL;
+
+   _to_color(value, &style->fill.r, &style->fill.g, &style->fill.b, &use);
+   if (use)
+     {
+        // update the gradient field
+     }
+}
+
+static void
+_handle_fill_attr(Svg_Node* node, const char *value)
+{
+   Svg_Style_Property *style = node->style;
+   char *use = NULL;
+
+   _to_color(value, &style->fill.r, &style->fill.g, &style->fill.b, &use);
+   if (use)
+     {
+        // update the gradient field
+     }
+}
+
+static void
+_handle_stroke_attr(Svg_Node* node, const char *value)
+{
+   Svg_Style_Property *style = node->style;
+   char *use = NULL;
+
+   _to_color(value, &style->stroke.r, &style->stroke.g, &style->stroke.b, 
&use);
+   if (use)
+     {
+        // update the gradient field
+     }
+}
+
+static void
+_handle_stroke_opacity_attr(Svg_Node* node, const char *value)
+{
+   node->style->stroke.a = _to_opacity(value);
+}
+
+static void
+_handle_stroke_width_attr(Svg_Node* node, const char *value)
+{
+   node->style->stroke.width = _to_double(value);
+}
+
+static void
+_handle_stroke_linecap_attr(Svg_Node* node, const char *value)
+{
+   node->style->stroke.cap = _to_line_cap(value);
+}
+
+static void
+_handle_stroke_linejoin_attr(Svg_Node* node, const char *value)
+{
+   node->style->stroke.join = _to_line_join(value);
+}
+
+static void
+_handle_color_opacity_attr(Svg_Node* node, const char *value)
+{
+   node->style->fill.a = _to_opacity(value);
+}
+
+static void
+_handle_fill_rule_attr(Svg_Node* node, const char *value)
+{
+   node->style->fill.fill_rule = _parse_fill_rule(value);
+}
+
+static void
+_handle_fill_opacity_attr(Svg_Node* node, const char *value)
+{
+   node->style->fill.a = _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(color-opacity, color_opacity),
+  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->style, value);
+     }
+   else if (!strcmp(key, "transform"))
+     {
+        node->transform = _parse_transformation_matrix(value);
+     }
+   else if (!strcmp(key, "id"))
+     {
+        node->id = _copy_id(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));
+   node->style->fill.a = 255;
+   node->style->fill.fill_rule = EFL_GFX_FILL_RULE_WINDING;
+
+   //default stroke property
+   node->style->stroke.cap = EFL_GFX_CAP_BUTT;
+   node->style->stroke.join = EFL_GFX_JOIN_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);
+
+   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->node.doc);
+   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 = malloc(strlen(value));
+        strcpy(path->path, value);
+     }
+   else if (!strcmp(key, "style"))
+     {
+        _attr_style_node(node->style, 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->style, 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->style, 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;
+
+   while (_parse_number(&str, &num))
+     {
+        tmp[tmp_count++] = num;
+        if (tmp_count == 50)
+          {
+             point_array = realloc(point_array, (count + tmp_count) * 
sizeof(double));
+             memcpy(&point_array[count], tmp, tmp_count * sizeof(double));
+             count += tmp_count;
+          }
+     }
+
+   if (tmp_count > 0)
+     {
+        point_array = realloc(point_array, (count + tmp_count) * 
sizeof(double));
+        memcpy(&point_array[count], tmp, tmp_count * sizeof(double));
+        count += tmp_count;
+     }
+   *point_count = count;
+   *points = point_array;
+}
+
+/* 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 = &(node->node.polygon);
+
+   if (!strcmp(key, "points"))
+     {
+        _attr_parse_polygon_points(value, &polygon->points, 
&polygon->points_count);
+     }
+   else if (!strcmp(key, "style"))
+     {
+        _attr_style_node(node->style, 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;
+}
+
+#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->style, value);
+     }
+   else
+     {
+        _parse_style_attr(node, key, value);
+     }
+
+   if (rect->rx != 0 && rect->ry == 0) rect->ry = rect->rx;
+   if (rect->ry != 0 && 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;
+}
+
+#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(circle),
+  TAG_DEF(ellipse),
+  TAG_DEF(path),
+  TAG_DEF(polygon),
+  TAG_DEF(rect)
+};
+
+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)
+};
+
+static Factory_Method
+_find_group_factory(const char  *name)
+{
+   unsigned int i;
+   int sz = strlen(name);
+
+   for (i = 0; i < sizeof (group_tags) / sizeof(group_tags[0]); i++)
+     if (group_tags[i].sz - 1 == sz && !strncmp(group_tags[i].tag, name, sz))
+       {
+          return group_tags[i].tag_handler;
+       }
+   return NULL;
+}
+
+static Factory_Method
+_find_graphics_factory(const char  *name)
+{
+   unsigned int i;
+   int sz = strlen(name);
+
+   for (i = 0; i < sizeof (graphics_tags) / sizeof(graphics_tags[0]); i++)
+     if (graphics_tags[i].sz - 1 == sz && !strncmp(graphics_tags[i].tag, name, 
sz))
+       {
+          return graphics_tags[i].tag_handler;
+       }
+   return NULL;
+}
+
+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);
+
+   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);
+     }
+   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 (radial_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);
+     }
+
+   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);
+
+   // find out the tag name starting from content till sz length
+   if (attrs)
+     {
+        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->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->def)
+          {
+             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);
+     }
+
+}
+
+static void
+_evas_svg_loader_xml_close_parser(Evas_SVG_Loader *loader,
+                                  const char *content, unsigned int length 
EINA_UNUSED)
+{
+   content = _skip_space(content, NULL);
+   if (!strncmp(content, "g", 1))
+     {
+        eina_array_pop(loader->stack);
+     }
+   else if (!strncmp(content, "svg", 3))
+     {
+        eina_array_pop(loader->stack);
+     }
+   else if (!strncmp(content, "defs", 3))
+     {
+        eina_array_pop(loader->stack);
+     }
+   else if (!strncmp(content, "linearGradient", 13))
+     {
+        //TODO
+     }
+
+   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);
+      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;
+}
+
+EAPI Svg_Node *
+_svg_load(Eina_File *f, const char *key EINA_UNUSED)
+{
+   Evas_SVG_Loader loader = {
+     NULL, NULL,NULL,0
+   };
+   const char *content;
+   unsigned int length;
+
+   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);
+     }
+   return loader.doc;
+}
diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c
index c229f6a..154c2ed 100644
--- a/src/lib/edje/edje_data.c
+++ b/src/lib/edje/edje_data.c
@@ -83,6 +83,414 @@ Eet_Data_Descriptor *_edje_edd_edje_map_colors_pointer = 
NULL;
 Eet_Data_Descriptor *_edje_edd_edje_filter = NULL;
 Eet_Data_Descriptor *_edje_edd_edje_filter_directory = 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_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);
+
+   // for fill
+   EET_DATA_DESCRIPTOR_ADD_SUB(eet, Svg_Style_Property, "fill.gradient", 
fill.gradient, eet_gradient);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.fill_rule", 
fill.fill_rule, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.r", fill.r, 
EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.g", fill.g, 
EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.b", fill.b, 
EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.a", fill.a, 
EET_T_INT);
+
+   // for stroke
+   EET_DATA_DESCRIPTOR_ADD_SUB(eet, Svg_Style_Property, "stroke.gradient", 
stroke.gradient, eet_gradient);
+   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.r", 
stroke.r, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.g", 
stroke.g, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.b", 
stroke.b, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "stroke.a", 
stroke.a, EET_T_INT);
+   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_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_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_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.
@@ -308,6 +716,7 @@ _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_private.h b/src/lib/edje/edje_private.h
index 05b0b64..f5c3bb8 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -2966,6 +2966,231 @@ Eina_Bool _edje_efl_container_content_set(Edje *ed, 
const char *part, Efl_Gfx *o
 
 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_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;
+
+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;
+};
+
+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
+{
+   char *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;
+   char              *id;
+   Efl_Gfx_Gradient_Spread spread;
+   Eina_List   *stops; // Efl_Gfx_Gradient_Stop
+   Svg_Radial_Gradient *radial;
+   Svg_Linear_Gradient *linear;
+};
+
+
+struct _Svg_Style_Fill
+{
+   Svg_Style_Gradient  *gradient;
+   Efl_Gfx_Fill_Rule   fill_rule;
+   int r;
+   int g;
+   int b;
+   int a;
+};
+
+struct _Svg_Style_Stroke
+{
+   Svg_Style_Gradient  *gradient;
+   double scale;
+   double width;
+   double centered;
+   int r;
+   int g;
+   int b;
+   int a;
+   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;
+};
+
+struct _Svg_Node
+{
+   Svg_Node_Type        type;
+   Svg_Node            *parent;
+   Eina_List           *child;
+   char                *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_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);
+
 #ifdef HAVE_LIBREMIX
 #include <remix/remix.h>
 #endif

-- 


Reply via email to