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:
parent
ddeab76da0
commit
522b82b026
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue