evas_vg_load_svg: Support multiple gradient without <defs> part

Summary:
Multiple gradients can be declared.
There is a problem of keeping only one gradient information
when it is declared outside defs or when defs is not declared.
It supports the use of multiple gradients even if no defs are declared.

Test Plan:
(with D9312 patch)
cd src/example/edje
edje_cc -beta svg.edc && gcc -o svg-test svg-test.c `pkg-config --libs --cflags evas ecore ecore-evas edje`
./svg-test

Reviewers: Hermet, kimcinoo, smohanty

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D9315
This commit is contained in:
junsu choi 2019-07-15 21:23:38 +09:00 committed by Hermet Park
parent 84fcc5d073
commit 2e4c928d81
3 changed files with 85 additions and 7 deletions

View File

@ -0,0 +1,62 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs>
<linearGradient
id="linearGradient1"
x1="0"
y1="0"
x2="0.2"
y2="0.2"
spreadMethod="reflect">
<stop
style="stop-color:#FF0000;stop-opacity:1;"
offset="0"/>
<stop
style="stop-color:#0000FF;stop-opacity:1;"
offset="1"/>
</linearGradient>
<radialGradient
id="radialGradient1"
r="0.2"
cx="0.3"
cy="0.3"
spreadMethod="reflect">
<stop
style="stop-color:#FFFF00;stop-opacity:1;"
offset="0"/>
<stop
style="stop-color:#00FFFF;stop-opacity:1;"
offset="1"/>
</radialGradient>
</defs>
<linearGradient
id="linearGradient2"
x1="0"
y1="0"
x2="0.2"
y2="0.2"
spreadMethod="reflect">
<stop
style="stop-color:#0F00F0;stop-opacity:1;"
offset="0"/>
<stop
style="stop-color:#0F000F;stop-opacity:1;"
offset="1"/>
</linearGradient>
<radialGradient
id="radialGradient2"
r="0.2"
cx="0.3"
cy="0.3"
spreadMethod="reflect">
<stop
style="stop-color:#00FF00;stop-opacity:1;"
offset="0"/>
<stop
style="stop-color:#FF00FF;stop-opacity:1;"
offset="1"/>
</radialGradient>
<rect x="0" y="0" width="50" height="50" fill="url(#linearGradient1)"/>
<rect x="50" y="0" width="50" height="50" fill="url(#radialGradient1)"/>
<rect x="0" y="50" width="50" height="50" fill="url(#linearGradient2)"/>
<rect x="50" y="50" width="50" height="50" fill="url(#radialGradient2)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -72,6 +72,7 @@ collections {
vector: "favorite_off.svg";
vector: "batman1.svg";
vector: "batman2.svg";
vector: "gradients.svg";
}
group {
name: "svg-test";
@ -104,6 +105,7 @@ collections {
SVG_PART("bg22", "vg22", 0.2, 0.8, .4, 1.0,"favorite_on.svg")
SVG_PART("bg23", "vg23", 0.4, 0.8, .6, 1.0,"favorite_off.svg")
SVG_PART_INTERPOLATE("bg24", "vg24", 0.6, 0.8, .8, 1.0,"batman1.svg", "batman2.svg")
SVG_PART("bg25", "vg25", 0.8, 0.8, 1.0, 1.0,"gradients.svg")
}
programs {
SVG_PROGRAM("bg1", "vg1")
@ -130,6 +132,7 @@ collections {
SVG_PROGRAM("bg22", "vg22")
SVG_PROGRAM("bg23", "vg23")
SVG_PROGRAM("bg24", "vg24")
SVG_PROGRAM("bg25", "vg25")
}
}
}
}

View File

@ -35,7 +35,8 @@ struct _Evas_SVG_Loader
Eina_Array *stack;
Svg_Node *doc;
Svg_Node *def;
Svg_Style_Gradient *gradient;
Eina_List *gradients;
Svg_Style_Gradient *latest_gradient; //for stops
Evas_SVG_Parser *svg_parse;
int level;
Eina_Bool result:1;
@ -2158,11 +2159,21 @@ _evas_svg_loader_xml_open_parser(Evas_SVG_Loader *loader,
{
Svg_Style_Gradient *gradient;
gradient = gradient_method(loader, attrs, attrs_length);
/*FIXME: The current parsing structure does not distinguish end tags.
There is no way to know if the currently parsed gradient is in defs.
If a gradient is declared outside of defs after defs is set, it is included in the gradients of defs.
But finally, the loader has a gradient style list regardless of defs.
This is only to support this when multiple gradients are declared, even if no defs are declared.
refer to: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs */
if (loader->doc->node.doc.defs)
{
loader->def->node.defs.gradients = eina_list_append(loader->def->node.defs.gradients, gradient);
}
loader->gradient = gradient;
else
{
loader->gradients = eina_list_append(loader->gradients, gradient);
}
loader->latest_gradient = gradient;
}
else if (!strcmp(tag_name, "stop"))
{
@ -2172,8 +2183,10 @@ _evas_svg_loader_xml_open_parser(Evas_SVG_Loader *loader,
stop->a = 255;
eina_simple_xml_attributes_parse(attrs, attrs_length,
_attr_parse_stops, loader);
if (loader->gradient)
loader->gradient->stops = eina_list_append(loader->gradient->stops, stop);
if (loader->latest_gradient)
{
loader->latest_gradient->stops = eina_list_append(loader->latest_gradient->stops, stop);
}
}
}
@ -2415,9 +2428,9 @@ evas_vg_load_file_open_svg(Eina_File *file,
_update_gradient(loader.doc, defs->node.defs.gradients);
else
{
if (loader.gradient)
if (loader.gradients)
{
Eina_List* gradient_list = eina_list_append(NULL, loader.gradient);
Eina_List* gradient_list = loader.gradients;
_update_gradient(loader.doc, gradient_list);
eina_list_free(gradient_list);
}