evas vg: fix broken vg rendering.

This fixes vg to connect node tree properly on copying nodes.

Vector rendering was broken when vg cache tries to reconstruct the scene-graph
tree on copying from the original cached one. Exactly, nodes lost parents on
copying. Here it fixes the lost links of the scene-graph tree.

@fix T6993
This commit is contained in:
Hermet Park 2018-06-11 16:23:28 +09:00
parent d1e1adf0bc
commit ca3fb6bf94
4 changed files with 81 additions and 76 deletions

View File

@ -152,25 +152,30 @@ _efl_canvas_vg_container_efl_gfx_path_interpolate(Eo *obj,
}
EOLIAN static Efl_VG *
_efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Container_Data *pd)
_efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
Efl_Canvas_Vg_Container_Data *pd)
{
Eina_List *l;
Efl_VG *child;
Efl_VG *cn = NULL;
Efl_VG *container;
cn = efl_duplicate(efl_super(obj, MY_CLASS));
container = efl_duplicate(efl_super(obj, MY_CLASS));
efl_parent_set(container, efl_parent_get(obj));
//Copy Children
EINA_LIST_FOREACH(pd->children, l, child)
{
// parent_set adds the new node to the list of children of cn
efl_parent_set(efl_duplicate(child), cn);
Efl_VG *eo = efl_duplicate(child);
efl_parent_set(eo, container);
}
return cn;
return container;
}
EAPI Efl_VG*
evas_vg_container_add(Efl_VG *parent)
{
return efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, parent);
return efl_add(MY_CLASS, parent);
}
#include "efl_canvas_vg_container.eo.c"

View File

