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
This commit is contained in:
parent
7d9c1256a3
commit
78bc406640
|
@ -5,26 +5,148 @@ static int _evas_vg_saver_svg_log_dom = -1;
|
||||||
#ifdef ERR
|
#ifdef ERR
|
||||||
# undef ERR
|
# undef ERR
|
||||||
#endif
|
#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
|
#ifdef INF
|
||||||
# undef INF
|
# undef INF
|
||||||
#endif
|
#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
|
int
|
||||||
evas_vg_save_file_svg(Vg_File_Data *evg_data, const char *file, const char *key EINA_UNUSED, int compress EINA_UNUSED)
|
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;
|
Eina_Strbuf *buf = NULL;
|
||||||
Eet_File *ef;
|
Svg_Node *root;
|
||||||
|
FILE *f = fopen(file, "w+");
|
||||||
ef = eet_open(file, EET_FILE_MODE_WRITE);
|
if (!f)
|
||||||
if (!ef)
|
{
|
||||||
return EVAS_LOAD_ERROR_GENERIC;
|
ERR("Cannot open file '%s' for SVG save", file);
|
||||||
|
return EFL_IMAGE_LOAD_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
root = vg_common_create_svg_node(evg_data);
|
root = vg_common_create_svg_node(evg_data);
|
||||||
//TODO: parse root into SVG source code and save into file as text file
|
buf = eina_strbuf_new();
|
||||||
eet_close(ef);
|
_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;
|
return EVAS_LOAD_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue