diff options
author | Vitalii Vorobiov <vi.vorobiov@samsung.com> | 2017-02-22 13:02:31 +0200 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-11-07 11:54:09 +0900 |
commit | 6bf5d9d96ef07dcd12f5c9e7ceaa1dbcca046206 (patch) | |
tree | a5cd44abe6e649f6c0aa009c9ad4e07d0187daad | |
parent | f81f031ceb799f22bd8b6ea216a9b565244af12c (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.c | 36 | ||||
-rw-r--r-- | src/static_libs/vg_common/vg_common.c | 12 |
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 | ||
172 | static inline int | 179 | static 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 | ||
1153 | static const struct { | 1160 | static 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 | ||
1307 | static const struct { | 1314 | static 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 | ||
1373 | static const struct { | 1380 | static const struct { |
1374 | const char *tag; | 1381 | const char *tag; |
@@ -1690,7 +1697,7 @@ _parse_spread_value(const char *value) | |||
1690 | static void | 1697 | static 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) | |||
1698 | static void | 1705 | static 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) | |||
1706 | static void | 1713 | static 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 | ||
1713 | static void | 1720 | static 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 | ||
1720 | static void | 1727 | static 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 | |||
1727 | typedef void (*Radial_Method)(Svg_Radial_Gradient *radial, const char *value); | 1733 | typedef 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 | { |