edje: creation of gradient node from data parsing of color property and refactoring...
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Thu, 16 Jun 2016 23:50:05 +0000 (16:50 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Thu, 16 Jun 2016 23:50:08 +0000 (16:50 -0700)
Reviewers: jpeg, cedric

Subscribers: cedric, jpeg

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

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
src/bin/edje/edje_svg_loader.c
src/lib/edje/edje_data.c
src/lib/edje/edje_load.c
src/lib/edje/edje_private.h

index 8f155b3..ea3126d 100644 (file)
@@ -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"))
      {
index 6fef146..bca1610 100644 (file)
@@ -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);
index 5ca19e5..74fb072 100644 (file)
@@ -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);
      }
 }
 
index fbfc633..db75df4 100644 (file)
@@ -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