aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitalii Vorobiov <vi.vorobiov@samsung.com>2017-01-31 18:06:36 +0200
committerJean-Philippe Andre <jp.andre@samsung.com>2017-11-07 11:54:09 +0900
commit78bc406640bead45f70978a7f2d1eecfc9122909 (patch)
tree698450d6aae475bc05c5edf69c47e7581cf1fc32
parentvg_savers/svg: empty (for now) module that will save svg in original file (diff)
downloadefl-78bc406640bead45f70978a7f2d1eecfc9122909.tar.gz
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
-rw-r--r--src/modules/evas/vg_savers/svg/evas_vg_save_svg.c142
1 files 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, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
+ eina_strbuf_append_printf(buf, "<svg viewBox=\"%f %f %f %f\" xmlns=\"http://www.w3.org/2000/svg\""
+ " xmlns:xlink=\"http://www.w3.org/1999/xlink\">\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, "</svg>\n");
+ break;
+ case SVG_NODE_G:
+ eina_strbuf_append_printf(buf, "<g");
+ 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);
+ eina_strbuf_append_printf(buf, ">\n");
+ EINA_LIST_FOREACH(parent->child, l, data)
+ {
+ _svg_node_printf(data, buf);
+ }
+ eina_strbuf_append_printf(buf, "</g>\n");
+ break;
+ case SVG_NODE_CUSTOME_COMMAND:
+ points = parent->node.command.points;
+ commands = parent->node.command.commands;
+ eina_strbuf_append_printf(buf, "<path d=\"");
+ for (i = 0; i < parent->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;
}