forked from enlightenment/efl
svg_parse: parse correct values for radialGradient
Especially Radius calculation which was a huge pain to find formula within SVG documentations!
This commit is contained in:
parent
f81f031ceb
commit
6bf5d9d96e
|
@ -145,11 +145,18 @@ _gradient_to_double(const char *str, SVG_Parser_Length_Type type)
|
|||
return parsed_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* That is according to Units in here
|
||||
*
|
||||
* https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
|
||||
*/
|
||||
if (type == SVG_PARSER_LENGTH_VERTICAL)
|
||||
max = svg_parse.global.height;
|
||||
else if (type == SVG_PARSER_LENGTH_HORIZONTAL)
|
||||
max = svg_parse.global.width;
|
||||
//TODO: what about radial?
|
||||
else if (type == SVG_PARSER_LENGTH_OTHER)
|
||||
max = sqrt(pow(svg_parse.global.height, 2) +
|
||||
pow(svg_parse.global.width, 2)) / sqrt(2.0);
|
||||
|
||||
if (strstr(str, "cm"))
|
||||
parsed_value = parsed_value * 35.43307;
|
||||
|
@ -169,7 +176,7 @@ _gradient_to_double(const char *str, SVG_Parser_Length_Type type)
|
|||
return parsed_value;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline double
|
||||
_to_offset(const char *str)
|
||||
{
|
||||
char *end = NULL;
|
||||
|
@ -1148,7 +1155,7 @@ _create_circle_node(Svg_Node *parent, const char *buf, unsigned buflen)
|
|||
}
|
||||
|
||||
#define ELLIPSE_DEF(Name, Field, Type) \
|
||||
{ #Name, Type, sizeof (#Name) + sizeof (Type), offsetof(Svg_Ellipse_Node, Field)}
|
||||
{ #Name, Type, sizeof (#Name), offsetof(Svg_Ellipse_Node, Field)}
|
||||
|
||||
static const struct {
|
||||
const char *tag;
|
||||
|
@ -1302,7 +1309,7 @@ _create_polyline_node(Svg_Node *parent, const char *buf, unsigned buflen)
|
|||
}
|
||||
|
||||
#define RECT_DEF(Name, Field, Type) \
|
||||
{ #Name, Type, sizeof (#Name) + sizeof(Type), offsetof(Svg_Rect_Node, Field)}
|
||||
{ #Name, Type, sizeof (#Name), offsetof(Svg_Rect_Node, Field)}
|
||||
|
||||
static const struct {
|
||||
const char *tag;
|
||||
|
@ -1368,7 +1375,7 @@ _create_rect_node(Svg_Node *parent, const char *buf, unsigned buflen)
|
|||
}
|
||||
|
||||
#define LINE_DEF(Name, Field, Type) \
|
||||
{ #Name, Type, sizeof (#Name) + sizeof (Type), offsetof(Svg_Line_Node, Field)}
|
||||
{ #Name, Type, sizeof (#Name), offsetof(Svg_Line_Node, Field)}
|
||||
|
||||
static const struct {
|
||||
const char *tag;
|
||||
|
@ -1690,7 +1697,7 @@ _parse_spread_value(const char *value)
|
|||
static void
|
||||
_handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value)
|
||||
{
|
||||
radial->cx = _to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
|
||||
radial->cx = _gradient_to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
|
||||
if (!svg_parse.gradient.fx_parsed)
|
||||
radial->fx = radial->cx;
|
||||
}
|
||||
|
@ -1698,7 +1705,7 @@ _handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value)
|
|||
static void
|
||||
_handle_radial_cy_attr(Svg_Radial_Gradient* radial, const char *value)
|
||||
{
|
||||
radial->cy = _to_double(value, SVG_PARSER_LENGTH_VERTICAL);
|
||||
radial->cy = _gradient_to_double(value, SVG_PARSER_LENGTH_VERTICAL);
|
||||
if (!svg_parse.gradient.fy_parsed)
|
||||
radial->fy = radial->cy;
|
||||
}
|
||||
|
@ -1706,24 +1713,23 @@ _handle_radial_cy_attr(Svg_Radial_Gradient* radial, const char *value)
|
|||
static void
|
||||
_handle_radial_fx_attr(Svg_Radial_Gradient* radial, const char *value)
|
||||
{
|
||||
radial->fx = _to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
|
||||
radial->fx = _gradient_to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
|
||||
svg_parse.gradient.fx_parsed = EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_handle_radial_fy_attr(Svg_Radial_Gradient* radial, const char *value)
|
||||
{
|
||||
radial->fy = _to_double(value, SVG_PARSER_LENGTH_VERTICAL);
|
||||
radial->fy = _gradient_to_double(value, SVG_PARSER_LENGTH_VERTICAL);
|
||||
svg_parse.gradient.fy_parsed = EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_handle_radial_r_attr(Svg_Radial_Gradient* radial, const char *value)
|
||||
{
|
||||
radial->r = _to_double(value, SVG_PARSER_LENGTH_OTHER);
|
||||
radial->r = _gradient_to_double(value, SVG_PARSER_LENGTH_OTHER);
|
||||
}
|
||||
|
||||
|
||||
typedef void (*Radial_Method)(Svg_Radial_Gradient *radial, const char *value);
|
||||
|
||||
#define RADIAL_DEF(Name) \
|
||||
|
@ -1768,9 +1774,9 @@ _attr_parse_radial_gradient_node(void *data, const char *key, const char *value)
|
|||
{
|
||||
grad->ref = _id_from_href(value);
|
||||
}
|
||||
else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse"))
|
||||
else if (!strcmp(key, "gradientUnits") && !strcmp(value, "objectBoundingBox"))
|
||||
{
|
||||
grad->user_space = EINA_TRUE;
|
||||
grad->user_space = EINA_FALSE;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
|
@ -1782,6 +1788,7 @@ _create_radialGradient(const char *buf, unsigned buflen)
|
|||
Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient));
|
||||
|
||||
grad->type = SVG_RADIAL_GRADIENT;
|
||||
grad->user_space = EINA_TRUE;
|
||||
grad->radial = calloc(1, sizeof(Svg_Radial_Gradient));
|
||||
|
||||
svg_parse.gradient.fx_parsed = EINA_FALSE;
|
||||
|
@ -1946,7 +1953,7 @@ _attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
|
|||
{
|
||||
grad->ref = _id_from_href(value);
|
||||
}
|
||||
else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse"))
|
||||
else if (!strcmp(key, "gradientUnits") && !strcmp(value, "objectBoundingBox"))
|
||||
{
|
||||
grad->user_space = EINA_TRUE;
|
||||
}
|
||||
|
@ -1961,6 +1968,7 @@ _create_linearGradient(const char *buf, unsigned buflen)
|
|||
unsigned int i;
|
||||
|
||||
grad->type = SVG_LINEAR_GRADIENT;
|
||||
grad->user_space = EINA_TRUE;
|
||||
grad->linear = calloc(1, sizeof(Svg_Linear_Gradient));
|
||||
/**
|
||||
* Default value of x2 is 100%
|
||||
|
|
|
@ -573,10 +573,16 @@ _apply_gradient_property(Svg_Style_Gradient *g, Efl_VG *vg, Vg_File_Data *vg_dat
|
|||
}
|
||||
else if (g->type == SVG_RADIAL_GRADIENT)
|
||||
{
|
||||
/**
|
||||
* That is according to Units in here
|
||||
*
|
||||
* https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
|
||||
*/
|
||||
int radius = sqrt(pow(r.h, 2) + pow(r.w, 2)) / sqrt(2.0);
|
||||
grad_obj = evas_vg_gradient_radial_add(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);
|
||||
evas_vg_gradient_radial_center_set(grad_obj, g->radial->cx * r.w + r.x, g->radial->cy * r.h + r.y);
|
||||
evas_vg_gradient_radial_radius_set(grad_obj, g->radial->r * radius);
|
||||
evas_vg_gradient_radial_focal_set(grad_obj, g->radial->fx * r.w + r.x, g->radial->fy * r.h + r.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue