This patch changes evas svg loader to using thorvg svg loader.
The patch extands .svg only; .svgz and .svg.gz will be loaded using old loader.
For edje_cc support (edj/edc files), svg file content is written into edj.
Patch is divided into two parts- edje & evas. This is evas part.
Change-Id: I3bbff14058daf737ec4c3c9b3244f1810649b948
Tvg_Matrix trans_mat = { 0 };
if (!nd || !nd->data) return;
-
Efl_Canvas_Vg_Image_Data *pd = nd->data;
if (nd->flags != EFL_GFX_CHANGE_FLAG_NONE)
{
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
- if (!pd->picture && pd->image)
- {
- pd->picture = tvg_picture_new();
- if (tvg_picture_load_raw(pd->picture, pd->image, pd->w, pd->h, true) != TVG_RESULT_SUCCESS)
- {
- printf("Error loading image buffer \n");
- return;
- }
- }
- if (!pd->picture) return;
-
EFL_CANVAS_VG_COMPUTE_MATRIX(cTransform, pTransform, nd);
tvg_paint_translate(pd->picture, nd->x, nd->y);
if (cTransform)
nd->render_pre = _efl_canvas_vg_image_render_pre;
+ pd->picture = tvg_picture_new();
+
efl_gfx_color_set(obj , 255, 255, 255, 255);
return obj;
}
static void
-_efl_canvas_vg_image_efl_object_destructor(Eo *obj, Efl_Canvas_Vg_Image_Data *pd EINA_UNUSED)
+_efl_canvas_vg_image_efl_object_destructor(Eo *obj, Efl_Canvas_Vg_Image_Data *pd)
{
+ tvg_paint_del(pd->picture);
efl_destructor(efl_super(obj, MY_CLASS));
}
if (!data || size.w <= 0 || size.h <= 0)
return;
+ if (pd->image == data && pd->w == size.w && pd->h == size.h)
+ return;
+
+ if (tvg_picture_load_raw(pd->picture, data, size.w, size.h, true) != TVG_RESULT_SUCCESS)
+ {
+ ERR("Error loading image buffer.");
+ return;
+ }
+
pd->image = data;
pd->w = size.w;
pd->h = size.h;
}
+static Eina_Bool
+_efl_canvas_vg_image_file_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Image_Data *pd, const char *path)
+{
+ if (tvg_picture_load(pd->picture, path) == TVG_RESULT_SUCCESS)
+ return EINA_TRUE;
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_efl_canvas_vg_image_memfile_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Image_Data *pd, const char *data, uint32_t size, const char *mimetype)
+{
+ if (tvg_picture_load_data(pd->picture, data, size, mimetype, true) == TVG_RESULT_SUCCESS)
+ return EINA_TRUE;
+ return EINA_FALSE;
+}
+
+static Eina_Rect
+_efl_canvas_vg_image_viewbox_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Image_Data *pd)
+{
+ float x, y, w, h;
+
+ if (tvg_picture_get_viewbox(pd->picture, &x, &y, &w, &h) == TVG_RESULT_SUCCESS)
+ return EINA_RECT(x, y, w, h);
+ return EINA_RECT(0, 0, 0, 0);
+}
+
+EOLIAN static Efl_Canvas_Vg_Node *
+_efl_canvas_vg_image_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Image_Data *pd)
+{
+ Efl_Canvas_Vg_Node *node = NULL;
+ Efl_Canvas_Vg_Image_Data *sd = NULL;
+
+ node = efl_duplicate(efl_super(obj, MY_CLASS));
+ sd = efl_data_scope_get(node, MY_CLASS);
+
+ if (pd->picture) sd->picture = tvg_paint_duplicate(pd->picture);
+
+ sd->image = pd->image; // note: no memcpy here
+ sd->w = pd->w;
+ sd->h = pd->h;
+
+ return node;
+}
+
#include "efl_canvas_vg_image.eo.c"
size: Eina.Size2D; [[The size in pixels.]]
}
}
+ @property file {
+ [[Set path for file to be loaded]]
+ set {
+ return: bool; [[$true on success, $false otherwise]]
+ }
+ values {
+ path: string; [[Path for image to be loaded]]
+ }
+ }
+ @property memfile {
+ [[Set image data passing data and size]]
+ set {
+ return: bool; [[$true on success, $false otherwise]]
+ }
+ values {
+ data: ptr(const(char)); [[Data]]
+ size: uint32; [[Size of data]]
+ mimetype: ptr(const(char)); [[Mimetype of data]]
+ }
+ }
+ @property viewbox {
+ [[Get viewbox for loaded]]
+ get {
+ }
+ values {
+ r: Eina.Rect; [[The function returns viewbox coordinates and size for given paint: x y w h]]
+ }
+ }
}
implements {
+ Efl.Duplicate.duplicate;
Efl.Object.constructor;
Efl.Object.destructor;
}
EVAS_EINA_STATIC_MODULE_DEFINE(vg_loader, eet);
EVAS_EINA_STATIC_MODULE_DEFINE(vg_loader, svg);
EVAS_EINA_STATIC_MODULE_DEFINE(vg_loader, json);
+EVAS_EINA_STATIC_MODULE_DEFINE(vg_loader, tvg);
#endif
#if !EVAS_MODULE_NO_IMAGE_LOADERS
#ifdef EVAS_STATIC_BUILD_VG_SVG
EVAS_EINA_STATIC_MODULE_USE(vg_loader, svg),
#endif
+#ifdef EVAS_STATIC_BUILD_VG_TVG
+ EVAS_EINA_STATIC_MODULE_USE(vg_loader, tvg),
+#endif
#ifdef EVAS_STATIC_BUILD_VG_EET
EVAS_EINA_STATIC_MODULE_USE(vg_loader, eet),
#endif
['eet', [eet]],
['json', [json]],
['svg', []],
+ ['tvg', []],
]
evas_vg_savers_file = ['eet', 'svg']
{ /* map extensions to loaders to use for good first-guess tries */
MATCHING(".eet", "eet"),
MATCHING(".edj", "eet"),
- MATCHING(".svg", "svg"),
+ MATCHING(".svg", "tvg"),
MATCHING(".svgz", "svg"),
MATCHING(".svg.gz", "svg")
};
static const char *loaders_name[] =
{ /* in order of most likely needed */
- "eet", "json", "svg"
+ "eet", "json", "tvg", "svg"
};
static const struct ext_saver_s savers[] =
--- /dev/null
+#include "vg_common.h"
+
+static int _evas_vg_loader_tvg_log_dom = -1;
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_evas_vg_loader_tvg_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_evas_vg_loader_tvg_log_dom, __VA_ARGS__)
+
+static Eina_Bool
+evas_vg_load_file_close_tvg(Vg_File_Data *vfd)
+{
+ if (!vfd) return EINA_FALSE;
+
+ if (vfd->root) efl_unref(vfd->root);
+ free(vfd);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_vg_load_file_data_tvg(Vg_File_Data *vfd EINA_UNUSED)
+{
+ return EINA_TRUE;
+}
+
+static Vg_File_Data*
+evas_vg_load_file_open_tvg(Eina_File *file,
+ const char *key EINA_UNUSED,
+ int *error EINA_UNUSED)
+{
+ Vg_File_Data *vfd = calloc(1, sizeof(Vg_File_Data));
+ if (!vfd) return NULL;
+
+ Eina_Bool loaded = EINA_FALSE;
+ Efl_Canvas_Vg_Image *image = efl_add_ref(EFL_CANVAS_VG_IMAGE_CLASS, NULL);
+
+ if (eina_file_virtual(file))
+ {
+ unsigned int length = eina_file_size_get(file);
+ const char *data = (const char*) eina_file_map_all(file, EINA_FILE_SEQUENTIAL);
+ if (!data) goto err;
+ loaded = efl_canvas_vg_image_memfile_set(image, data, length, "svg");
+ eina_file_map_free(file, (void *) data);
+ }
+ else
+ {
+ loaded = efl_canvas_vg_image_file_set(image, eina_file_filename_get(file));
+ }
+
+ if (!loaded) goto err;
+
+ vfd->root = image;
+
+ Eina_Rect r = efl_canvas_vg_image_viewbox_get(image);
+ vfd->view_box.x = r.x;
+ vfd->view_box.y = r.y;
+ vfd->view_box.w = r.w;
+ vfd->view_box.h = r.h;
+
+ vfd->preserve_aspect = EINA_TRUE;
+ vfd->static_viewbox = EINA_TRUE;
+
+ return vfd;
+
+err:
+ efl_unref(image);
+ free(vfd);
+ return NULL;
+}
+
+static Evas_Vg_Load_Func evas_vg_load_tvg_func =
+{
+ evas_vg_load_file_open_tvg,
+ evas_vg_load_file_close_tvg,
+ evas_vg_load_file_data_tvg
+};
+
+static int
+module_open(Evas_Module *em)
+{
+ if (!em) return 0;
+ em->functions = (void *)(&evas_vg_load_tvg_func);
+ _evas_vg_loader_tvg_log_dom = eina_log_domain_register
+ ("vg-load-tvg", EVAS_DEFAULT_LOG_COLOR);
+ if (_evas_vg_loader_tvg_log_dom < 0)
+ {
+ EINA_LOG_ERR("Can not create a module log domain.");
+ return 0;
+ }
+ return 1;
+}
+
+static void
+module_close(Evas_Module *em EINA_UNUSED)
+{
+ if (_evas_vg_loader_tvg_log_dom >= 0)
+ {
+ eina_log_domain_unregister(_evas_vg_loader_tvg_log_dom);
+ _evas_vg_loader_tvg_log_dom = -1;
+ }
+}
+
+static Evas_Module_Api evas_modapi =
+{
+ EVAS_MODULE_API_VERSION,
+ "tvg",
+ "none",
+ {
+ module_open,
+ module_close
+ }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_VG_LOADER, vg_loader, tvg);
+
+#ifndef EVAS_STATIC_BUILD_VG_TVG
+EVAS_EINA_MODULE_DEFINE(vg_loader, tvg);
+#endif
if (node->type == SVG_NODE_G || node->type == SVG_NODE_CLIP_PATH) return;
// apply the fill style property
-#ifndef HAVE_THORVG
- //FIX_TVG: replace?
- efl_gfx_shape_fill_rule_set(vg, style->fill.fill_rule);
-#endif
+ evas_vg_shape_fill_rule_set(vg, style->fill.fill_rule);
+
evas_vg_shape_stroke_width_set(vg, style->stroke.width);
evas_vg_shape_stroke_cap_set(vg, style->stroke.cap);
evas_vg_shape_stroke_join_set(vg, style->stroke.join);