@ -241,19 +241,21 @@ _efl_canvas_vg_node_parent_checked_get(Eo *obj,
static Eo *
_efl_canvas_vg_node_efl_object_constructor(Eo *obj,
Efl_Canvas_Vg_Node_Data *pd)
Efl_Canvas_Vg_Node_Data *pd)
{
Efl_Canvas_Vg_Container_Data *cd = NULL;
Efl_Canvas_Vg_Container_Data *cd;
Eo *parent;
obj = efl_constructor(efl_super(obj, MY_CLASS));
if (!_efl_canvas_vg_node_parent_checked_get(obj, &parent, &cd)) {
if (!_efl_canvas_vg_node_parent_checked_get(obj, &parent, &cd))
{
ERR("Failed");
return NULL;
}
}
efl_event_callback_add(obj, EFL_GFX_PATH_EVENT_CHANGED, _efl_canvas_vg_node_property_changed, pd);
efl_event_callback_add(obj, EFL_GFX_PATH_EVENT_CHANGED,
_efl_canvas_vg_node_property_changed, pd);
pd->flags = EFL_GFX_CHANGE_FLAG_ALL;
pd->changed = EINA_TRUE;
@ -294,14 +296,14 @@ _efl_canvas_vg_node_name_insert(Eo *obj, Efl_Canvas_Vg_Container_Data *cd)
{
Eo *set;
const char *name = efl_name_get(efl_super(obj, MY_CLASS));
if (!name) return ;
if (!name) return;
set = eina_hash_find(cd->names, name);
if (set == obj) return ;
if (set == obj) return;
if (set)
{
ERR("node name(%s) is already exist in container but child node(%p) is different...", name, obj);
efl_name_set(efl_super(obj, MY_CLASS), NULL);
}
else
@ -313,8 +315,8 @@ _efl_canvas_vg_node_name_insert(Eo *obj, Efl_Canvas_Vg_Container_Data *cd)
static void
_efl_canvas_vg_node_efl_object_name_set(Eo *obj, Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED, const char *name)
{
Efl_Canvas_Vg_Container_Data *cd = NULL;
Eo *parent = NULL;
Efl_Canvas_Vg_Container_Data *cd;
Eo *parent;
const char *pname = efl_name_get(obj);
if (_efl_canvas_vg_node_parent_checked_get(obj, &parent, &cd))
@ -333,59 +335,42 @@ _efl_canvas_vg_node_efl_object_parent_set(Eo *obj,
Eo *parent)
{
Efl_Canvas_Vg_Container_Data *cd = NULL;
Efl_Canvas_Vg_Container_Data *old_cd = NULL;
Eo *old_parent = NULL;
Efl_Canvas_Vg_Container_Data *old_cd;
Eo *old_parent;
Eina_Bool parent_container = EINA_TRUE;
if (efl_isa(parent, EFL_CANVAS_VG_CONTAINER_CLASS))
{
cd = efl_data_scope_get(parent, EFL_CANVAS_VG_CONTAINER_CLASS);
if (!cd)
{
ERR("Can't get EFL_CANVAS_VG_CONTAINER_CLASS data from %p.", parent);
goto on_error;
}
}
else if (efl_isa(parent, EFL_CANVAS_VG_OBJECT_CLASS))
{
parent_container = EINA_FALSE;
}
else if (parent != NULL)
else if (parent)
{
ERR("%p not even an Vector Graphics related class.", parent);
goto on_error;
ERR("parent(%p, class = %s) is not allowed by vg node(%p).",
parent, efl_class_name_get(efl_class_get(parent)), obj);
return;
}
if (!_efl_canvas_vg_node_parent_checked_get(obj, &old_parent, &old_cd))
{
ERR("Can't check the old parent of %p.", obj);
goto on_error;
}
return;
// FIXME: this may become slow with to much object
if (old_cd)
{
old_cd->children = eina_list_remove(old_cd->children, obj);
eina_hash_del(old_cd->names, efl_name_get(efl_super(obj, MY_CLASS)), obj);
}
efl_parent_set(efl_super(obj, MY_CLASS), parent);
if (cd)
{
cd->children = eina_list_append(cd->children, obj);
_efl_canvas_vg_node_name_insert(obj, cd);
}
_efl_canvas_vg_node_changed(old_parent);
_efl_canvas_vg_node_changed(obj);
if (parent_container) _efl_canvas_vg_node_changed(parent);
return ;
on_error:
return ;
}
static void
@ -726,31 +711,36 @@ _efl_canvas_vg_node_efl_gfx_path_interpolate(Eo *obj,
EOLIAN static Efl_VG *
_efl_canvas_vg_node_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Node_Data *pd)
{
Efl_VG *cn;
Efl_Canvas_Vg_Node_Data *cd;
Efl_VG *node;
Efl_Canvas_Vg_Node_Data *nd;
node = efl_add_ref(efl_class_get(obj), NULL);
nd = efl_data_scope_get(node, MY_CLASS);
//Hmm...?
efl_name_set(efl_super(node, MY_CLASS), efl_name_get(efl_super(obj, MY_CLASS)));
cn = efl_add(efl_class_get(obj), NULL);
cd = efl_data_scope_get(cn, MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN_VAL(cd, NULL);
efl_name_set(efl_super(cn, MY_CLASS), efl_name_get(efl_super(obj, MY_CLASS)));
if (pd->m)
{
cd->m = malloc(sizeof (Eina_Matrix3)) ;
if (cd->m) memcpy(cd->m, pd->m, sizeof (Eina_Matrix3));
nd->m = malloc(sizeof(Eina_Matrix3));
if (nd->m) memcpy(nd->m, pd->m, sizeof(Eina_Matrix3));
}
if (pd->mask)
cd->mask = efl_duplicate(pd->mask);
{
nd->mask = efl_duplicate(pd->mask);
efl_parent_set(nd->mask, node);
}
cd->x = pd->x;
cd->y = pd->y;
cd->r = pd->r;
cd->g = pd->g;
cd->b = pd->b;
cd->a = pd->a;
cd->visibility = pd->visibility;
nd->x = pd->x;
nd->y = pd->y;
nd->r = pd->r;
nd->g = pd->g;
nd->b = pd->b;
nd->a = pd->a;
nd->visibility = pd->visibility;
return cn;
return node;
}
EAPI Eina_Bool

View File

@ -177,20 +177,33 @@ _efl_canvas_vg_shape_efl_gfx_path_interpolate(Eo *obj,
EOLIAN static Efl_Canvas_Vg_Node *
_efl_canvas_vg_shape_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Shape_Data *pd)
{
Efl_Canvas_Vg_Node *cn = NULL;
Efl_Canvas_Vg_Shape_Data *cd = NULL;
Efl_Canvas_Vg_Node *node;
Efl_Canvas_Vg_Shape_Data *sd;
node = efl_duplicate(efl_super(obj, MY_CLASS));
sd = efl_data_scope_get(node, MY_CLASS);
cn = efl_duplicate(efl_super(obj, MY_CLASS));
cd = efl_data_scope_get(cn, MY_CLASS);
if (pd->fill)
cd->fill = efl_duplicate(pd->fill);
if (pd->stroke.fill)
cd->stroke.fill = efl_duplicate(pd->stroke.fill);
if (pd->stroke.marker)
cd->stroke.marker = efl_duplicate(pd->stroke.marker);
{
sd->fill = efl_duplicate(pd->fill);
efl_parent_set(sd->fill, node);
}
efl_gfx_path_copy_from(cn, obj);
return cn;
if (pd->stroke.fill)
{
sd->stroke.fill = efl_duplicate(pd->stroke.fill);
efl_parent_set(sd->stroke.fill, node);
}
if (pd->stroke.marker)
{
sd->stroke.marker = efl_duplicate(pd->stroke.marker);
efl_parent_set(sd->stroke.marker, node);
}
efl_gfx_path_copy_from(node, obj);
return node;
}
EAPI double

View File

@ -177,7 +177,6 @@ static void
_evas_cache_vg_data_free_cb(void *data)
{
Vg_File_Data *val = data;
efl_del(val->root);
free(val);
}
@ -268,11 +267,10 @@ _apply_transformation(Efl_VG *root, double w, double h, Vg_File_Data *vg_data)
static Efl_VG *
_evas_vg_dup_vg_tree(Vg_File_Data *fd, double w, double h)
{
Efl_VG *root;
if (!fd) return NULL;
if ( !w || !h ) return NULL;
if (w < 1 || h < 1) return NULL;
root = efl_duplicate(fd->root);
_apply_transformation(root, w, h, fd);
@ -335,9 +333,8 @@ evas_cache_vg_tree_get(Evas_Cache_Vg_Entry *entry)
if (entry->root) return entry->root;
if (entry->file)
{
_evas_cache_svg_vg_tree_update(entry);
}
_evas_cache_svg_vg_tree_update(entry);
return entry->root;
}