summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitalii Vorobiov <vi.vorobiov@samsung.com>2017-02-22 13:02:31 +0200
committerJean-Philippe Andre <jp.andre@samsung.com>2017-11-07 11:54:09 +0900
commit6bf5d9d96ef07dcd12f5c9e7ceaa1dbcca046206 (patch)
treea5cd44abe6e649f6c0aa009c9ad4e07d0187daad
parentf81f031ceb799f22bd8b6ea216a9b565244af12c (diff)
svg_parse: parse correct values for radialGradient
Especially Radius calculation which was a huge pain to find formula within SVG documentations!
-rw-r--r--src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c36
-rw-r--r--src/static_libs/vg_common/vg_common.c12
2 files changed, 31 insertions, 17 deletions
diff --git a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c
index ff1b2d8e2d..36e5d14409 100644
--- a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c
+++ b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c
@@ -145,11 +145,18 @@ _gradient_to_double(const char *str, SVG_Parser_Length_Type type)
145 return parsed_value; 145 return parsed_value;
146 } 146 }
147 147
148 /**
149 * That is according to Units in here
150 *
151 * https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
152 */
148 if (type == SVG_PARSER_LENGTH_VERTICAL) 153 if (type == SVG_PARSER_LENGTH_VERTICAL)
149 max = svg_parse.global.height; 154 max = svg_parse.global.height;
150 else if (type == SVG_PARSER_LENGTH_HORIZONTAL) 155 else if (type == SVG_PARSER_LENGTH_HORIZONTAL)
151 max = svg_parse.global.width; 156 max = svg_parse.global.width;
152 //TODO: what about radial? 157 else if (type == SVG_PARSER_LENGTH_OTHER)
158 max = sqrt(pow(svg_parse.global.height, 2) +
159 pow(svg_parse.global.width, 2)) / sqrt(2.0);
153 160
154 if (strstr(str, "cm")) 161 if (strstr(str, "cm"))
155 parsed_value = parsed_value * 35.43307; 162 parsed_value = parsed_value * 35.43307;
@@ -169,7 +176,7 @@ _gradient_to_double(const char *str, SVG_Parser_Length_Type type)
169 return parsed_value; 176 return parsed_value;
170} 177}
171 178
172static inline int 179static inline double
173_to_offset(const char *str) 180_to_offset(const char *str)
174{ 181{
175 char *end = NULL; 182 char *end = NULL;
@@ -1148,7 +1155,7 @@ _create_circle_node(Svg_Node *parent, const char *buf, unsigned buflen)
1148} 1155}
1149 1156
1150#define ELLIPSE_DEF(Name, Field, Type) \ 1157#define ELLIPSE_DEF(Name, Field, Type) \
1151 { #Name, Type, sizeof (#Name) + sizeof (Type), offsetof(Svg_Ellipse_Node, Field)} 1158 { #Name, Type, sizeof (#Name), offsetof(Svg_Ellipse_Node, Field)}
1152 1159
1153static const struct { 1160static const struct {
1154 const char *tag; 1161 const char *tag;
@@ -1302,7 +1309,7 @@ _create_polyline_node(Svg_Node *parent, const char *buf, unsigned buflen)
1302} 1309}
1303 1310
1304#define RECT_DEF(Name, Field, Type) \ 1311#define RECT_DEF(Name, Field, Type) \
1305 { #Name, Type, sizeof (#Name) + sizeof(Type), offsetof(Svg_Rect_Node, Field)} 1312 { #Name, Type, sizeof (#Name), offsetof(Svg_Rect_Node, Field)}
1306 1313
1307static const struct { 1314static const struct {
1308 const char *tag; 1315 const char *tag;
@@ -1368,7 +1375,7 @@ _create_rect_node(Svg_Node *parent, const char *buf, unsigned buflen)
1368} 1375}
1369 1376
1370#define LINE_DEF(Name, Field, Type) \ 1377#define LINE_DEF(Name, Field, Type) \
1371 { #Name, Type, sizeof (#Name) + sizeof (Type), offsetof(Svg_Line_Node, Field)} 1378 { #Name, Type, sizeof (#Name), offsetof(Svg_Line_Node, Field)}
1372 1379
1373static const struct { 1380static const struct {
1374 const char *tag; 1381 const char *tag;
@@ -1690,7 +1697,7 @@ _parse_spread_value(const char *value)
1690static void 1697static void
1691_handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value) 1698_handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value)
1692{ 1699{
1693 radial->cx = _to_double(value, SVG_PARSER_LENGTH_HORIZONTAL); 1700 radial->cx = _gradient_to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
1694 if (!svg_parse.gradient.fx_parsed) 1701 if (!svg_parse.gradient.fx_parsed)
1695 radial->fx = radial->cx; 1702 radial->fx = radial->cx;
1696} 1703}
@@ -1698,7 +1705,7 @@ _handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value)
1698static void 1705static void
1699_handle_radial_cy_attr(Svg_Radial_Gradient* radial, const char *value) 1706_handle_radial_cy_attr(Svg_Radial_Gradient* radial, const char *value)
1700{ 1707{
1701 radial->cy = _to_double(value, SVG_PARSER_LENGTH_VERTICAL); 1708 radial->cy = _gradient_to_double(value, SVG_PARSER_LENGTH_VERTICAL);
1702 if (!svg_parse.gradient.fy_parsed) 1709 if (!svg_parse.gradient.fy_parsed)
1703 radial->fy = radial->cy; 1710 radial->fy = radial->cy;
1704} 1711}
@@ -1706,24 +1713,23 @@ _handle_radial_cy_attr(Svg_Radial_Gradient* radial, const char *value)
1706static void 1713static void
1707_handle_radial_fx_attr(Svg_Radial_Gradient* radial, const char *value) 1714_handle_radial_fx_attr(Svg_Radial_Gradient* radial, const char *value)
1708{ 1715{
1709 radial->fx = _to_double(value, SVG_PARSER_LENGTH_HORIZONTAL); 1716 radial->fx = _gradient_to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
1710 svg_parse.gradient.fx_parsed = EINA_TRUE; 1717 svg_parse.gradient.fx_parsed = EINA_TRUE;
1711} 1718}
1712 1719
1713static void 1720static void
1714_handle_radial_fy_attr(Svg_Radial_Gradient* radial, const char *value) 1721_handle_radial_fy_attr(Svg_Radial_Gradient* radial, const char *value)
1715{ 1722{
1716 radial->fy = _to_double(value, SVG_PARSER_LENGTH_VERTICAL); 1723 radial->fy = _gradient_to_double(value, SVG_PARSER_LENGTH_VERTICAL);
1717 svg_parse.gradient.fy_parsed = EINA_TRUE; 1724 svg_parse.gradient.fy_parsed = EINA_TRUE;
1718} 1725}
1719 1726
1720static void 1727static void
1721_handle_radial_r_attr(Svg_Radial_Gradient* radial, const char *value) 1728_handle_radial_r_attr(Svg_Radial_Gradient* radial, const char *value)
1722{ 1729{
1723 radial->r = _to_double(value, SVG_PARSER_LENGTH_OTHER); 1730 radial->r = _gradient_to_double(value, SVG_PARSER_LENGTH_OTHER);
1724} 1731}
1725 1732
1726
1727typedef void (*Radial_Method)(Svg_Radial_Gradient *radial, const char *value); 1733typedef void (*Radial_Method)(Svg_Radial_Gradient *radial, const char *value);
1728 1734
1729#define RADIAL_DEF(Name) \ 1735#define RADIAL_DEF(Name) \
@@ -1768,9 +1774,9 @@ _attr_parse_radial_gradient_node(void *data, const char *key, const char *value)
1768 { 1774 {
1769 grad->ref = _id_from_href(value); 1775 grad->ref = _id_from_href(value);
1770 } 1776 }
1771 else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) 1777 else if (!strcmp(key, "gradientUnits") && !strcmp(value, "objectBoundingBox"))
1772 { 1778 {
1773 grad->user_space = EINA_TRUE; 1779 grad->user_space = EINA_FALSE;
1774 } 1780 }
1775 1781
1776 return EINA_TRUE; 1782 return EINA_TRUE;
@@ -1782,6 +1788,7 @@ _create_radialGradient(const char *buf, unsigned buflen)
1782 Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient)); 1788 Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient));
1783 1789
1784 grad->type = SVG_RADIAL_GRADIENT; 1790 grad->type = SVG_RADIAL_GRADIENT;
1791 grad->user_space = EINA_TRUE;
1785 grad->radial = calloc(1, sizeof(Svg_Radial_Gradient)); 1792 grad->radial = calloc(1, sizeof(Svg_Radial_Gradient));
1786 1793
1787 svg_parse.gradient.fx_parsed = EINA_FALSE; 1794 svg_parse.gradient.fx_parsed = EINA_FALSE;
@@ -1946,7 +1953,7 @@ _attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
1946 { 1953 {
1947 grad->ref = _id_from_href(value); 1954 grad->ref = _id_from_href(value);
1948 } 1955 }
1949 else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) 1956 else if (!strcmp(key, "gradientUnits") && !strcmp(value, "objectBoundingBox"))
1950 { 1957 {
1951 grad->user_space = EINA_TRUE; 1958 grad->user_space = EINA_TRUE;
1952 } 1959 }
@@ -1961,6 +1968,7 @@ _create_linearGradient(const char *buf, unsigned buflen)
1961 unsigned int i; 1968 unsigned int i;
1962 1969
1963 grad->type = SVG_LINEAR_GRADIENT; 1970 grad->type = SVG_LINEAR_GRADIENT;
1971 grad->user_space = EINA_TRUE;
1964 grad->linear = calloc(1, sizeof(Svg_Linear_Gradient)); 1972 grad->linear = calloc(1, sizeof(Svg_Linear_Gradient));
1965 /** 1973 /**
1966 * Default value of x2 is 100% 1974 * Default value of x2 is 100%
diff --git a/src/static_libs/vg_common/vg_common.c b/src/static_libs/vg_common/vg_common.c
index eb6c992652..7b33053ed0 100644
--- a/src/static_libs/vg_common/vg_common.c
+++ b/src/static_libs/vg_common/vg_common.c
@@ -573,10 +573,16 @@ _apply_gradient_property(Svg_Style_Gradient *g, Efl_VG *vg, Vg_File_Data *vg_dat
573 } 573 }
574 else if (g->type == SVG_RADIAL_GRADIENT) 574 else if (g->type == SVG_RADIAL_GRADIENT)
575 { 575 {
576 /**
577 * That is according to Units in here
578 *
579 * https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
580 */
581 int radius = sqrt(pow(r.h, 2) + pow(r.w, 2)) / sqrt(2.0);
576 grad_obj = evas_vg_gradient_radial_add(NULL); 582 grad_obj = evas_vg_gradient_radial_add(NULL);
577 evas_vg_gradient_radial_center_set(grad_obj, g->radial->cx, g->radial->cy); 583 evas_vg_gradient_radial_center_set(grad_obj, g->radial->cx * r.w + r.x, g->radial->cy * r.h + r.y);
578 evas_vg_gradient_radial_radius_set(grad_obj, g->radial->r); 584 evas_vg_gradient_radial_radius_set(grad_obj, g->radial->r * radius);
579 evas_vg_gradient_radial_focal_set(grad_obj, g->radial->fx, g->radial->fy); 585 evas_vg_gradient_radial_focal_set(grad_obj, g->radial->fx * r.w + r.x, g->radial->fy * r.h + r.y);
580 } 586 }
581 else 587 else
582 { 588 {