From d8760275646849d289809bb6971f1ece550ac145 Mon Sep 17 00:00:00 2001 From: Subhransu Mohanty Date: Thu, 23 Jun 2016 10:11:46 +0900 Subject: [PATCH] svg_loader: Fixed the parsing of style attribute in g node as well as inheriting style attribute from parent. Reviewers: jpeg, cedric Reviewed By: cedric Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4070 --- src/bin/edje/edje_svg_loader.c | 84 ++++++++++++++++++++++++++++++++++++++++++ src/lib/edje/edje_data.c | 2 + src/lib/edje/edje_private.h | 29 ++++++++++++++- 3 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/bin/edje/edje_svg_loader.c b/src/bin/edje/edje_svg_loader.c index e97118d..e659e93 100644 --- a/src/bin/edje/edje_svg_loader.c +++ b/src/bin/edje/edje_svg_loader.c @@ -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; } diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index c6a4e5d..6d75c7c 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -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); diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index e8e17e5..4694846 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -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; -- 2.7.4