{
int w, h;
int new_svg = 0;
- Efl_VG *vg_tree, *root_vg;
- double sx, sy, vx, vy, vw, vh;
+ Efl_VG *root_vg;
+ double sx, sy;
+ Eina_Matrix3 matrix;
+ Edje_Vector_Data *start, *end;
evas_object_geometry_get(ep->object, NULL, NULL, &w, &h);
}
if (new_svg) // animation with svg id change
{
- Efl_VG *container;
- if (ep->typedata.vector->cache.svg_id != new_svg)
- {
- //create it
- vg_tree = _edje_create_vg_tree(ed->file->ef, new_svg, w, h, &vx, &vy, &vw, &vh);
- if (vg_tree)
- {
- //1. clear the cache
- if (ep->typedata.vector->cache.vg)
- {
- eo_unref(ep->typedata.vector->cache.vg);
- ep->typedata.vector->cache.vg = NULL;
- ep->typedata.vector->cache.svg_id = 0;
- }
- //2. update current
- ep->typedata.vector->cache.svg_id = new_svg;
- ep->typedata.vector->cache.x = vx;
- ep->typedata.vector->cache.y = vy;
- ep->typedata.vector->cache.w = vw;
- ep->typedata.vector->cache.h = vh;
- ep->typedata.vector->cache.vg = vg_tree;
- }
- }
- // just do the interpolation
- if (eo_parent_get(ep->typedata.vector->cur.vg))
- {
- // remove it from the hirarchy
- eo_ref(ep->typedata.vector->cur.vg);
- eo_parent_set(ep->typedata.vector->cur.vg, NULL);
- }
- // create a container
- container = evas_vg_container_add(NULL);
- // reset the matrix.
- Eina_Matrix3 matrix;
- sx = w/ep->typedata.vector->cur.w;
- sy = h/ep->typedata.vector->cur.h;
- // for current vg
+ start = _edje_ref_vector_data(ed, chosen_desc->vg.id);
+ end = _edje_ref_vector_data(ed, new_svg);
+
+ // for start vector
+ sx = w/start->w;
+ sy = h/start->h;
eina_matrix3_identity(&matrix);
- eina_matrix3_translate(&matrix, -ep->typedata.vector->cur.x, -ep->typedata.vector->cur.y);
+ eina_matrix3_translate(&matrix, -start->x, -start->y);
eina_matrix3_scale(&matrix, sx, sy);
- evas_vg_node_transformation_set(ep->typedata.vector->cur.vg, &matrix);
- // for next vg
- sx = w/ep->typedata.vector->cache.w;
- sy = h/ep->typedata.vector->cache.h;
+ evas_vg_node_transformation_set(start->vg, &matrix);
+
+ // for end vector
+ sx = w/end->w;
+ sy = h/end->h;
eina_matrix3_identity(&matrix);
- eina_matrix3_translate(&matrix, -ep->typedata.vector->cache.x, -ep->typedata.vector->cache.y);
+ eina_matrix3_translate(&matrix, -end->x, -end->y);
eina_matrix3_scale(&matrix, sx, sy);
- evas_vg_node_transformation_set(ep->typedata.vector->cache.vg, &matrix);
+ evas_vg_node_transformation_set(end->vg, &matrix);
+
// do the interpolation
- if (evas_vg_node_interpolate(container, ep->typedata.vector->cur.vg, ep->typedata.vector->cache.vg, pos))
- {
- // can interpolate between two svg file
- eo_parent_set(container, root_vg);
- }
- else
+ if (!evas_vg_node_interpolate(ep->typedata.vector->cur.vg, start->vg, end->vg, pos))
{
- // can't interpolate between 2 shape
- // keep the current vg tree
- eo_parent_set(ep->typedata.vector->cur.vg, root_vg);
- // delete the container
- eo_unref(container);
+ ERR(" Can't interpolate check the svg file \n");
}
+ // performance hack
+ // instead of duplicating the tree and applying the transformation
+ // i just updated the transformation matrix and reset it back to null.
+ // assumption is that the root vg will never have a transformation
+ eina_matrix3_identity(&matrix);
+ evas_vg_node_transformation_set(start->vg, &matrix);
+ evas_vg_node_transformation_set(end->vg, &matrix);
}
else
{
if (ep->typedata.vector->cur.svg_id == chosen_desc->vg.id) // no svg file change
{
- Eina_Matrix3 matrix;
sx = w/ep->typedata.vector->cur.w;
sy = h/ep->typedata.vector->cur.h;
eina_matrix3_identity(&matrix);
}
else
{
- Eina_Matrix3 matrix;
- // check in cache if the vg tree already exists
- if (ep->typedata.vector->cache.svg_id == chosen_desc->vg.id)
- {
- int id = ep->typedata.vector->cache.svg_id;
- int vx = ep->typedata.vector->cache.x;
- int vy = ep->typedata.vector->cache.y;
- int vw = ep->typedata.vector->cache.w;
- int vh = ep->typedata.vector->cache.h;
- Efl_VG *vg = ep->typedata.vector->cache.vg;
-
- //1. update the cache from current.
- ep->typedata.vector->cache.svg_id = ep->typedata.vector->cur.svg_id;
- ep->typedata.vector->cache.vg = ep->typedata.vector->cur.vg;
- ep->typedata.vector->cache.x = ep->typedata.vector->cur.x;
- ep->typedata.vector->cache.y = ep->typedata.vector->cur.y;
- ep->typedata.vector->cache.w = ep->typedata.vector->cur.w;
- ep->typedata.vector->cache.h = ep->typedata.vector->cur.h;
- eo_ref(ep->typedata.vector->cache.vg);
- eo_parent_set(ep->typedata.vector->cache.vg, NULL);
-
- //2. update the root node
- sx = w/vw;
- sy = h/vh;
- eina_matrix3_identity(&matrix);
- eina_matrix3_translate(&matrix, -vx, -vy);
- eina_matrix3_scale(&matrix, sx, sy);
- evas_vg_node_transformation_set(vg, &matrix);
- // update parent and ref
- eo_parent_set(vg, root_vg);
-
- //3.update the cur
- ep->typedata.vector->cur.svg_id = id;
- ep->typedata.vector->cur.x = vx;
- ep->typedata.vector->cur.y = vy;
- ep->typedata.vector->cur.w = vw;
- ep->typedata.vector->cur.h = vh;
- ep->typedata.vector->cur.vg = vg;
- }
- else
- {
- //create it
- vg_tree = _edje_create_vg_tree(ed->file->ef, chosen_desc->vg.id, w, h, &vx, &vy, &vw, &vh);
- if (vg_tree)
- {
- //1. clear the cache
- if (ep->typedata.vector->cache.vg)
- {
- eo_unref(ep->typedata.vector->cache.vg);
- ep->typedata.vector->cache.vg = NULL;
- ep->typedata.vector->cache.svg_id = 0;
- }
- // 2. move the current tree to cache
- if (ep->typedata.vector->cur.vg)
- {
- eo_ref(ep->typedata.vector->cur.vg);
- eo_parent_set(ep->typedata.vector->cur.vg, NULL);
- // copy to the cache.
- ep->typedata.vector->cache.svg_id = ep->typedata.vector->cur.svg_id;
- ep->typedata.vector->cache.vg = ep->typedata.vector->cur.vg;
- ep->typedata.vector->cache.x = ep->typedata.vector->cur.x;
- ep->typedata.vector->cache.y = ep->typedata.vector->cur.y;
- ep->typedata.vector->cache.w = ep->typedata.vector->cur.w;
- ep->typedata.vector->cache.h = ep->typedata.vector->cur.h;
- }
- //3. update current
- ep->typedata.vector->cur.svg_id = chosen_desc->vg.id;
- ep->typedata.vector->cur.x = vx;
- ep->typedata.vector->cur.y = vy;
- ep->typedata.vector->cur.w = vw;
- ep->typedata.vector->cur.h = vh;
- ep->typedata.vector->cur.vg = vg_tree;
- eo_parent_set(vg_tree, root_vg);
- }
- else
- {
- //1. clear current
- ep->typedata.vector->cur.svg_id = 0;
- eo_parent_set(ep->typedata.vector->cur.vg, NULL);
- ep->typedata.vector->cur.vg = NULL;
- }
- }
+ if (ep->typedata.vector->cur.vg)
+ eo_del(ep->typedata.vector->cur.vg);
+
+ _edje_dupe_vector_data(ed, chosen_desc->vg.id, w, h, &ep->typedata.vector->cur);
+
+ eo_parent_set(ep->typedata.vector->cur.vg, root_vg);
}
}
}
};
void _edje_file_add(Edje *ed, const Eina_File *f);
+static void _edje_vector_data_free(Edje *ed);
/* START - Nested part support */
#define _edje_smart_nested_type "Evas_Smart_Nested"
_edje_message_del(ed);
_edje_block_violate(ed);
_edje_var_shutdown(ed);
-
+ _edje_vector_data_free(ed);
if (!((ed->file) && (ed->collection)))
{
if (tev)
_apply_vg_property(node, vg);
}
-Efl_VG*
-_edje_create_vg_tree(Eet_File *ef, int svg_id, double width, double height,
- double *vx, double *vy, double *vw, double *vh)
+static void
+_edje_vector_data_free(Edje *ed)
+{
+ Edje_Vector_Data *vector;
+
+ EINA_LIST_FREE(ed->vector_cache, vector)
+ {
+ if (vector->vg) eo_del(vector->vg);
+ free(vector);
+ }
+}
+
+Edje_Vector_Data *
+_edje_ref_vector_data(Edje *ed, int svg_id)
{
- double sx=1.0, sy=1.0;
- Eina_Matrix3 matrix;
- Efl_VG *root = NULL;
- Svg_Node *child;
Eina_List *l;
- Svg_Node *node;
+ Edje_Vector_Data *vector;
char svg_key[20];
Eet_Data_Descriptor *svg_node_eet;
+ Svg_Node *child;
+ Svg_Node *node;
+ Efl_VG *root = NULL;
+
+ // check in the cache
+ EINA_LIST_FOREACH(ed->vector_cache, l, vector)
+ {
+ if (vector->svg_id == svg_id)
+ return vector;
+ }
+
+ // create and put it in the cache.
+ vector = calloc(1, sizeof(Edje_Vector_Data));
+ vector->svg_id = svg_id;
snprintf(svg_key, sizeof(svg_key), "edje/vectors/%i", svg_id);
svg_node_eet = _edje_svg_node_eet();
- node = eet_data_read(ef, svg_node_eet, svg_key);
+ node = eet_data_read(ed->file->ef, svg_node_eet, svg_key);
- if (!node && (node->type != SVG_NODE_DOC)) return NULL;
- if (node->node.doc.vw && node->node.doc.vh)
+ if (!node || (node->type != SVG_NODE_DOC))
+ {
+ root = NULL;
+ }
+ else
{
- sx = width/node->node.doc.vw;
- sy = height/node->node.doc.vh;
root = evas_vg_container_add(NULL);
+ EINA_LIST_FOREACH(node->child, l, child)
+ {
+ _create_vg_node(child, root);
+ }
+ vector->x = node->node.doc.vx;
+ vector->y = node->node.doc.vy;
+ vector->w = node->node.doc.vw;
+ vector->h = node->node.doc.vh;
+ }
+ vector->vg = root;
+ ed->vector_cache = eina_list_append(ed->vector_cache, vector);
+ return vector;
+}
+
+void
+_edje_dupe_vector_data(Edje *ed, int svg_id, double width, double height,
+ Edje_Vector_Data *data)
+{
+ double sx=1.0, sy=1.0;
+ Edje_Vector_Data *vector;
+ Efl_VG *root;
+ Eina_Matrix3 matrix;
+
+ vector = _edje_ref_vector_data(ed, svg_id);
+ if (!vector->vg)
+ {
+ data->vg = NULL;
+ }
+
+ root = evas_vg_container_add(NULL);
+ efl_vg_dup(root, vector->vg);
+
+ if (vector->w && vector->h)
+ {
+ sx = width/vector->w;
+ sy = height/vector->h;
eina_matrix3_identity(&matrix);
- eina_matrix3_translate(&matrix, -node->node.doc.vx, -node->node.doc.vy);
+ eina_matrix3_translate(&matrix, -vector->x, -vector->y);
eina_matrix3_scale(&matrix, sx, sy);
evas_vg_node_transformation_set(root, &matrix);
}
- EINA_LIST_FOREACH(node->child, l, child)
- {
- _create_vg_node(child, root);
- }
- *vx = node->node.doc.vx;
- *vy = node->node.doc.vy;
- *vw = node->node.doc.vw;
- *vh = node->node.doc.vh;
- return root;
+ data->vg = root;
+ data->x = vector->x;
+ data->y = vector->y;
+ data->w = vector->w;
+ data->h = vector->h;
}