From 901e8a0cfc20b6605dd9a3d27353810ff982e030 Mon Sep 17 00:00:00 2001 From: Subhransu Mohanty Date: Thu, 16 Jun 2016 16:50:05 -0700 Subject: [PATCH] edje: creation of gradient node from data parsing of color property and refactoring of fill and stroke attribute. Reviewers: jpeg, cedric Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4045 Signed-off-by: Cedric BAIL --- src/bin/edje/edje_svg_loader.c | 80 ++++++++++++++------------ src/lib/edje/edje_data.c | 25 +++++--- src/lib/edje/edje_load.c | 127 ++++++++++++++++++++++++++++++++++++++--- src/lib/edje/edje_private.h | 43 ++++++++------ 4 files changed, 207 insertions(+), 68 deletions(-) diff --git a/src/bin/edje/edje_svg_loader.c b/src/bin/edje/edje_svg_loader.c index 8f155b3..ea3126d 100644 --- a/src/bin/edje/edje_svg_loader.c +++ b/src/bin/edje/edje_svg_loader.c @@ -522,49 +522,50 @@ _attr_parse_svg_node(void *data, const char *key, const char *value) return EINA_TRUE; } +//https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint static void -_handle_color_attr(Svg_Node* node, const char *value) +_handle_paint_attr(Svg_Paint* paint, 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) + if (!strcmp(value, "none")) { - // update the gradient field + // 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_fill_attr(Svg_Node* node, const char *value) +_handle_color_attr(Svg_Node* node, const char *value) { Svg_Style_Property *style = node->style; - char *use = NULL; + _to_color(value, &style->r, &style->g, &style->b, 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; + _handle_paint_attr(&style->fill.paint, value); } 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 - } + _handle_paint_attr(&style->stroke.paint, value); } static void _handle_stroke_opacity_attr(Svg_Node* node, const char *value) { - node->style->stroke.a = _to_opacity(value); + node->style->stroke.opacity = _to_opacity(value); } static void @@ -586,12 +587,6 @@ _handle_stroke_linejoin_attr(Svg_Node* node, const char *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 = _to_fill_rule(value); @@ -600,7 +595,7 @@ _handle_fill_rule_attr(Svg_Node* node, const char *value) static void _handle_fill_opacity_attr(Svg_Node* node, const char *value) { - node->style->fill.a = _to_opacity(value); + node->style->fill.opacity = _to_opacity(value); } static void @@ -621,7 +616,6 @@ static const struct { 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), @@ -695,12 +689,29 @@ _create_node(Svg_Node *parent, Svg_Node_Type type) // default fill property node->style = calloc(1, sizeof(Svg_Style_Property)); - node->style->fill.a = 255; + + // 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 property + // 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; - node->style->stroke.join = EFL_GFX_JOIN_MITER; + // default line join is miter node->style->stroke.join = EFL_GFX_JOIN_MITER; node->style->stroke.scale = 1.0; @@ -755,8 +766,7 @@ _attr_parse_path_node(void *data, const char *key, const char *value) if (!strcmp(key, "d")) { - path->path = malloc(strlen(value)); - strcpy(path->path, value); + path->path = strdup(value); } else if (!strcmp(key, "style")) { diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index 6fef146..bca1610 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -243,23 +243,32 @@ _eet_for_style_property(void) 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_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); + 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_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); - 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.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_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.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); diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 5ca19e5..74fb072 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -2310,21 +2310,130 @@ _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(Efl_VG *parent, Svg_Style_Gradient *g) +{ + Efl_VG *grad_obj = NULL; + Efl_Gfx_Gradient_Stop *stops, *stop; + int stop_count = 0; + Eina_List *l; + + if (g->type == SVG_LINEAR_GRADIENT) + { + grad_obj = eo_add(EFL_VG_GRADIENT_LINEAR_CLASS, parent); + 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 = eo_add(EFL_VG_GRADIENT_RADIAL_CLASS, parent); + 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)); + EINA_LIST_FOREACH(g->stops, l, stop) + { + stops->r = stop->r; + stops->g = stop->g; + stops->b = stop->b; + stops->a = stop->a; + stops->offset = stop->offset; + } + 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); - if (node->style) - { - evas_vg_node_color_set(vg, node->style->fill.r, node->style->fill.g, node->style->fill.b, node->style->fill.a); - efl_gfx_shape_fill_rule_set(vg, node->style->fill.fill_rule); - evas_vg_shape_stroke_color_set(vg, node->style->stroke.r, node->style->stroke.g, node->style->stroke.b, node->style->stroke.a); - evas_vg_shape_stroke_width_set(vg, node->style->stroke.width); - evas_vg_shape_stroke_cap_set(vg, node->style->stroke.cap); - evas_vg_shape_stroke_join_set(vg, node->style->stroke.join); - evas_vg_shape_stroke_scale_set(vg, node->style->stroke.scale); + + // 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.gradient) + { + // if the fill has gradient then apply. + evas_vg_shape_fill_set(vg, _apply_gradient_property(vg, style->fill.gradient)); + } + else if (style->fill.paint.url) + { + // apply the color pointed by url + // TODO + } + 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 + evas_vg_shape_stroke_width_set(vg, style->stroke.width); + 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.gradient) + { + // if the fill has gradient then apply. + evas_vg_shape_stroke_fill_set(vg, _apply_gradient_property(vg, style->stroke.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); } } diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index fbfc633..db75df4 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -3033,6 +3033,7 @@ 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 { @@ -3163,37 +3164,47 @@ struct _Svg_Style_Gradient Svg_Linear_Gradient *linear; }; +struct _Svg_Paint +{ + int r; + int g; + int b; + Eina_Bool none; + Eina_Bool cur_color; + char *url; +}; struct _Svg_Style_Fill { + Svg_Paint paint; + int opacity; Svg_Style_Gradient *gradient; - Efl_Gfx_Fill_Rule fill_rule; - int r; - int g; - int b; - int a; + Efl_Gfx_Fill_Rule fill_rule; }; struct _Svg_Style_Stroke { + Svg_Paint paint; + int opacity; 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; + 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 -- 2.7.4