svg_parse: Change initial value of gradientUnits of linearGradient

Summary:
The initial value of gradientUnits is objectBoundingBox.
If userSpaceOnUse is declared, change user_space to true.
We do not have to recalculate each value by this change.
The default unit for linear x1, y1, x2, y2 is percentages.
This can be a value from 0 to 1. If svg want to use a value between 0 and 100, it must have a '%' symbol

That is accroding to gradientUnits in here
https://www.w3.org/TR/2015/WD-SVG2-20150915/pservers.html#LinearGradientElementGradientUnitsAttribute

Test Plan:
cd ./src/examples/edje
edje_cc -beta svg.edc && gcc -o svg-test svg-test.c `pkg-config --libs --cflags evas ecore ecore-evas edje`

Reviewers: Hermet, smohanty

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D8589
This commit is contained in:
junsu choi 2019-04-10 18:03:05 +09:00 committed by Hermet Park
parent 96e6d307b8
commit 8ef6c422af
1 changed files with 6 additions and 73 deletions

View File

@ -20,7 +20,6 @@ struct _Evas_SVG_Parser {
int x, y, width, height; int x, y, width, height;
} global; } global;
struct { struct {
Eina_Bool x1_percent, x2_percent, y1_percent, y2_percent;
Eina_Bool fx_parsed; Eina_Bool fx_parsed;
Eina_Bool fy_parsed; Eina_Bool fy_parsed;
} gradient; } gradient;
@ -1790,9 +1789,9 @@ _attr_parse_radial_gradient_node(void *data, const char *key, const char *value)
{ {
grad->ref = _id_from_href(value); grad->ref = _id_from_href(value);
} }
else if (!strcmp(key, "gradientUnits") && !strcmp(value, "objectBoundingBox")) else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse"))
{ {
grad->user_space = EINA_FALSE; grad->user_space = EINA_TRUE;
} }
return EINA_TRUE; return EINA_TRUE;
@ -1805,7 +1804,7 @@ _create_radialGradient(Evas_SVG_Loader *loader, const char *buf, unsigned buflen
loader->svg_parse->style_grad = grad; loader->svg_parse->style_grad = grad;
grad->type = SVG_RADIAL_GRADIENT; grad->type = SVG_RADIAL_GRADIENT;
grad->user_space = EINA_TRUE; grad->user_space = EINA_FALSE;
grad->radial = calloc(1, sizeof(Svg_Radial_Gradient)); grad->radial = calloc(1, sizeof(Svg_Radial_Gradient));
/** /**
* Default values of gradient * Default values of gradient
@ -1855,95 +1854,35 @@ static void
_handle_linear_x1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value) _handle_linear_x1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value)
{ {
linear->x1 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL); linear->x1 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL);
if (strstr(value, "%"))
loader->svg_parse->gradient.x1_percent = EINA_TRUE;
} }
static void static void
_handle_linear_y1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value) _handle_linear_y1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value)
{ {
linear->y1 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL); linear->y1 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL);
if (strstr(value, "%"))
loader->svg_parse->gradient.y1_percent = EINA_TRUE;
} }
static void static void
_handle_linear_x2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value) _handle_linear_x2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value)
{ {
linear->x2 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL); linear->x2 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL);
/* checking if there are no percentage because x2 have default value
* already set in percentages (100%) */
if (!strstr(value, "%"))
loader->svg_parse->gradient.x2_percent = EINA_FALSE;
} }
static void static void
_handle_linear_y2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value) _handle_linear_y2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, const char *value)
{ {
linear->y2 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL); linear->y2 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL);
if (strstr(value, "%"))
loader->svg_parse->gradient.y2_percent = EINA_TRUE;
}
static void
_recalc_linear_x1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
if (!loader->svg_parse->gradient.x1_percent && !user_space)
{
/* Since previous percentage is not required (it was already percent)
* so oops and make it all back */
linear->x1 = linear->x1 * loader->svg_parse->global.width;
}
loader->svg_parse->gradient.x1_percent = EINA_FALSE;
}
static void
_recalc_linear_y1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
if (!loader->svg_parse->gradient.y1_percent && !user_space)
{
/* Since previous percentage is not required (it was already percent)
* so oops and make it all back */
linear->y1 = linear->y1 * loader->svg_parse->global.height;
}
loader->svg_parse->gradient.y1_percent = EINA_FALSE;
}
static void
_recalc_linear_x2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
if (!loader->svg_parse->gradient.x2_percent && !user_space)
{
/* Since previous percentage is not required (it was already percent)
* so oops and make it all back */
linear->x2 = linear->x2 * loader->svg_parse->global.width;
}
loader->svg_parse->gradient.x2_percent = EINA_FALSE;
}
static void
_recalc_linear_y2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
if (!loader->svg_parse->gradient.y2_percent && !user_space)
{
/* Since previous percentage is not required (it was already percent)
* so oops and make it all back */
linear->y2 = linear->y2 * loader->svg_parse->global.height;
}
loader->svg_parse->gradient.y2_percent = EINA_FALSE;
} }
typedef void (*Linear_Method)(Evas_SVG_Loader *loader, Svg_Linear_Gradient *linear, const char *value); typedef void (*Linear_Method)(Evas_SVG_Loader *loader, Svg_Linear_Gradient *linear, const char *value);
typedef void (*Linear_Method_Recalc)(Evas_SVG_Loader *loader, Svg_Linear_Gradient *linear, Eina_Bool user_space);
#define LINEAR_DEF(Name) \ #define LINEAR_DEF(Name) \
{ #Name, sizeof (#Name), _handle_linear_##Name##_attr, _recalc_linear_##Name##_attr} { #Name, sizeof (#Name), _handle_linear_##Name##_attr}
static const struct { static const struct {
const char *tag; const char *tag;
int sz; int sz;
Linear_Method tag_handler;; Linear_Method tag_handler;;
Linear_Method_Recalc tag_recalc;;
} linear_tags[] = { } linear_tags[] = {
LINEAR_DEF(x1), LINEAR_DEF(x1),
LINEAR_DEF(y1), LINEAR_DEF(y1),
@ -1979,7 +1918,7 @@ _attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
{ {
grad->ref = _id_from_href(value); grad->ref = _id_from_href(value);
} }
else if (!strcmp(key, "gradientUnits") && !strcmp(value, "objectBoundingBox")) else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse"))
{ {
grad->user_space = EINA_TRUE; grad->user_space = EINA_TRUE;
} }
@ -1993,22 +1932,16 @@ _create_linearGradient(Evas_SVG_Loader *loader, const char *buf, unsigned buflen
Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient)); Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient));
loader->svg_parse->style_grad = grad; loader->svg_parse->style_grad = grad;
unsigned int i;
grad->type = SVG_LINEAR_GRADIENT; grad->type = SVG_LINEAR_GRADIENT;
grad->user_space = EINA_TRUE; grad->user_space = EINA_FALSE;
grad->linear = calloc(1, sizeof(Svg_Linear_Gradient)); grad->linear = calloc(1, sizeof(Svg_Linear_Gradient));
/** /**
* Default value of x2 is 100% * Default value of x2 is 100%
*/ */
grad->linear->x2 = 1; grad->linear->x2 = 1;
loader->svg_parse->gradient.x2_percent = EINA_TRUE;
eina_simple_xml_attributes_parse(buf, buflen, eina_simple_xml_attributes_parse(buf, buflen,
_attr_parse_linear_gradient_node, loader); _attr_parse_linear_gradient_node, loader);
for (i = 0; i < sizeof (linear_tags) / sizeof(linear_tags[0]); i++)
linear_tags[i].tag_recalc(loader, grad->linear, grad->user_space);
return loader->svg_parse->style_grad; return loader->svg_parse->style_grad;
} }