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)
{
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));
}
// 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)
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)
{
}
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;
}
{
_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;
}
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);
{
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;
}
break ;
}
- if (!strncmp(content, "linearGradient", 13))
- {
- //TODO
- }
-
loader->level--;
}
}
}
+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)
{
};
const char *content;
unsigned int length;
+ Svg_Node *defs;
if (!f) return NULL;
}
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;
}
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);
}
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);
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);
{
//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)
{
{
//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)
{
{
Svg_Gradient_Type type;
char *id;
+ char *ref;
Efl_Gfx_Gradient_Spread spread;
Eina_List *stops; // Efl_Gfx_Gradient_Stop
Svg_Radial_Gradient *radial;
int b;
Eina_Bool none;
Eina_Bool cur_color;
+ Svg_Style_Gradient *gradient;
char *url;
};
Svg_Fill_Flags flags;
Svg_Paint paint;
int opacity;
- Svg_Style_Gradient *gradient;
Efl_Gfx_Fill_Rule fill_rule;
};
Svg_Stroke_Flags flags;
Svg_Paint paint;
int opacity;
- Svg_Style_Gradient *gradient;
double scale;
double width;
double centered;