edje: fix parsing and and visualizing gradients.

Reviewers: jpeg, cedric

Subscribers: cedric, jpeg

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

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
Subhransu Mohanty 2016-07-06 12:51:56 -07:00 committed by Cedric BAIL
parent ddeab76da0
commit 522b82b026
4 changed files with 155 additions and 34 deletions

View File

@ -1269,6 +1269,29 @@ _find_child_by_id(Svg_Node *node, char *id)
return NULL;
}
static Eina_List *
_clone_grad_stops(Eina_List *from)
{
Efl_Gfx_Gradient_Stop *stop;
Eina_List *l;
Eina_List *res = NULL;
EINA_LIST_FOREACH(from, l, stop)
{
Efl_Gfx_Gradient_Stop *new_stop;
new_stop = calloc(1, sizeof(Efl_Gfx_Gradient_Stop));
new_stop->r = stop->r;
new_stop->g = stop->g;
new_stop->b = stop->b;
new_stop->a = stop->a;
res = eina_list_append(res, new_stop);
}
return res;
}
static Svg_Style_Gradient *
_clone_gradient(Svg_Style_Gradient *from)
{
@ -1279,8 +1302,9 @@ _clone_gradient(Svg_Style_Gradient *from)
grad= calloc(1, sizeof(Svg_Style_Gradient));
grad->type = from->type;
grad->id = _copy_id(from->id);
grad->ref = _copy_id(from->ref);
grad->spread = from->spread;
grad->stops = eina_list_clone(from->stops);
grad->stops = _clone_grad_stops(from->stops);
if (grad->type == SVG_LINEAR_GRADIENT)
{
grad->linear = calloc(1, sizeof(Svg_Linear_Gradient));
@ -1313,9 +1337,6 @@ _copy_attribute(Svg_Node *to, Svg_Node *from)
}
// copy style attribute;
memcpy(to->style, from->style, sizeof(Svg_Style_Property));
// copy gradient
to->style->fill.gradient = _clone_gradient(from->style->fill.gradient);
to->style->stroke.gradient = _clone_gradient(from->style->stroke.gradient);
// copy node attribute
switch (from->type)
@ -1448,6 +1469,23 @@ static const struct {
FIND_FACTORY(group, group_tags);
FIND_FACTORY(graphics, graphics_tags);
Efl_Gfx_Gradient_Spread
_parse_spread_value(const char *value)
{
Efl_Gfx_Gradient_Spread spread = EFL_GFX_GRADIENT_SPREAD_PAD;
if (!strcmp(value, "reflect"))
{
spread = EFL_GFX_GRADIENT_SPREAD_REFLECT;
}
else if (!strcmp(value, "repeat"))
{
spread = EFL_GFX_GRADIENT_SPREAD_REPEAT;
}
return spread;
}
static void
_handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value)
{
@ -1512,7 +1550,17 @@ _attr_parse_radial_gradient_node(void *data, const char *key, const char *value)
}
if (!strcmp(key, "id"))
grad->id = _copy_id(value);
{
grad->id = _copy_id(value);
}
else if (!strcmp(key, "spreadMethod"))
{
grad->spread = _parse_spread_value(value);
}
else if (!strcmp(key, "xlink:href"))
{
grad->ref = _id_from_href(value);
}
return EINA_TRUE;
}
@ -1547,6 +1595,12 @@ _attr_parse_stops(void *data, const char *key, const char *value)
{
_to_color(value, &stop->r, &stop->g, &stop->b, NULL);
}
else if (!strcmp(key, "style"))
{
eina_simple_xml_attribute_w3c_parse(value,
_attr_parse_stops, data);
}
return EINA_TRUE;
}
@ -1599,7 +1653,7 @@ _attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
unsigned int i;
int sz = strlen(key);
for (i = 0; i < sizeof (radial_tags) / sizeof(linear_tags[0]); i++)
for (i = 0; i < sizeof (linear_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);
@ -1610,6 +1664,14 @@ _attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
{
grad->id = _copy_id(value);
}
else if (!strcmp(key, "spreadMethod"))
{
grad->spread = _parse_spread_value(value);
}
else if (!strcmp(key, "xlink:href"))
{
grad->ref = _id_from_href(value);
}
return EINA_TRUE;
}
@ -1763,11 +1825,6 @@ _evas_svg_loader_xml_close_parser(Evas_SVG_Loader *loader,
break ;
}
if (!strncmp(content, "linearGradient", 13))
{
//TODO
}
loader->level--;
}
@ -1870,6 +1927,67 @@ _update_style(Svg_Node *node, Svg_Style_Property *parent_style)
}
}
static Svg_Style_Gradient*
_dup_gradient(Eina_List *grad_list, const char *id)
{
Svg_Style_Gradient *grad;
Svg_Style_Gradient *result = NULL;
Eina_List *l;
EINA_LIST_FOREACH(grad_list, l, grad)
{
if (!strcmp(grad->id, id))
{
result = _clone_gradient(grad);
break;
}
}
if (result && result->ref)
{
EINA_LIST_FOREACH(grad_list, l, grad)
{
if (!strcmp(grad->id, result->ref))
{
if (!result->stops)
{
result->stops = _clone_grad_stops(grad->stops);
}
//TODO properly inherit other property
break;
}
}
}
return result;
}
void
_update_gradient(Svg_Node *node, Eina_List *grad_list)
{
Eina_List *l;
Svg_Node *child;
if (node->child)
{
EINA_LIST_FOREACH(node->child, l, child)
{
_update_gradient(child, grad_list);
}
}
else
{
if (node->style->fill.paint.url)
{
node->style->fill.paint.gradient = _dup_gradient(grad_list, node->style->fill.paint.url);
}
else if (node->style->stroke.paint.url)
{
node->style->stroke.paint.gradient = _dup_gradient(grad_list, node->style->stroke.paint.url);
}
}
}
EAPI Svg_Node *
_svg_load(Eina_File *f, const char *key EINA_UNUSED)
{
@ -1878,6 +1996,7 @@ _svg_load(Eina_File *f, const char *key EINA_UNUSED)
};
const char *content;
unsigned int length;
Svg_Node *defs;
if (!f) return NULL;
@ -1894,7 +2013,12 @@ _svg_load(Eina_File *f, const char *key EINA_UNUSED)
}
if (loader.doc)
_update_style(loader.doc, NULL);
{
_update_style(loader.doc, NULL);
defs = loader.doc->node.doc.defs;
if (defs)
_update_gradient(loader.doc, defs->node.defs.gradients);
}
return loader.doc;
}

