From 78bc406640bead45f70978a7f2d1eecfc9122909 Mon Sep 17 00:00:00 2001 From: Vitalii Vorobiov Date: Tue, 31 Jan 2017 18:06:36 +0200 Subject: [PATCH] saver/svg: parse loaded tree data into svg XML file and save it Just base source code which will parse all structures of svg tree into xml text to save current vector image into file @feature --- .../evas/vg_savers/svg/evas_vg_save_svg.c | 142 ++++++++++++++++-- 1 file changed, 132 insertions(+), 10 deletions(-) diff --git a/src/modules/evas/vg_savers/svg/evas_vg_save_svg.c b/src/modules/evas/vg_savers/svg/evas_vg_save_svg.c index 8c11fb3d69..c44b0d536f 100644 --- a/src/modules/evas/vg_savers/svg/evas_vg_save_svg.c +++ b/src/modules/evas/vg_savers/svg/evas_vg_save_svg.c @@ -5,26 +5,148 @@ static int _evas_vg_saver_svg_log_dom = -1; #ifdef ERR # undef ERR #endif -#define ERR(...) EINA_LOG_DOM_ERR(_evas_vg_saver_eet_log_dom, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_evas_vg_saver_svg_log_dom, __VA_ARGS__) #ifdef INF # undef INF #endif -#define INF(...) EINA_LOG_DOM_INFO(_evas_vg_saver_eet_log_dom, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_evas_vg_saver_svg_log_dom, __VA_ARGS__) + +static void +printf_style(Svg_Style_Property *style, Eina_Strbuf *buf) +{ + if ((style->fill.paint.r) || (style->fill.paint.g) || (style->fill.paint.b)) + eina_strbuf_append_printf(buf, " fill=\"#%02X%02X%02X\" ", style->fill.paint.r, style->fill.paint.g, style->fill.paint.b); + if (style->fill.fill_rule == EFL_GFX_FILL_RULE_ODD_EVEN) + eina_strbuf_append_printf(buf, " fill-rule=\"evenodd\" "); + if (style->fill.opacity != 255) + eina_strbuf_append_printf(buf, " fill-opacity=\"%f\"", style->fill.opacity / 255.0); + if ((style->stroke.paint.r) || (style->stroke.paint.g) || (style->stroke.paint.b)) + eina_strbuf_append_printf(buf, " stroke=\"#%02X%02X%02X\" ", style->stroke.paint.r, style->stroke.paint.g, style->stroke.paint.b); + if (style->stroke.width) + eina_strbuf_append_printf(buf, " stroke-width=\"%f\" ", style->stroke.width); + if (style->stroke.cap == EFL_GFX_CAP_ROUND) + eina_strbuf_append_printf(buf, " stroke-linecap=\"round\" "); + else if (style->stroke.cap == EFL_GFX_CAP_SQUARE) + eina_strbuf_append_printf(buf, " stroke-linecap=\"square\" "); +} + +static void +_svg_node_printf(Svg_Node *parent, Eina_Strbuf *buf) +{ + int i = 0; + double *points; + double last_x = 0, last_y = 0; + Efl_Gfx_Path_Command *commands; + Eina_List *l; + Svg_Node *data; + + switch (parent->type) + { + case SVG_NODE_DOC: + eina_strbuf_append_printf(buf, "\n"); + eina_strbuf_append_printf(buf, "\n", + parent->node.doc.vx, parent->node.doc.vy, + parent->node.doc.vw, parent->node.doc.vh); + EINA_LIST_FOREACH(parent->child, l, data) + { + _svg_node_printf(data, buf); + } + eina_strbuf_append_printf(buf, "\n"); + break; + case SVG_NODE_G: + eina_strbuf_append_printf(buf, "transform) + eina_strbuf_append_printf(buf, + " transform=\"matrix(%f %f %f %f %f %f)\"", + parent->transform->xx, + parent->transform->yx, + parent->transform->xy, + parent->transform->yy, + parent->transform->xz, + parent->transform->yz); + eina_strbuf_append_printf(buf, ">\n"); + EINA_LIST_FOREACH(parent->child, l, data) + { + _svg_node_printf(data, buf); + } + eina_strbuf_append_printf(buf, "\n"); + break; + case SVG_NODE_CUSTOME_COMMAND: + points = parent->node.command.points; + commands = parent->node.command.commands; + eina_strbuf_append_printf(buf, "node.command.commands_count; i++) + { + switch (commands[i]) + { + case EFL_GFX_PATH_COMMAND_TYPE_END: + eina_strbuf_append_printf(buf, "\""); + if (parent->transform) + eina_strbuf_append_printf(buf, " transform=\"matrix(%f %f %f %f %f %f)\"", + parent->transform->xx, + parent->transform->yx, + parent->transform->xy, + parent->transform->yy, + parent->transform->xz, + parent->transform->yz); + printf_style(parent->style, buf); + eina_strbuf_append_printf(buf, "/>\n"); + break; + case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO: + eina_strbuf_append_printf(buf, "m%f,%f ", points[0] - last_x, points[1] - last_y); + last_x = points[0]; + last_y = points[1]; + points += 2; + break; + case EFL_GFX_PATH_COMMAND_TYPE_LINE_TO: + eina_strbuf_append_printf(buf, "L%f,%f ", points[0], points[1]); + last_x = points[0]; + last_y = points[1]; + points += 2; + break; + case EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO: + eina_strbuf_append_printf(buf, "c%f,%f %f,%f %f,%f ", + points[0] - last_x, points[1] - last_y, + points[2] - last_x, points[3] - last_y, + points[4] - last_x, points[5] - last_y); + last_x = points[4]; + last_y = points[5]; + points += 6; + break; + case EFL_GFX_PATH_COMMAND_TYPE_CLOSE: + eina_strbuf_append_printf(buf, " z "); + break; + case EFL_GFX_PATH_COMMAND_TYPE_LAST: + default: + break; + } + } + break; + default: + break; + } +} int evas_vg_save_file_svg(Vg_File_Data *evg_data, const char *file, const char *key EINA_UNUSED, int compress EINA_UNUSED) { - Svg_Node *root EINA_UNUSED; - Eet_File *ef; - - ef = eet_open(file, EET_FILE_MODE_WRITE); - if (!ef) - return EVAS_LOAD_ERROR_GENERIC; + Eina_Strbuf *buf = NULL; + Svg_Node *root; + FILE *f = fopen(file, "w+"); + if (!f) + { + ERR("Cannot open file '%s' for SVG save", file); + return EFL_IMAGE_LOAD_ERROR_GENERIC; + } root = vg_common_create_svg_node(evg_data); - //TODO: parse root into SVG source code and save into file as text file - eet_close(ef); + buf = eina_strbuf_new(); + _svg_node_printf(root, buf); + fprintf(f, "%s\n", eina_strbuf_string_get(buf)); + fclose(f); + eina_strbuf_free(buf); return EVAS_LOAD_ERROR_NONE; }