svg_loader: Fixed the parsing of style attribute in g node as well as inheriting...
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Thu, 23 Jun 2016 01:11:46 +0000 (10:11 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Thu, 23 Jun 2016 01:20:44 +0000 (10:20 +0900)
Reviewers: jpeg, cedric

Reviewed By: cedric

Subscribers: cedric, jpeg

Differential Revision: https://phab.enlightenment.org/D4070

src/bin/edje/edje_svg_loader.c
src/lib/edje/edje_data.c
src/lib/edje/edje_private.h

index e97118d..e659e93 100644 (file)
@@ -60,6 +60,8 @@ _skip_space(const char *str, const char *end)
 static inline char *
 _copy_id(const char* str)
 {
+   if (str == NULL) return NULL;
+
    return strdup(str);
 }
 
@@ -552,6 +554,7 @@ 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);
 }
 
@@ -559,42 +562,49 @@ 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);
 }
 
@@ -678,6 +688,10 @@ _attr_parse_g_node(void *data, const char *key, const char *value)
      {
         node->id = _copy_id(value);
      }
+   else
+     {
+        _parse_style_attr(node, key, value);
+     }
    return EINA_TRUE;
 }
 
@@ -1443,6 +1457,72 @@ _evas_svg_loader_parser(void *data, Eina_Simple_XML_Type type,
    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);
+     }
+}
+
 EAPI Svg_Node *
 _svg_load(Eina_File *f, const char *key EINA_UNUSED)
 {
@@ -1465,5 +1545,9 @@ _svg_load(Eina_File *f, const char *key EINA_UNUSED)
        eina_array_free(loader.stack);
        eina_file_map_free(f, (void*) content);
      }
+
+   if (loader.doc)
+     _update_style(loader.doc, NULL);
+
    return loader.doc;
 }
index c6a4e5d..6d75c7c 100644 (file)
@@ -247,6 +247,7 @@ _eet_for_style_property(void)
    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_SUB(eet, Svg_Style_Property, "fill.gradient", fill.gradient, eet_gradient);
    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);
@@ -258,6 +259,7 @@ _eet_for_style_property(void)
    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_SUB(eet, Svg_Style_Property, "stroke.gradient", stroke.gradient, eet_gradient);
    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);
index e8e17e5..4694846 100644 (file)
@@ -3029,8 +3029,11 @@ 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 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;
@@ -3177,8 +3180,29 @@ struct _Svg_Paint
    char      *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;
    Svg_Style_Gradient  *gradient;
@@ -3187,6 +3211,7 @@ struct _Svg_Style_Fill
 
 struct _Svg_Style_Stroke
 {
+   Svg_Stroke_Flags     flags;
    Svg_Paint            paint;
    int                  opacity;
    Svg_Style_Gradient  *gradient;