View File

@ -248,24 +248,24 @@ _eet_for_style_property(void)
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);
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_SUB(eet, Svg_Style_Property, "fill.paint.gradient", fill.paint.gradient, eet_gradient);
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);
// 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);
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_SUB(eet, Svg_Style_Property, "stroke.paint.gradient", stroke.paint.gradient, eet_gradient);
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);

View File

@ -2318,22 +2318,22 @@ _cb_signal_repeat(void *data, Evas_Object *obj, const char *sig, const char *sou
}
static Efl_VG *
_apply_gradient_property(Efl_VG *parent, Svg_Style_Gradient *g)
_apply_gradient_property(Svg_Style_Gradient *g)
{
Efl_VG *grad_obj = NULL;
Efl_Gfx_Gradient_Stop *stops, *stop;
int stop_count = 0;
int stop_count = 0, i = 0;
Eina_List *l;
if (g->type == SVG_LINEAR_GRADIENT)
{
grad_obj = eo_add(EFL_VG_GRADIENT_LINEAR_CLASS, parent);
grad_obj = eo_add(EFL_VG_GRADIENT_LINEAR_CLASS, NULL);
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);
grad_obj = eo_add(EFL_VG_GRADIENT_RADIAL_CLASS, NULL);
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);
@ -2350,13 +2350,15 @@ _apply_gradient_property(Efl_VG *parent, Svg_Style_Gradient *g)
if (stop_count)
{
stops = calloc(stop_count, sizeof(Efl_Gfx_Gradient_Stop));
i = 0;
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;
stops[i].r = stop->r;
stops[i].g = stop->g;
stops[i].b = stop->b;
stops[i].a = stop->a;
stops[i].offset = stop->offset;
i++;
}
evas_vg_gradient_stop_set(grad_obj, stops, stop_count);
free(stops);
@ -2387,15 +2389,10 @@ _apply_vg_property(Svg_Node *node, Efl_VG *vg)
{
//do nothing
}
else if (style->fill.gradient)
else if (style->fill.paint.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
evas_vg_shape_fill_set(vg, _apply_gradient_property(style->fill.paint.gradient));
}
else if (style->fill.paint.cur_color)
{
@ -2420,10 +2417,10 @@ _apply_vg_property(Svg_Node *node, Efl_VG *vg)
{
//do nothing
}
else if (style->stroke.gradient)
else if (style->stroke.paint.gradient)
{
// if the fill has gradient then apply.
evas_vg_shape_stroke_fill_set(vg, _apply_gradient_property(vg, style->stroke.gradient));
evas_vg_shape_stroke_fill_set(vg, _apply_gradient_property(style->stroke.paint.gradient));
}
else if (style->stroke.paint.url)
{

View File

@ -3158,6 +3158,7 @@ struct _Svg_Style_Gradient
{
Svg_Gradient_Type type;
char *id;
char *ref;
Efl_Gfx_Gradient_Spread spread;
Eina_List *stops; // Efl_Gfx_Gradient_Stop
Svg_Radial_Gradient *radial;
@ -3171,6 +3172,7 @@ struct _Svg_Paint
int b;
Eina_Bool none;
Eina_Bool cur_color;
Svg_Style_Gradient *gradient;
char *url;
};
@ -3199,7 +3201,6 @@ struct _Svg_Style_Fill
Svg_Fill_Flags flags;
Svg_Paint paint;
int opacity;
Svg_Style_Gradient *gradient;
Efl_Gfx_Fill_Rule fill_rule;
};
@ -3208,7 +3209,6 @@ struct _Svg_Style_Stroke
Svg_Stroke_Flags flags;
Svg_Paint paint;
int opacity;
Svg_Style_Gradient *gradient;
double scale;
double width;
double centered;