summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitalii Vorobiov <vi.vorobiov@samsung.com>2017-11-07 11:41:36 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-11-07 11:54:09 +0900
commitee93543799fc4ccf72a0cbf43a2c3efe5c61d6d3 (patch)
treeaba6f64632b450ff67ef3fde881a757715b93ba7
parent66e0caccb7cfc15daf362c75f1b28689d2d2ab02 (diff)
evas_vg_load_svg: get rid of static Evas_SVG_Parsing
Summary: Refactoring. It is good to store values from that struct in a parsing/loading context static variable is a big NO NO: 1. Ugly code design, 2. Might not work when trying to load more than one SVG file. @fix Reviewers: jpeg, smohanty Subscribers: jenkins, cedric Differential Revision: https://phab.enlightenment.org/D5399
-rw-r--r--src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c400
1 files changed, 214 insertions, 186 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 cec86e6eae..867d95c9df 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
@@ -13,9 +13,22 @@ static int _evas_vg_loader_svg_log_dom = -1;
#endif
#define INF(...) EINA_LOG_DOM_INFO(_evas_vg_loader_svg_log_dom, __VA_ARGS__)
-typedef Svg_Node *(*Factory_Method)(Svg_Node *parent, const char *buf, unsigned buflen);
+/* Global struct for working global cases during the parse */
+typedef struct _Evas_SVG_Parser Evas_SVG_Parser;
+struct _Evas_SVG_Parser {
+ struct {
+ int x, y, width, height;
+ } global;
+ struct {
+ Eina_Bool x1_percent, x2_percent, y1_percent, y2_percent;
+ Eina_Bool fx_parsed;
+ Eina_Bool fy_parsed;
+ } gradient;
-typedef Svg_Style_Gradient *(*Gradient_Factory_Method)(const char *buf, unsigned buflen);
+ Svg_Node *node;
+ Svg_Style_Gradient *style_grad;
+ Efl_Gfx_Gradient_Stop *grad_stop;
+};
typedef struct _Evas_SVG_Loader Evas_SVG_Loader;
struct _Evas_SVG_Loader
@@ -24,10 +37,16 @@ struct _Evas_SVG_Loader
Svg_Node *doc;
Svg_Node *def;
Svg_Style_Gradient *gradient;
+ Evas_SVG_Parser *svg_parse;
int level;
Eina_Bool result:1;
};
+
+typedef Svg_Node *(*Factory_Method)(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen);
+
+typedef Svg_Style_Gradient *(*Gradient_Factory_Method)(Evas_SVG_Loader *loader, const char *buf, unsigned buflen);
+
/* length type to recalculate %, pt, pc, mm, cm etc*/
typedef enum {
SVG_PARSER_LENGTH_VERTICAL,
@@ -36,19 +55,6 @@ typedef enum {
SVG_PARSER_LENGTH_OTHER
} SVG_Parser_Length_Type;
-/* Global struct for working global cases during the parse */
-typedef struct {
- struct {
- int x, y, width, height;
- } global;
- struct {
- Eina_Bool x1_percent, x2_percent, y1_percent, y2_percent;
- Eina_Bool fx_parsed;
- Eina_Bool fy_parsed;
- } gradient;
-} Evas_SVG_Parsing;
-static Evas_SVG_Parsing svg_parse;
-
char *
_skip_space(const char *str, const char *end)
{
@@ -94,7 +100,7 @@ _parse_number(const char **content, double *number)
* is required, but for now default w3 constants would be used
*/
static inline double
-_to_double(const char *str, SVG_Parser_Length_Type type)
+_to_double(Evas_SVG_Parser *svg_parse, const char *str, SVG_Parser_Length_Type type)
{
double parsed_value = strtod(str, NULL);
@@ -111,13 +117,13 @@ _to_double(const char *str, SVG_Parser_Length_Type type)
else if (strstr(str, "%"))
{
if (type == SVG_PARSER_LENGTH_VERTICAL)
- parsed_value = (parsed_value / 100.0) * svg_parse.global.height;
+ parsed_value = (parsed_value / 100.0) * svg_parse->global.height;
else if (type == SVG_PARSER_LENGTH_HORIZONTAL)
- parsed_value = (parsed_value / 100.0) * svg_parse.global.width;
+ parsed_value = (parsed_value / 100.0) * svg_parse->global.width;
else // if other then it's radius
{
- double max = svg_parse.global.width;
- if (max < svg_parse.global.height) max = svg_parse.global.height;
+ double max = svg_parse->global.width;
+ if (max < svg_parse->global.height) max = svg_parse->global.height;
parsed_value = (parsed_value / 100.0) * max;
}
}
@@ -131,7 +137,7 @@ _to_double(const char *str, SVG_Parser_Length_Type type)
* Turn gradient variables into percentages
*/
static inline double
-_gradient_to_double(const char *str, SVG_Parser_Length_Type type)
+_gradient_to_double(Evas_SVG_Parser *svg_parse, const char *str, SVG_Parser_Length_Type type)
{
char *end = NULL;
@@ -151,12 +157,12 @@ _gradient_to_double(const char *str, SVG_Parser_Length_Type type)
* https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html
*/
if (type == SVG_PARSER_LENGTH_VERTICAL)
- max = svg_parse.global.height;
+ max = svg_parse->global.height;
else if (type == SVG_PARSER_LENGTH_HORIZONTAL)
- max = svg_parse.global.width;
+ max = svg_parse->global.width;
else if (type == SVG_PARSER_LENGTH_OTHER)
- max = sqrt(pow(svg_parse.global.height, 2) +
- pow(svg_parse.global.width, 2)) / sqrt(2.0);
+ 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;
@@ -763,7 +769,8 @@ static Eina_Bool _attr_style_node(void *data, const char *str);
static Eina_Bool
_attr_parse_svg_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node *node = loader->svg_parse->node;
Svg_Doc_Node *doc = &(node->node.doc);
Svg_Length_Type type;
@@ -785,13 +792,13 @@ _attr_parse_svg_node(void *data, const char *key, const char *value)
if (_parse_number(&value, &doc->vw))
{
_parse_number(&value, &doc->vh);
- svg_parse.global.height = doc->vh;
+ loader->svg_parse->global.height = doc->vh;
}
- svg_parse.global.width = doc->vw;
+ loader->svg_parse->global.width = doc->vw;
}
- svg_parse.global.y = doc->vy;
+ loader->svg_parse->global.y = doc->vy;
}
- svg_parse.global.x = doc->vx;
+ loader->svg_parse->global.x = doc->vx;
}
else if (!strcmp(key, "preserveAspectRatio"))
{
@@ -800,18 +807,18 @@ _attr_parse_svg_node(void *data, const char *key, const char *value)
}
else if (!strcmp(key, "style"))
{
- _attr_style_node(node, value);
+ _attr_style_node(loader, value);
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
return EINA_TRUE;
}
//https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint
static void
-_handle_paint_attr(Svg_Paint* paint, const char *value)
+_handle_paint_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Paint* paint, const char *value)
{
if (!strcmp(value, "none"))
{
@@ -829,78 +836,78 @@ _handle_paint_attr(Svg_Paint* paint, const char *value)
}
static void
-_handle_color_attr(Svg_Node* node, const char *value)
+_handle_color_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
Svg_Style_Property *style = node->style;
_to_color(value, &style->r, &style->g, &style->b, NULL);
}
static void
-_handle_fill_attr(Svg_Node* node, const char *value)
+_handle_fill_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
Svg_Style_Property *style = node->style;
style->fill.flags |= SVG_FILL_FLAGS_PAINT;
- _handle_paint_attr(&style->fill.paint, value);
+ _handle_paint_attr(loader, &style->fill.paint, value);
}
static void
-_handle_stroke_attr(Svg_Node* node, const char *value)
+_handle_stroke_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
Svg_Style_Property *style = node->style;
style->stroke.flags |= SVG_STROKE_FLAGS_PAINT;
- _handle_paint_attr(&style->stroke.paint, value);
+ _handle_paint_attr(loader, &style->stroke.paint, value);
}
static void
-_handle_stroke_opacity_attr(Svg_Node* node, const char *value)
+_handle_stroke_opacity_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
node->style->stroke.flags |= SVG_STROKE_FLAGS_OPACITY;
node->style->stroke.opacity = _to_opacity(value);
}
static void
-_handle_stroke_width_attr(Svg_Node* node, const char *value)
+_handle_stroke_width_attr(Evas_SVG_Loader *loader, Svg_Node* node, const char *value)
{
node->style->stroke.flags |= SVG_STROKE_FLAGS_WIDTH;
- node->style->stroke.width = _to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
+ node->style->stroke.width = _to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL);
}
static void
-_handle_stroke_linecap_attr(Svg_Node* node, const char *value)
+_handle_stroke_linecap_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
node->style->stroke.flags |= SVG_STROKE_FLAGS_CAP;
node->style->stroke.cap = _to_line_cap(value);
}
static void
-_handle_stroke_linejoin_attr(Svg_Node* node, const char *value)
+_handle_stroke_linejoin_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
node->style->stroke.flags |= SVG_STROKE_FLAGS_JOIN;
node->style->stroke.join = _to_line_join(value);
}
static void
-_handle_fill_rule_attr(Svg_Node* node, const char *value)
+_handle_fill_rule_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
node->style->fill.flags |= SVG_FILL_FLAGS_FILL_RULE;
node->style->fill.fill_rule = _to_fill_rule(value);
}
static void
-_handle_fill_opacity_attr(Svg_Node* node, const char *value)
+_handle_fill_opacity_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
node->style->fill.flags |= SVG_FILL_FLAGS_OPACITY;
node->style->fill.opacity = _to_opacity(value);
}
static void
-_handle_transform_attr(Svg_Node* node, const char *value)
+_handle_transform_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value)
{
node->transform = _parse_transformation_matrix(value);
}
-typedef void (*Style_Method)(Svg_Node *node, const char *value);
+typedef void (*Style_Method)(Evas_SVG_Loader *loader, Svg_Node *node, const char *value);
#define STYLE_DEF(Name, Name1) \
{ #Name, sizeof (#Name), _handle_##Name1##_attr}
@@ -925,7 +932,8 @@ static const struct {
static Eina_Bool
_parse_style_attr(void *data, const char *key, const char *value)
{
- Svg_Node* node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node* node = loader->svg_parse->node;
unsigned int i;
int sz;
@@ -938,7 +946,7 @@ _parse_style_attr(void *data, const char *key, const char *value)
for (i = 0; i < sizeof (style_tags) / sizeof(style_tags[0]); i++)
if (style_tags[i].sz - 1 == sz && !strncmp(style_tags[i].tag, key, sz))
{
- style_tags[i].tag_handler(node, value);
+ style_tags[i].tag_handler(loader, node, value);
return EINA_TRUE;
}
@@ -959,11 +967,12 @@ _attr_style_node(void *data, const char *str)
static Eina_Bool
_attr_parse_g_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node* node = loader->svg_parse->node;
if (!strcmp(key, "style"))
{
- return _attr_style_node(node, value);
+ return _attr_style_node(loader, value);
}
else if (!strcmp(key, "transform"))
{
@@ -975,7 +984,7 @@ _attr_parse_g_node(void *data, const char *key, const char *value)
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
return EINA_TRUE;
}
@@ -1024,7 +1033,7 @@ _create_node(Svg_Node *parent, Svg_Node_Type type)
}
static Svg_Node *
-_create_defs_node(Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, unsigned buflen EINA_UNUSED)
+_create_defs_node(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, unsigned buflen EINA_UNUSED)
{
Svg_Node *node = _create_node(NULL, SVG_NODE_DEFS);
eina_simple_xml_attributes_parse(buf, buflen,
@@ -1033,29 +1042,30 @@ _create_defs_node(Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, uns
}
static Svg_Node *
-_create_g_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_g_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_G);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_G);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_g_node, node);
- return node;
+ _attr_parse_g_node, loader);
+ return loader->svg_parse->node;
}
static Svg_Node *
-_create_svg_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_svg_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_DOC);
- Svg_Doc_Node *doc = &(node->node.doc);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_DOC);
+ Svg_Doc_Node *doc = &(loader->svg_parse->node->node.doc);
doc->preserve_aspect = EINA_TRUE;
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_svg_node, node);
- return node;
+ _attr_parse_svg_node, loader);
+
+ return loader->svg_parse->node;
}
static Svg_Node *
-_create_switch_node(Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, unsigned buflen EINA_UNUSED)
+_create_switch_node(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, unsigned buflen EINA_UNUSED)
{
return NULL;
}
@@ -1063,7 +1073,8 @@ _create_switch_node(Svg_Node *parent EINA_UNUSED, const char *buf EINA_UNUSED, u
static Eina_Bool
_attr_parse_path_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node* node = loader->svg_parse->node;
Svg_Path_Node *path = &(node->node.path);
if (!strcmp(key, "d"))
@@ -1072,7 +1083,7 @@ _attr_parse_path_node(void *data, const char *key, const char *value)
}
else if (!strcmp(key, "style"))
{
- _attr_style_node(node, value);
+ _attr_style_node(loader, value);
}
else if (!strcmp(key, "id"))
{
@@ -1080,19 +1091,20 @@ _attr_parse_path_node(void *data, const char *key, const char *value)
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
return EINA_TRUE;
}
static Svg_Node *
-_create_path_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_path_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_PATH);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_PATH);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_path_node, node);
- return node;
+ _attr_parse_path_node, loader);
+
+ return loader->svg_parse->node;
}
#define CIRCLE_DEF(Name, Field, Type) \
@@ -1115,7 +1127,8 @@ static const struct {
static Eina_Bool
_attr_parse_circle_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node* node = loader->svg_parse->node;
Svg_Circle_Node *circle = &(node->node.circle);
unsigned int i;
unsigned char *array;
@@ -1125,13 +1138,14 @@ _attr_parse_circle_node(void *data, const char *key, const char *value)
for (i = 0; i < sizeof (circle_tags) / sizeof(circle_tags[0]); i++)
if (circle_tags[i].sz - 1 == sz && !strncmp(circle_tags[i].tag, key, sz))
{
- *((double*) (array + circle_tags[i].offset)) = _to_double(value, circle_tags[i].type);
+ *((double*) (array + circle_tags[i].offset)) =
+ _to_double(loader->svg_parse, value, circle_tags[i].type);
return EINA_TRUE;
}
if (!strcmp(key, "style"))
{
- _attr_style_node(node, value);
+ _attr_style_node(loader, value);
}
else if (!strcmp(key, "id"))
{
@@ -1139,19 +1153,19 @@ _attr_parse_circle_node(void *data, const char *key, const char *value)
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
return EINA_TRUE;
}
static Svg_Node *
-_create_circle_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_circle_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_CIRCLE);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_CIRCLE);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_circle_node, node);
- return node;
+ _attr_parse_circle_node, loader);
+ return loader->svg_parse->node;
}
#define ELLIPSE_DEF(Name, Field, Type) \
@@ -1175,7 +1189,8 @@ static const struct {
static Eina_Bool
_attr_parse_ellipse_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node* node = loader->svg_parse->node;
Svg_Ellipse_Node *ellipse = &(node->node.ellipse);
unsigned int i;
unsigned char *array;
@@ -1185,7 +1200,8 @@ _attr_parse_ellipse_node(void *data, const char *key, const char *value)
for (i = 0; i < sizeof (ellipse_tags) / sizeof(ellipse_tags[0]); i++)
if (ellipse_tags[i].sz - 1 == sz && !strncmp(ellipse_tags[i].tag, key, sz))
{
- *((double*) (array + ellipse_tags[i].offset)) = _to_double(value, ellipse_tags[i].type);
+ *((double*) (array + ellipse_tags[i].offset)) =
+ _to_double(loader->svg_parse, value, ellipse_tags[i].type);
return EINA_TRUE;
}
@@ -1195,23 +1211,23 @@ _attr_parse_ellipse_node(void *data, const char *key, const char *value)
}
else if (!strcmp(key, "style"))
{
- _attr_style_node(node, value);
+ _attr_style_node(loader, value);
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
return EINA_TRUE;
}
static Svg_Node *
-_create_ellipse_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_ellipse_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_ELLIPSE);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_ELLIPSE);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_ellipse_node, node);
- return node;
+ _attr_parse_ellipse_node, loader);
+ return loader->svg_parse->node;
}
static void
@@ -1260,7 +1276,8 @@ error_alloc:
static Eina_Bool
_attr_parse_polygon_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node *node = loader->svg_parse->node;
Svg_Polygon_Node *polygon = NULL;
if (node->type == SVG_NODE_POLYGON)
@@ -1275,7 +1292,7 @@ _attr_parse_polygon_node(void *data, const char *key, const char *value)
}
else if (!strcmp(key, "style"))
{
- _attr_style_node(node, value);
+ _attr_style_node(loader, value);
}
else if (!strcmp(key, "id"))
{
@@ -1283,29 +1300,29 @@ _attr_parse_polygon_node(void *data, const char *key, const char *value)
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
return EINA_TRUE;
}
static Svg_Node *
-_create_polygon_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_polygon_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_POLYGON);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_POLYGON);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_polygon_node, node);
- return node;
+ _attr_parse_polygon_node, loader);
+ return loader->svg_parse->node;
}
static Svg_Node *
-_create_polyline_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_polyline_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_POLYLINE);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_POLYLINE);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_polygon_node, node);
- return node;
+ _attr_parse_polygon_node, loader);
+ return loader->svg_parse->node;
}
#define RECT_DEF(Name, Field, Type) \
@@ -1331,7 +1348,8 @@ static const struct {
static Eina_Bool
_attr_parse_rect_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node *node = loader->svg_parse->node;
Svg_Rect_Node *rect = & (node->node.rect);
unsigned int i;
unsigned char *array;
@@ -1341,7 +1359,7 @@ _attr_parse_rect_node(void *data, const char *key, const char *value)
for (i = 0; i < sizeof (rect_tags) / sizeof(rect_tags[0]); i++)
if (rect_tags[i].sz - 1 == sz && !strncmp(rect_tags[i].tag, key, sz))
{
- *((double*) (array + rect_tags[i].offset)) = _to_double(value, rect_tags[i].type);
+ *((double*) (array + rect_tags[i].offset)) = _to_double(loader->svg_parse, value, rect_tags[i].type);
return EINA_TRUE;
}
@@ -1351,11 +1369,11 @@ _attr_parse_rect_node(void *data, const char *key, const char *value)
}
else if (!strcmp(key, "style"))
{
- _attr_style_node(node, value);
+ _attr_style_node(loader, value);
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
if (!EINA_DBL_EQ(rect->rx, 0) && EINA_DBL_EQ(rect->ry, 0)) rect->ry = rect->rx;
@@ -1365,13 +1383,13 @@ _attr_parse_rect_node(void *data, const char *key, const char *value)
}
static Svg_Node *
-_create_rect_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_rect_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_RECT);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_RECT);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_rect_node, node);
- return node;
+ _attr_parse_rect_node, loader);
+ return loader->svg_parse->node;
}
#define LINE_DEF(Name, Field, Type) \
@@ -1395,7 +1413,8 @@ static const struct {
static Eina_Bool
_attr_parse_line_node(void *data, const char *key, const char *value)
{
- Svg_Node *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node *node = loader->svg_parse->node;
Svg_Line_Node *line = & (node->node.line);
unsigned int i;
unsigned char *array;
@@ -1405,7 +1424,7 @@ _attr_parse_line_node(void *data, const char *key, const char *value)
for (i = 0; i < sizeof (line_tags) / sizeof(line_tags[0]); i++)
if (line_tags[i].sz - 1 == sz && !strncmp(line_tags[i].tag, key, sz))
{
- *((double*) (array + line_tags[i].offset)) = _to_double(value, line_tags[i].type);
+ *((double*) (array + line_tags[i].offset)) = _to_double(loader->svg_parse, value, line_tags[i].type);
return EINA_TRUE;
}
@@ -1415,23 +1434,23 @@ _attr_parse_line_node(void *data, const char *key, const char *value)
}
else if (!strcmp(key, "style"))
{
- _attr_style_node(node, value);
+ _attr_style_node(loader, value);
}
else
{
- _parse_style_attr(node, key, value);
+ _parse_style_attr(loader, key, value);
}
return EINA_TRUE;
}
static Svg_Node *
-_create_line_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_line_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_LINE);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_LINE);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_line_node, node);
- return node;
+ _attr_parse_line_node, loader);
+ return loader->svg_parse->node;
}
static Eina_Stringshare *
@@ -1601,7 +1620,8 @@ _clone_node(Svg_Node *from, Svg_Node *parent)
static Eina_Bool
_attr_parse_use_node(void *data, const char *key, const char *value)
{
- Svg_Node *defs, *node_from, *node = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Node *defs, *node_from, *node = loader->svg_parse->node;
Eina_Stringshare *id;
if (!strcmp(key, "xlink:href"))
@@ -1620,13 +1640,13 @@ _attr_parse_use_node(void *data, const char *key, const char *value)
}
static Svg_Node *
-_create_use_node(Svg_Node *parent, const char *buf, unsigned buflen)
+_create_use_node(Evas_SVG_Loader *loader, Svg_Node *parent, const char *buf, unsigned buflen)
{
- Svg_Node *node = _create_node(parent, SVG_NODE_G);
+ loader->svg_parse->node = _create_node(parent, SVG_NODE_G);
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_use_node, node);
- return node;
+ _attr_parse_use_node, loader);
+ return loader->svg_parse->node;
}
#define TAG_DEF(Name) \
@@ -1695,42 +1715,42 @@ _parse_spread_value(const char *value)
}
static void
-_handle_radial_cx_attr(Svg_Radial_Gradient* radial, const char *value)
+_handle_radial_cx_attr(Evas_SVG_Loader *loader, Svg_Radial_Gradient* radial, const char *value)
{
- radial->cx = _gradient_to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
- if (!svg_parse.gradient.fx_parsed)
+ radial->cx = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL);
+ if (!loader->svg_parse->gradient.fx_parsed)
radial->fx = radial->cx;
}
static void
-_handle_radial_cy_attr(Svg_Radial_Gradient* radial, const char *value)
+_handle_radial_cy_attr(Evas_SVG_Loader *loader, Svg_Radial_Gradient* radial, const char *value)
{
- radial->cy = _gradient_to_double(value, SVG_PARSER_LENGTH_VERTICAL);
- if (!svg_parse.gradient.fy_parsed)
+ radial->cy = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL);
+ if (!loader->svg_parse->gradient.fy_parsed)
radial->fy = radial->cy;
}
static void
-_handle_radial_fx_attr(Svg_Radial_Gradient* radial, const char *value)
+_handle_radial_fx_attr(Evas_SVG_Loader *loader, Svg_Radial_Gradient* radial, const char *value)
{
- radial->fx = _gradient_to_double(value, SVG_PARSER_LENGTH_HORIZONTAL);
- svg_parse.gradient.fx_parsed = EINA_TRUE;
+ radial->fx = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL);
+ loader->svg_parse->gradient.fx_parsed = EINA_TRUE;
}
static void
-_handle_radial_fy_attr(Svg_Radial_Gradient* radial, const char *value)
+_handle_radial_fy_attr(Evas_SVG_Loader *loader, Svg_Radial_Gradient* radial, const char *value)
{
- radial->fy = _gradient_to_double(value, SVG_PARSER_LENGTH_VERTICAL);
- svg_parse.gradient.fy_parsed = EINA_TRUE;
+ radial->fy = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL);
+ loader->svg_parse->gradient.fy_parsed = EINA_TRUE;
}
static void
-_handle_radial_r_attr(Svg_Radial_Gradient* radial, const char *value)
+_handle_radial_r_attr(Evas_SVG_Loader *loader, Svg_Radial_Gradient* radial, const char *value)
{
- radial->r = _gradient_to_double(value, SVG_PARSER_LENGTH_OTHER);
+ radial->r = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_OTHER);
}
-typedef void (*Radial_Method)(Svg_Radial_Gradient *radial, const char *value);
+typedef void (*Radial_Method)(Evas_SVG_Loader *loader, Svg_Radial_Gradient *radial, const char *value);
#define RADIAL_DEF(Name) \
{ #Name, sizeof (#Name), _handle_radial_##Name##_attr}
@@ -1750,7 +1770,8 @@ static const struct {
static Eina_Bool
_attr_parse_radial_gradient_node(void *data, const char *key, const char *value)
{
- Svg_Style_Gradient *grad = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Style_Gradient *grad = loader->svg_parse->style_grad;
Svg_Radial_Gradient *radial = grad->radial;
unsigned int i;
int sz = strlen(key);
@@ -1758,7 +1779,7 @@ _attr_parse_radial_gradient_node(void *data, const char *key, const char *value)
for (i = 0; i < sizeof (radial_tags) / sizeof(radial_tags[0]); i++)
if (radial_tags[i].sz - 1 == sz && !strncmp(radial_tags[i].tag, key, sz))
{
- radial_tags[i].tag_handler(radial, value);
+ radial_tags[i].tag_handler(loader, radial, value);
return EINA_TRUE;
}
@@ -1783,9 +1804,10 @@ _attr_parse_radial_gradient_node(void *data, const char *key, const char *value)
}
static Svg_Style_Gradient *
-_create_radialGradient(const char *buf, unsigned buflen)
+_create_radialGradient(Evas_SVG_Loader *loader, const char *buf, unsigned buflen)
{
Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient));
+ loader->svg_parse->style_grad = grad;
grad->type = SVG_RADIAL_GRADIENT;
grad->user_space = EINA_TRUE;
@@ -1799,19 +1821,19 @@ _create_radialGradient(const char *buf, unsigned buflen)
grad->radial->fy = 0.5;
grad->radial->r = 0.5;
- svg_parse.gradient.fx_parsed = EINA_FALSE;
- svg_parse.gradient.fy_parsed = EINA_FALSE;
+ loader->svg_parse->gradient.fx_parsed = EINA_FALSE;
+ loader->svg_parse->gradient.fy_parsed = EINA_FALSE;
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_radial_gradient_node, grad);
-
- return grad;
+ _attr_parse_radial_gradient_node, loader);
+ return loader->svg_parse->style_grad;
}
static Eina_Bool
_attr_parse_stops(void *data, const char *key, const char *value)
{
- Efl_Gfx_Gradient_Stop *stop = data;
+ Evas_SVG_Loader *loader = data;
+ Efl_Gfx_Gradient_Stop *stop = loader->svg_parse->grad_stop;
if (!strcmp(key, "offset"))
{
@@ -1835,89 +1857,89 @@ _attr_parse_stops(void *data, const char *key, const char *value)
}
static void
-_handle_linear_x1_attr(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(value, SVG_PARSER_LENGTH_HORIZONTAL);
+ linear->x1 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_HORIZONTAL);
if (strstr(value, "%"))
- svg_parse.gradient.x1_percent = EINA_TRUE;
+ loader->svg_parse->gradient.x1_percent = EINA_TRUE;
}
static void
-_handle_linear_y1_attr(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(value, SVG_PARSER_LENGTH_VERTICAL);
+ linear->y1 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL);
if (strstr(value, "%"))
- svg_parse.gradient.y1_percent = EINA_TRUE;
+ loader->svg_parse->gradient.y1_percent = EINA_TRUE;
}
static void
-_handle_linear_x2_attr(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(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, "%"))
- svg_parse.gradient.x2_percent = EINA_FALSE;
+ loader->svg_parse->gradient.x2_percent = EINA_FALSE;
}
static void
-_handle_linear_y2_attr(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(value, SVG_PARSER_LENGTH_VERTICAL);
+ linear->y2 = _gradient_to_double(loader->svg_parse, value, SVG_PARSER_LENGTH_VERTICAL);
if (strstr(value, "%"))
- svg_parse.gradient.y2_percent = EINA_TRUE;
+ loader->svg_parse->gradient.y2_percent = EINA_TRUE;
}
static void
-_recalc_linear_x1_attr(Svg_Linear_Gradient* linear, Eina_Bool user_space)
+_recalc_linear_x1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
- if (!svg_parse.gradient.x1_percent && !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 * svg_parse.global.width;
+ linear->x1 = linear->x1 * loader->svg_parse->global.width;
}
- svg_parse.gradient.x1_percent = EINA_FALSE;
+ loader->svg_parse->gradient.x1_percent = EINA_FALSE;
}
static void
-_recalc_linear_y1_attr(Svg_Linear_Gradient* linear, Eina_Bool user_space)
+_recalc_linear_y1_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
- if (!svg_parse.gradient.y1_percent && !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 * svg_parse.global.height;
+ linear->y1 = linear->y1 * loader->svg_parse->global.height;
}
- svg_parse.gradient.y1_percent = EINA_FALSE;
+ loader->svg_parse->gradient.y1_percent = EINA_FALSE;
}
static void
-_recalc_linear_x2_attr(Svg_Linear_Gradient* linear, Eina_Bool user_space)
+_recalc_linear_x2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
- if (!svg_parse.gradient.x2_percent && !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 * svg_parse.global.width;
+ linear->x2 = linear->x2 * loader->svg_parse->global.width;
}
- svg_parse.gradient.x2_percent = EINA_FALSE;
+ loader->svg_parse->gradient.x2_percent = EINA_FALSE;
}
static void
-_recalc_linear_y2_attr(Svg_Linear_Gradient* linear, Eina_Bool user_space)
+_recalc_linear_y2_attr(Evas_SVG_Loader *loader, Svg_Linear_Gradient* linear, Eina_Bool user_space)
{
- if (!svg_parse.gradient.y2_percent && !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 * svg_parse.global.height;
+ linear->y2 = linear->y2 * loader->svg_parse->global.height;
}
- svg_parse.gradient.y2_percent = EINA_FALSE;
+ loader->svg_parse->gradient.y2_percent = EINA_FALSE;
}
-typedef void (*Linear_Method)(Svg_Linear_Gradient *linear, const char *value);
-typedef void (*Linear_Method_Recalc)(Svg_Linear_Gradient *linear, Eina_Bool user_space);
+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) \
{ #Name, sizeof (#Name), _handle_linear_##Name##_attr, _recalc_linear_##Name##_attr}
@@ -1937,7 +1959,8 @@ static const struct {
static Eina_Bool
_attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
{
- Svg_Style_Gradient *grad = data;
+ Evas_SVG_Loader *loader = data;
+ Svg_Style_Gradient *grad = loader->svg_parse->style_grad;
Svg_Linear_Gradient *linear = grad->linear;
unsigned int i;
int sz = strlen(key);
@@ -1945,7 +1968,7 @@ _attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
for (i = 0; i < sizeof (linear_tags) / sizeof(linear_tags[0]); i++)
if (linear_tags[i].sz - 1 == sz && !strncmp(linear_tags[i].tag, key, sz))
{
- linear_tags[i].tag_handler(linear, value);
+ linear_tags[i].tag_handler(loader, linear, value);
return EINA_TRUE;
}
@@ -1970,9 +1993,11 @@ _attr_parse_linear_gradient_node(void *data, const char *key, const char *value)
}
static Svg_Style_Gradient *
-_create_linearGradient(const char *buf, unsigned buflen)
+_create_linearGradient(Evas_SVG_Loader *loader, const char *buf, unsigned buflen)
{
Svg_Style_Gradient *grad = calloc(1, sizeof(Svg_Style_Gradient));
+ loader->svg_parse->style_grad = grad;
+
unsigned int i;
grad->type = SVG_LINEAR_GRADIENT;
@@ -1982,14 +2007,14 @@ _create_linearGradient(const char *buf, unsigned buflen)
* Default value of x2 is 100%
*/
grad->linear->x2 = 1;
- svg_parse.gradient.x2_percent = EINA_TRUE;
+ loader->svg_parse->gradient.x2_percent = EINA_TRUE;
eina_simple_xml_attributes_parse(buf, buflen,
- _attr_parse_linear_gradient_node, grad);
+ _attr_parse_linear_gradient_node, loader);
for (i = 0; i < sizeof (linear_tags) / sizeof(linear_tags[0]); i++)
- linear_tags[i].tag_recalc(grad->linear, grad->user_space);
+ linear_tags[i].tag_recalc(loader, grad->linear, grad->user_space);
- return grad;
+ return loader->svg_parse->style_grad;
}
#define GRADIENT_DEF(Name) \
@@ -2064,13 +2089,13 @@ _evas_svg_loader_xml_open_parser(Evas_SVG_Loader *loader,
{
if (strcmp(tag_name, "svg"))
return; // Not a valid svg document
- node = method(NULL, attrs, attrs_length);
+ node = method(loader, NULL, attrs, attrs_length);
loader->doc = node;
}
else
{
parent = eina_array_data_get(loader->stack, eina_array_count(loader->stack) - 1);
- node = method(parent, attrs, attrs_length);
+ node = method(loader, parent, attrs, attrs_length);
}
eina_array_push(loader->stack, node);
@@ -2083,12 +2108,12 @@ _evas_svg_loader_xml_open_parser(Evas_SVG_Loader *loader,
else if ((method = _find_graphics_factory(tag_name)))
{
parent = eina_array_data_get(loader->stack, eina_array_count(loader->stack) - 1);
- node = method(parent, attrs, attrs_length);
+ node = method(loader, parent, attrs, attrs_length);
}
else if ((gradient_method = _find_gradient_factory(tag_name)))
{
Svg_Style_Gradient *gradient;
- gradient = gradient_method(attrs, attrs_length);
+ gradient = gradient_method(loader, attrs, attrs_length);
if (loader->doc->node.doc.defs)
{
loader->def->node.defs.gradients = eina_list_append(loader->def->node.defs.gradients, gradient);
@@ -2098,10 +2123,11 @@ _evas_svg_loader_xml_open_parser(Evas_SVG_Loader *loader,
else if (!strcmp(tag_name, "stop"))
{
Efl_Gfx_Gradient_Stop *stop = calloc(1, sizeof(Efl_Gfx_Gradient_Stop));
+ loader->svg_parse->grad_stop = stop;
/* default value for opacity */
stop->a = 255;
eina_simple_xml_attributes_parse(attrs, attrs_length,
- _attr_parse_stops, stop);
+ _attr_parse_stops, loader);
if (loader->gradient)
loader->gradient->stops = eina_list_append(loader->gradient->stops, stop);
}
@@ -2304,7 +2330,7 @@ static Vg_File_Data*
evas_vg_load_file_data_svg(const char *file, const char *key EINA_UNUSED, int *error EINA_UNUSED)
{
Evas_SVG_Loader loader = {
- NULL, NULL, NULL, NULL, 0, EINA_FALSE
+ NULL, NULL, NULL, NULL, NULL, 0, EINA_FALSE
};
const char *content;
unsigned int length;
@@ -2318,6 +2344,7 @@ evas_vg_load_file_data_svg(const char *file, const char *key EINA_UNUSED, int *e
return NULL;
}
+ loader.svg_parse = calloc(1, sizeof(Evas_SVG_Parser));
length = eina_file_size_get(f);
content = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (content)
@@ -2343,7 +2370,8 @@ evas_vg_load_file_data_svg(const char *file, const char *key EINA_UNUSED, int *e
{
*error = EVAS_LOAD_ERROR_GENERIC;
}
- return vg_common_create_vg_node(loader.doc);
+ free(loader.svg_parse);
+ return vg_common_create_vg_node(loader.doc);
}
static Evas_Vg_Load_Func evas_vg_load_svg_func =