forked from enlightenment/efl
evas vector: support lottie animation as using json loader.
Summary: This patch extends efl_canvas_vg_object class to implement efl_gfx_frame_controller to suppor any playable animation on it. Plus, vector object takes care of lottie animation by using json loader. it's caching mechanism is changed to cache only static frame, not all frames. vg_cache supports json loader and make it animation request properly. This feature has been stabilized enough, it's using in Samsung Galaxy Watch active product, proved its stability enough. Depends on {D8940} Co-authored-by: JunsuChoi <jsuya.choi@samsung.com> Reviewers: #committers, jsuya Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8941
This commit is contained in:
parent
23af6ec640
commit
625e11f584
|
@ -3613,6 +3613,82 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
|
||||||
*/
|
*/
|
||||||
EAPI Evas_Object *evas_object_vg_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
EAPI Evas_Object *evas_object_vg_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total number of frames of the vector, if it's animated.
|
||||||
|
*
|
||||||
|
* @return The number of frames. 0, if it's not animated.
|
||||||
|
*
|
||||||
|
* @since 1.23
|
||||||
|
*/
|
||||||
|
EAPI int evas_object_vg_animated_frame_count_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the duration of a sequence of frames.
|
||||||
|
*
|
||||||
|
* This returns total duration in seconds that the specified
|
||||||
|
* sequence of frames should take.
|
||||||
|
*
|
||||||
|
* If @p start_frame is 1 and @p frame_num is 0, this returns the
|
||||||
|
* duration of frame 1. If @p start_frame is 1 and @p frame_num is 1,
|
||||||
|
* this returns the total duration of frame 1 + frame 2.
|
||||||
|
*
|
||||||
|
* @param[in] start_frame The first frame, ranges from 1 to maximum frame count.
|
||||||
|
* @param[in] frame_num Number of frames in the sequence, starts from 0.
|
||||||
|
*
|
||||||
|
* @return Duration in seconds.
|
||||||
|
*
|
||||||
|
* @see evas_object_vg_animated_frame_count_get()
|
||||||
|
* @since 1.23
|
||||||
|
*/
|
||||||
|
EAPI double evas_object_vg_animated_frame_duration_get(const Evas_Object *obj, int start_frame EINA_UNUSED, int frame_num EINA_UNUSED) EINA_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Set the source file from where an vector object must fetch the real
|
||||||
|
* vector data (it may be one of json, svg, eet files).
|
||||||
|
*
|
||||||
|
* If the file supports multiple data stored in it (as Eet files do),
|
||||||
|
* you can specify the key to be used as the index of the vector in
|
||||||
|
* this file.
|
||||||
|
*
|
||||||
|
* @param[in] file The vector file path.
|
||||||
|
* @param[in] key The vector key in @p file (if its an Eet one), or @c
|
||||||
|
NULL, otherwise.
|
||||||
|
*
|
||||||
|
* @return @c EINA_TRUE if it's succeed to read file, @c EINA_FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since 1.23
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool evas_object_vg_file_set(Evas_Object *obj, const char *file, const char *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set current frame of animated vector object.
|
||||||
|
*
|
||||||
|
* @param[in] frame_index The index of current frame.
|
||||||
|
*
|
||||||
|
* @note the @p frame_index must be in range of animation frames. (0 ~ max frame count)
|
||||||
|
*
|
||||||
|
* @return @c EINA_TRUE, if the frame index is valid. @c EINA_FALSE, otherwise.
|
||||||
|
*
|
||||||
|
* @see evas_object_vg_animated_frame_count_get()
|
||||||
|
*
|
||||||
|
* @since 1.23
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool evas_object_vg_animated_frame_set(Evas_Object *obj, int frame_index) EINA_ARG_NONNULL(1, 2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current frame number of animated vector object.
|
||||||
|
*
|
||||||
|
* @return The frame index.
|
||||||
|
*
|
||||||
|
* @see evas_object_vg_animated_frame_set()
|
||||||
|
* @see evas_object_vg_animated_frame_count_get()
|
||||||
|
*
|
||||||
|
* @since 1.23
|
||||||
|
*/
|
||||||
|
EAPI int evas_object_vg_animated_frame_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
|
||||||
#include "canvas/efl_canvas_vg_node_eo.legacy.h"
|
#include "canvas/efl_canvas_vg_node_eo.legacy.h"
|
||||||
#include "canvas/efl_canvas_vg_object_eo.legacy.h"
|
#include "canvas/efl_canvas_vg_object_eo.legacy.h"
|
||||||
#include "canvas/efl_canvas_vg_container_eo.legacy.h"
|
#include "canvas/efl_canvas_vg_container_eo.legacy.h"
|
||||||
|
|
|
@ -124,7 +124,7 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
||||||
if (!pd->mask.buffer) ERR("Mask Buffer is invalid");
|
if (!pd->mask.buffer) ERR("Mask Buffer is invalid");
|
||||||
|
|
||||||
//FIXME: This code means that there is another masking container.
|
//FIXME: This code means that there is another masking container.
|
||||||
if (pd->mask.option != EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE)
|
if (pd->mask.option >= EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD)
|
||||||
{
|
{
|
||||||
Efl_Canvas_Vg_Container_Data *src_pd = pd;
|
Efl_Canvas_Vg_Container_Data *src_pd = pd;
|
||||||
mask = pd->mask.buffer;
|
mask = pd->mask.buffer;
|
||||||
|
@ -178,7 +178,11 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
|
||||||
EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
|
EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
|
||||||
|
|
||||||
//Container may have mask source.
|
//Container may have mask source.
|
||||||
if (pd->mask_src && !pd->mask.target)
|
//FIXME : _prepare_mask() should only work in cases with matte or main mask.
|
||||||
|
// This condition is valid because the main mask use same type as matte alpha.
|
||||||
|
if (pd->mask_src &&
|
||||||
|
(pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA ||
|
||||||
|
pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV))
|
||||||
{
|
{
|
||||||
mask_op = pd->mask.option;
|
mask_op = pd->mask.option;
|
||||||
mask = _prepare_mask(vg_pd, pd->mask_src,
|
mask = _prepare_mask(vg_pd, pd->mask_src,
|
||||||
|
|
|
@ -117,7 +117,7 @@ _efl_canvas_vg_object_root_node_get(const Eo *obj, Efl_Canvas_Vg_Object_Data *pd
|
||||||
evas_cache_vg_entry_del(pd->vg_entry);
|
evas_cache_vg_entry_del(pd->vg_entry);
|
||||||
pd->vg_entry = vg_entry;
|
pd->vg_entry = vg_entry;
|
||||||
}
|
}
|
||||||
root = evas_cache_vg_tree_get(pd->vg_entry);
|
root = evas_cache_vg_tree_get(pd->vg_entry, pd->frame_idx);
|
||||||
}
|
}
|
||||||
else if (pd->user_entry) root = pd->user_entry->root;
|
else if (pd->user_entry) root = pd->user_entry->root;
|
||||||
else root = pd->root;
|
else root = pd->root;
|
||||||
|
@ -459,7 +459,7 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
|
||||||
static void *
|
static void *
|
||||||
_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
|
_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
|
||||||
void *engine, Efl_VG *root, int w, int h, void *buffer,
|
void *engine, Efl_VG *root, int w, int h, void *buffer,
|
||||||
Eina_Bool do_async)
|
Eina_Bool do_async, Eina_Bool cacheable)
|
||||||
{
|
{
|
||||||
Ector_Surface *ector;
|
Ector_Surface *ector;
|
||||||
RGBA_Draw_Context *context;
|
RGBA_Draw_Context *context;
|
||||||
|
@ -502,10 +502,11 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
|
||||||
ENFN->ector_end(engine, buffer, context, ector, do_async);
|
ENFN->ector_end(engine, buffer, context, ector, do_async);
|
||||||
evas_common_draw_context_free(context);
|
evas_common_draw_context_free(context);
|
||||||
|
|
||||||
if (buffer_created)
|
if (buffer_created && cacheable)
|
||||||
{
|
{
|
||||||
//Use root as a cache key.
|
//Use root as a cache key.
|
||||||
ENFN->ector_surface_cache_set(engine, root, buffer);
|
ENFN->ector_surface_cache_set(engine, root, buffer);
|
||||||
|
pd->cached_frame_idx = pd->frame_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
@ -516,7 +517,7 @@ _render_buffer_to_screen(Evas_Object_Protected_Data *obj,
|
||||||
void *engine, void *output, void *context, void *surface,
|
void *engine, void *output, void *context, void *surface,
|
||||||
void *buffer,
|
void *buffer,
|
||||||
int x, int y, int w, int h,
|
int x, int y, int w, int h,
|
||||||
Eina_Bool do_async)
|
Eina_Bool do_async, Eina_Bool cacheable)
|
||||||
{
|
{
|
||||||
Eina_Bool async_unref;
|
Eina_Bool async_unref;
|
||||||
|
|
||||||
|
@ -532,49 +533,107 @@ _render_buffer_to_screen(Evas_Object_Protected_Data *obj,
|
||||||
evas_cache_image_ref((Image_Entry *)buffer);
|
evas_cache_image_ref((Image_Entry *)buffer);
|
||||||
evas_unref_queue_image_put(obj->layer->evas, buffer);
|
evas_unref_queue_image_put(obj->layer->evas, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Reuse buffer if size is same?
|
||||||
|
if (!cacheable) ENFN->ector_surface_destroy(engine, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cache_vg_entry_render(Evas_Object_Protected_Data *obj,
|
_cache_vg_entry_render(Evas_Object_Protected_Data *obj,
|
||||||
Efl_Canvas_Vg_Object_Data *pd,
|
Efl_Canvas_Vg_Object_Data *pd,
|
||||||
void *engine, void *output, void *context, void *surface,
|
void *engine, void *output, void *context, void *surface,
|
||||||
int x, int y, int w, int h, Eina_Bool do_async)
|
int x, int y, int w, int h, Eina_Bool do_async,
|
||||||
|
Eina_Bool cacheable)
|
||||||
{
|
{
|
||||||
Vg_Cache_Entry *vg_entry = pd->vg_entry;
|
Vg_Cache_Entry *vg_entry = pd->vg_entry;
|
||||||
Efl_VG *root;
|
Efl_VG *root;
|
||||||
|
Eina_Position2D offset = {0, 0}; //Offset after keeping aspect ratio.
|
||||||
|
Eina_Bool drop_cache = EINA_FALSE;
|
||||||
|
void *buffer = NULL;
|
||||||
|
|
||||||
// if the size changed in between path set and the draw call;
|
// if the size changed in between path set and the draw call;
|
||||||
|
|
||||||
if ((vg_entry->w != w) ||
|
if ((vg_entry->w != w) ||
|
||||||
(vg_entry->h != h))
|
(vg_entry->h != h))
|
||||||
{
|
{
|
||||||
vg_entry = evas_cache_vg_entry_resize(vg_entry, w, h);
|
Eina_Size2D size = evas_cache_vg_entry_default_size_get(pd->vg_entry);
|
||||||
evas_cache_vg_entry_del(pd->vg_entry);
|
|
||||||
pd->vg_entry = vg_entry;
|
//adjust size for aspect ratio.
|
||||||
|
if (size.w > 0 && size.h > 0)
|
||||||
|
{
|
||||||
|
float rw = (float) w / (float) size.w;
|
||||||
|
float rh = (float) h / (float) size.h;
|
||||||
|
|
||||||
|
if (rw < rh)
|
||||||
|
{
|
||||||
|
size.w = w;
|
||||||
|
size.h = (int) ((float) size.h * rw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size.w = (int) ((float) size.w * rh);
|
||||||
|
size.h = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size.w = w;
|
||||||
|
size.h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Size is changed, cached data is invalid.
|
||||||
|
if ((size.w != vg_entry->w) || (size.h != vg_entry->h))
|
||||||
|
{
|
||||||
|
drop_cache = EINA_TRUE;
|
||||||
|
vg_entry = evas_cache_vg_entry_resize(vg_entry, size.w, size.h);
|
||||||
|
evas_cache_vg_entry_del(pd->vg_entry);
|
||||||
|
pd->vg_entry = vg_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
//update for adjusted pos and size.
|
||||||
|
offset.x = w - size.w;
|
||||||
|
if (offset.x > 0) offset.x /= 2;
|
||||||
|
offset.y = h - size.h;
|
||||||
|
if (offset.y > 0) offset.y /= 2;
|
||||||
|
w = size.w;
|
||||||
|
h = size.h;
|
||||||
|
|
||||||
}
|
}
|
||||||
root = evas_cache_vg_tree_get(vg_entry);
|
root = evas_cache_vg_tree_get(vg_entry, pd->frame_idx);
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
|
|
||||||
void *buffer = ENFN->ector_surface_cache_get(engine, root);
|
if (cacheable)
|
||||||
|
{
|
||||||
|
//if the size doesn't match, drop previous cache surface.
|
||||||
|
if (drop_cache)
|
||||||
|
ENFN->ector_surface_cache_drop(engine, (void *) root);
|
||||||
|
//Cache Hit!
|
||||||
|
else if (pd->frame_idx == pd->cached_frame_idx)
|
||||||
|
buffer = ENFN->ector_surface_cache_get(engine, (void *) root);
|
||||||
|
//Drop invalid one.
|
||||||
|
else
|
||||||
|
ENFN->ector_surface_cache_drop(engine, (void *) root);
|
||||||
|
}
|
||||||
|
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL, do_async);
|
buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL,
|
||||||
|
do_async, cacheable);
|
||||||
else
|
else
|
||||||
//cache reference was increased when we get the cache.
|
//cache reference was increased when we get the cache.
|
||||||
ENFN->ector_surface_cache_drop(engine, root);
|
ENFN->ector_surface_cache_drop(engine, (void *) root);
|
||||||
|
|
||||||
_render_buffer_to_screen(obj,
|
_render_buffer_to_screen(obj,
|
||||||
engine, output, context, surface,
|
engine, output, context, surface,
|
||||||
buffer,
|
buffer,
|
||||||
x, y, w, h,
|
x + offset.x, y + offset.y, w, h,
|
||||||
do_async);
|
do_async, cacheable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_user_vg_entry_render(Evas_Object_Protected_Data *obj,
|
_user_vg_entry_render(Evas_Object_Protected_Data *obj,
|
||||||
Efl_Canvas_Vg_Object_Data *pd,
|
Efl_Canvas_Vg_Object_Data *pd,
|
||||||
void *engine, void *output, void *context, void *surface,
|
void *engine, void *output, void *context, void *surface,
|
||||||
int x, int y, int w, int h, Eina_Bool do_async)
|
int x, int y, int w, int h, Eina_Bool do_async,
|
||||||
|
Eina_Bool cacheable)
|
||||||
{
|
{
|
||||||
Vg_User_Entry *user_entry = pd->user_entry;
|
Vg_User_Entry *user_entry = pd->user_entry;
|
||||||
|
|
||||||
|
@ -588,13 +647,16 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the buffer is not created yet
|
//if the buffer is not created yet
|
||||||
void *buffer = ENFN->ector_surface_cache_get(engine, user_entry->root);
|
void *buffer = NULL;
|
||||||
|
|
||||||
|
if (cacheable)
|
||||||
|
buffer = ENFN->ector_surface_cache_get(engine, user_entry->root);
|
||||||
|
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
// render to the buffer
|
// render to the buffer
|
||||||
buffer = _render_to_buffer(obj, pd, engine, user_entry->root,
|
buffer = _render_to_buffer(obj, pd, engine, user_entry->root,
|
||||||
w, h, buffer, do_async);
|
w, h, buffer, do_async, cacheable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -602,9 +664,8 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
|
||||||
if (pd->changed)
|
if (pd->changed)
|
||||||
buffer = _render_to_buffer(obj, pd, engine,
|
buffer = _render_to_buffer(obj, pd, engine,
|
||||||
user_entry->root,
|
user_entry->root,
|
||||||
w, h,
|
w, h, buffer,
|
||||||
buffer,
|
do_async, EINA_FALSE);
|
||||||
do_async);
|
|
||||||
//cache reference was increased when we get the cache.
|
//cache reference was increased when we get the cache.
|
||||||
ENFN->ector_surface_cache_drop(engine, user_entry->root);
|
ENFN->ector_surface_cache_drop(engine, user_entry->root);
|
||||||
}
|
}
|
||||||
|
@ -613,7 +674,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
|
||||||
engine, output, context, surface,
|
engine, output, context, surface,
|
||||||
buffer,
|
buffer,
|
||||||
x, y, w, h,
|
x, y, w, h,
|
||||||
do_async);
|
do_async, cacheable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -635,19 +696,30 @@ _efl_canvas_vg_object_render(Evas_Object *eo_obj EINA_UNUSED,
|
||||||
ENFN->context_anti_alias_set(engine, context, obj->cur->anti_alias);
|
ENFN->context_anti_alias_set(engine, context, obj->cur->anti_alias);
|
||||||
ENFN->context_render_op_set(engine, context, obj->cur->render_op);
|
ENFN->context_render_op_set(engine, context, obj->cur->render_op);
|
||||||
|
|
||||||
|
//Cache surface?
|
||||||
|
Eina_Bool cacheable = EINA_FALSE;
|
||||||
|
|
||||||
|
/* Try caching buffer only for first and last frames
|
||||||
|
because it's an overhead task if it caches all frame images.
|
||||||
|
We assume the first and last frame images are the most resusable
|
||||||
|
in generic scenarios. */
|
||||||
|
if (pd->frame_idx == 0 ||
|
||||||
|
(pd->frame_idx == (int) (evas_cache_vg_anim_frame_count_get(pd->vg_entry) - 1)))
|
||||||
|
cacheable = EINA_TRUE;
|
||||||
|
|
||||||
if (pd->vg_entry)
|
if (pd->vg_entry)
|
||||||
{
|
{
|
||||||
_cache_vg_entry_render(obj, pd,
|
_cache_vg_entry_render(obj, pd,
|
||||||
engine, output, context, surface,
|
engine, output, context, surface,
|
||||||
obj->cur->geometry.x + x, obj->cur->geometry.y + y,
|
obj->cur->geometry.x + x, obj->cur->geometry.y + y,
|
||||||
obj->cur->geometry.w, obj->cur->geometry.h, do_async);
|
obj->cur->geometry.w, obj->cur->geometry.h, do_async, cacheable);
|
||||||
}
|
}
|
||||||
if (pd->user_entry)
|
if (pd->user_entry)
|
||||||
{
|
{
|
||||||
_user_vg_entry_render(obj, pd,
|
_user_vg_entry_render(obj, pd,
|
||||||
engine, output, context, surface,
|
engine, output, context, surface,
|
||||||
obj->cur->geometry.x + x, obj->cur->geometry.y + y,
|
obj->cur->geometry.x + x, obj->cur->geometry.y + y,
|
||||||
obj->cur->geometry.w, obj->cur->geometry.h, do_async);
|
obj->cur->geometry.w, obj->cur->geometry.h, do_async, cacheable);
|
||||||
}
|
}
|
||||||
pd->changed = EINA_FALSE;
|
pd->changed = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -804,6 +876,79 @@ _efl_canvas_vg_object_was_opaque(Evas_Object *eo_obj EINA_UNUSED,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* animated feature */
|
||||||
|
EOLIAN static Eina_Bool
|
||||||
|
_efl_canvas_vg_object_efl_gfx_frame_controller_animated_get(const Eo *eo_obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd EINA_UNUSED EINA_UNUSED)
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static int
|
||||||
|
_efl_canvas_vg_object_efl_gfx_frame_controller_frame_count_get(const Eo *eo_obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
if (!pd->vg_entry) return 0;
|
||||||
|
return evas_cache_vg_anim_frame_count_get(pd->vg_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Efl_Gfx_Frame_Controller_Loop_Hint
|
||||||
|
_efl_canvas_vg_object_efl_gfx_frame_controller_loop_type_get(const Eo *eo_obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
return EFL_GFX_FRAME_CONTROLLER_LOOP_HINT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static int
|
||||||
|
_efl_canvas_vg_object_efl_gfx_frame_controller_loop_count_get(const Eo *eo_obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static double
|
||||||
|
_efl_canvas_vg_object_efl_gfx_frame_controller_frame_duration_get(const Eo *eo_obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd,
|
||||||
|
int start_frame EINA_UNUSED,
|
||||||
|
int frame_num EINA_UNUSED)
|
||||||
|
{
|
||||||
|
if (!pd->vg_entry) return 0;
|
||||||
|
return evas_cache_vg_anim_duration_get(pd->vg_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Eina_Bool
|
||||||
|
_efl_canvas_vg_object_efl_gfx_frame_controller_frame_set(Eo *eo_obj,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd,
|
||||||
|
int frame_index)
|
||||||
|
{
|
||||||
|
//TODO: Validate frame_index range
|
||||||
|
if (pd->frame_idx == frame_index) return EINA_TRUE;
|
||||||
|
|
||||||
|
//Image is changed, drop previous cached image.
|
||||||
|
pd->frame_idx = frame_index;
|
||||||
|
pd->changed = EINA_TRUE;
|
||||||
|
evas_object_change(eo_obj, efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS));
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static int
|
||||||
|
_efl_canvas_vg_object_efl_gfx_frame_controller_frame_get(const Eo *eo_obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
return pd->frame_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Eina_Size2D
|
||||||
|
_efl_canvas_vg_object_default_size_get(const Eo *eo_obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Object_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
return evas_cache_vg_entry_default_size_get(pd->vg_entry);
|
||||||
|
}
|
||||||
|
|
||||||
/* the actual api call to add a vector graphic object */
|
/* the actual api call to add a vector graphic object */
|
||||||
EAPI Evas_Object *
|
EAPI Evas_Object *
|
||||||
evas_object_vg_add(Evas *e)
|
evas_object_vg_add(Evas *e)
|
||||||
|
@ -814,5 +959,35 @@ evas_object_vg_add(Evas *e)
|
||||||
return efl_add(MY_CLASS, e, efl_canvas_object_legacy_ctor(efl_added));
|
return efl_add(MY_CLASS, e, efl_canvas_object_legacy_ctor(efl_added));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI int
|
||||||
|
evas_object_vg_animated_frame_get(const Evas_Object *obj)
|
||||||
|
{
|
||||||
|
return efl_gfx_frame_controller_frame_get(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
evas_object_vg_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int frame_num)
|
||||||
|
{
|
||||||
|
return efl_gfx_frame_controller_frame_duration_get(obj, start_frame, frame_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI int
|
||||||
|
evas_object_vg_animated_frame_count_get(const Evas_Object *obj)
|
||||||
|
{
|
||||||
|
return efl_gfx_frame_controller_frame_count_get(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
evas_object_vg_animated_frame_set(Evas_Object *obj, int frame_index)
|
||||||
|
{
|
||||||
|
return efl_gfx_frame_controller_frame_set(obj, frame_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
evas_object_vg_file_set(Evas_Object *obj, const char *file, const char *key)
|
||||||
|
{
|
||||||
|
return efl_file_simple_load(obj, file, key);
|
||||||
|
}
|
||||||
|
|
||||||
#include "efl_canvas_vg_object.eo.c"
|
#include "efl_canvas_vg_object.eo.c"
|
||||||
#include "efl_canvas_vg_object_eo.legacy.c"
|
#include "efl_canvas_vg_object_eo.legacy.c"
|
||||||
|
|
|
@ -21,7 +21,8 @@ enum @beta Efl.Canvas.Vg.Fill_Mode
|
||||||
dimension of the viewport.]]
|
dimension of the viewport.]]
|
||||||
}
|
}
|
||||||
|
|
||||||
class @beta Efl.Canvas.Vg.Object extends Efl.Canvas.Object implements Efl.File, Efl.File_Save
|
class @beta Efl.Canvas.Vg.Object extends Efl.Canvas.Object implements Efl.File, Efl.File_Save,
|
||||||
|
Efl.Gfx.Frame_Controller
|
||||||
{
|
{
|
||||||
[[Efl vector graphics class]]
|
[[Efl vector graphics class]]
|
||||||
methods {
|
methods {
|
||||||
|
@ -67,6 +68,15 @@ class @beta Efl.Canvas.Vg.Object extends Efl.Canvas.Object implements Efl.File,
|
||||||
root: Efl.Canvas.Vg.Node; [[Root node of the VG canvas.]]
|
root: Efl.Canvas.Vg.Node; [[Root node of the VG canvas.]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@property default_size {
|
||||||
|
get {
|
||||||
|
[[Get the default vector size that specified from vector resource.
|
||||||
|
@since 1.22]]
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
size: Eina.Size2D;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
implements {
|
implements {
|
||||||
Efl.Object.constructor;
|
Efl.Object.constructor;
|
||||||
|
@ -76,5 +86,11 @@ class @beta Efl.Canvas.Vg.Object extends Efl.Canvas.Object implements Efl.File,
|
||||||
Efl.File.unload;
|
Efl.File.unload;
|
||||||
Efl.File.file { set; }
|
Efl.File.file { set; }
|
||||||
Efl.File_Save.save;
|
Efl.File_Save.save;
|
||||||
|
Efl.Gfx.Frame_Controller.animated { get; }
|
||||||
|
Efl.Gfx.Frame_Controller.frame { get; set; }
|
||||||
|
Efl.Gfx.Frame_Controller.frame_count { get; }
|
||||||
|
Efl.Gfx.Frame_Controller.loop_type { get; }
|
||||||
|
Efl.Gfx.Frame_Controller.loop_count { get; }
|
||||||
|
Efl.Gfx.Frame_Controller.frame_duration { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ typedef struct _Vg_Cache_Entry
|
||||||
Eina_Stringshare *key;
|
Eina_Stringshare *key;
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
Efl_VG *root;
|
Efl_VG *root[3]; //0: default, 1: start frame, 2: end frame
|
||||||
int ref;
|
int ref;
|
||||||
Vg_File_Data *vfd;
|
Vg_File_Data *vfd;
|
||||||
} Vg_Cache_Entry;
|
} Vg_Cache_Entry;
|
||||||
|
@ -48,6 +48,8 @@ struct _Efl_Canvas_Vg_Object_Data
|
||||||
Eina_Array cleanup;
|
Eina_Array cleanup;
|
||||||
double align_x, align_y;
|
double align_x, align_y;
|
||||||
Efl_Canvas_Vg_Fill_Mode fill_mode;
|
Efl_Canvas_Vg_Fill_Mode fill_mode;
|
||||||
|
int frame_idx;
|
||||||
|
int cached_frame_idx;
|
||||||
|
|
||||||
Eina_Bool changed : 1;
|
Eina_Bool changed : 1;
|
||||||
};
|
};
|
||||||
|
@ -123,11 +125,14 @@ void evas_cache_vg_init(void);
|
||||||
void evas_cache_vg_shutdown(void);
|
void evas_cache_vg_shutdown(void);
|
||||||
Vg_Cache_Entry* evas_cache_vg_entry_resize(Vg_Cache_Entry *entry, int w, int h);
|
Vg_Cache_Entry* evas_cache_vg_entry_resize(Vg_Cache_Entry *entry, int w, int h);
|
||||||
Vg_Cache_Entry* evas_cache_vg_entry_create(const Eina_File *file, const char *key, int w, int h);
|
Vg_Cache_Entry* evas_cache_vg_entry_create(const Eina_File *file, const char *key, int w, int h);
|
||||||
Efl_VG* evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry);
|
Efl_VG* evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num);
|
||||||
void evas_cache_vg_entry_del(Vg_Cache_Entry *vg_entry);
|
void evas_cache_vg_entry_del(Vg_Cache_Entry *vg_entry);
|
||||||
Vg_File_Data * evas_cache_vg_file_open(const Eina_File *file, const char *key);
|
Vg_File_Data * evas_cache_vg_file_open(const Eina_File *file, const char *key);
|
||||||
Eina_Bool evas_cache_vg_file_save(Efl_VG *root, int w, int h, const char *file, const char *key, const Efl_File_Save_Info *info);
|
Eina_Bool evas_cache_vg_file_save(Efl_VG *root, int w, int h, const char *file, const char *key, const Efl_File_Save_Info *info);
|
||||||
Eina_Bool evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info);
|
Eina_Bool evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info);
|
||||||
|
double evas_cache_vg_anim_duration_get(const Vg_Cache_Entry *vg_entry);
|
||||||
|
unsigned int evas_cache_vg_anim_frame_count_get(const Vg_Cache_Entry *vg_entry);
|
||||||
|
Eina_Size2D evas_cache_vg_entry_default_size_get(const Vg_Cache_Entry *vg_entry);
|
||||||
void efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd);
|
void efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd);
|
||||||
void efl_canvas_vg_node_change(Efl_VG *node);
|
void efl_canvas_vg_node_change(Efl_VG *node);
|
||||||
void efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd);
|
void efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd);
|
||||||
|
|
|
@ -139,6 +139,7 @@ typedef struct _Evas_Canvas3D_Header_Eet Evas_Canvas3D_Header_Eet;
|
||||||
typedef struct _Evas_Canvas3D_File_Eet Evas_Canvas3D_File_Eet;
|
typedef struct _Evas_Canvas3D_File_Eet Evas_Canvas3D_File_Eet;
|
||||||
|
|
||||||
typedef struct _Vg_File_Data Vg_File_Data;
|
typedef struct _Vg_File_Data Vg_File_Data;
|
||||||
|
typedef struct _Vg_File_Anim_Data Vg_File_Anim_Data;
|
||||||
|
|
||||||
struct _Evas_Canvas3D_Vec2_Eet
|
struct _Evas_Canvas3D_Vec2_Eet
|
||||||
{
|
{
|
||||||
|
@ -1510,13 +1511,25 @@ struct _Evas_Image_Save_Func
|
||||||
int (*image_save) (RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
|
int (*image_save) (RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _Vg_File_Anim_Data
|
||||||
|
{
|
||||||
|
unsigned int frame_num; //current frame number
|
||||||
|
unsigned int frame_cnt; //total frame count
|
||||||
|
float duration; //animation duration
|
||||||
|
};
|
||||||
|
|
||||||
struct _Vg_File_Data
|
struct _Vg_File_Data
|
||||||
{
|
{
|
||||||
Efl_VG *root;
|
Efl_VG *root;
|
||||||
Evas_Vg_Load_Func *loader;
|
Evas_Vg_Load_Func *loader;
|
||||||
Eina_Rectangle view_box;
|
Eina_Rectangle view_box;
|
||||||
|
Vg_File_Anim_Data *anim_data; //only when animation supported.
|
||||||
int ref;
|
int ref;
|
||||||
|
int w, h; //default size
|
||||||
|
|
||||||
|
void *loader_data; //loader specific local data
|
||||||
|
|
||||||
|
Eina_Bool no_share : 1; //Shareable VFD through multiple file open requests.
|
||||||
Eina_Bool static_viewbox: 1;
|
Eina_Bool static_viewbox: 1;
|
||||||
Eina_Bool preserve_aspect : 1; //Used in SVG
|
Eina_Bool preserve_aspect : 1; //Used in SVG
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ static const struct ext_loader_s loaders[] =
|
||||||
|
|
||||||
static const char *loaders_name[] =
|
static const char *loaders_name[] =
|
||||||
{ /* in order of most likely needed */
|
{ /* in order of most likely needed */
|
||||||
"eet", "svg"
|
"eet", "json", "svg"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ext_saver_s savers[] =
|
static const struct ext_saver_s savers[] =
|
||||||
|
@ -153,19 +153,26 @@ _evas_cache_vg_entry_free_cb(void *data)
|
||||||
|
|
||||||
if (vg_entry->vfd->ref <= 0)
|
if (vg_entry->vfd->ref <= 0)
|
||||||
{
|
{
|
||||||
Eina_Strbuf *hash_key = eina_strbuf_new();
|
if (vg_entry->vfd->no_share)
|
||||||
eina_strbuf_append_printf(hash_key, "%s/%s",
|
vg_entry->vfd->loader->file_close(vg_entry->vfd);
|
||||||
eina_file_filename_get(vg_entry->file),
|
else
|
||||||
vg_entry->key);
|
{
|
||||||
if (!eina_hash_del(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vg_entry->vfd))
|
Eina_Strbuf *hash_key = eina_strbuf_new();
|
||||||
ERR("Failed to delete vfd = (%p) from hash", vg_entry->vfd);
|
eina_strbuf_append_printf(hash_key, "%s/%s",
|
||||||
eina_strbuf_free(hash_key);
|
eina_file_filename_get(vg_entry->file),
|
||||||
|
vg_entry->key);
|
||||||
|
if (!eina_hash_del(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vg_entry->vfd))
|
||||||
|
ERR("Failed to delete vfd = (%p) from hash", vg_entry->vfd);
|
||||||
|
eina_strbuf_free(hash_key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eina_stringshare_del(vg_entry->key);
|
eina_stringshare_del(vg_entry->key);
|
||||||
free(vg_entry->hash_key);
|
free(vg_entry->hash_key);
|
||||||
efl_unref(vg_entry->root);
|
efl_unref(vg_entry->root[0]);
|
||||||
|
efl_unref(vg_entry->root[1]);
|
||||||
|
efl_unref(vg_entry->root[2]);
|
||||||
free(vg_entry);
|
free(vg_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,9 +202,37 @@ _vg_file_save(Vg_File_Data *vfd, const char *file, const char *key, const Efl_Fi
|
||||||
}
|
}
|
||||||
|
|
||||||
static Efl_VG*
|
static Efl_VG*
|
||||||
_cached_root_get(Vg_Cache_Entry *vg_entry)
|
_cached_root_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num)
|
||||||
{
|
{
|
||||||
return vg_entry->root;
|
Vg_File_Data *vfd = vg_entry->vfd;
|
||||||
|
|
||||||
|
//Case 1: Animatable
|
||||||
|
if (vfd->anim_data)
|
||||||
|
{
|
||||||
|
//Start frame
|
||||||
|
if (vg_entry->root[1] && frame_num == 0)
|
||||||
|
{
|
||||||
|
return vg_entry->root[1];
|
||||||
|
}
|
||||||
|
//End frame
|
||||||
|
else if (vg_entry->root[2] && (frame_num == (vfd->anim_data->frame_cnt - 1)))
|
||||||
|
{
|
||||||
|
return vg_entry->root[2];
|
||||||
|
}
|
||||||
|
//Current frame
|
||||||
|
else if (vg_entry->root[0] && (frame_num == (vfd->anim_data->frame_num)))
|
||||||
|
{
|
||||||
|
return vg_entry->root[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Case 2: Static
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (vg_entry->root[0])
|
||||||
|
return vg_entry->root[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -214,12 +249,34 @@ _caching_root_update(Vg_Cache_Entry *vg_entry)
|
||||||
/* TODO: Yet trivial but still we may have a better solution to
|
/* TODO: Yet trivial but still we may have a better solution to
|
||||||
avoid this unnecessary copy. If the ector surface key is not
|
avoid this unnecessary copy. If the ector surface key is not
|
||||||
to this root pointer. */
|
to this root pointer. */
|
||||||
vg_entry->root = efl_duplicate(vfd->root);
|
vg_entry->root[0] = efl_duplicate(vfd->root);
|
||||||
}
|
}
|
||||||
else if (vg_entry->root != vfd->root)
|
else if (vg_entry->root[0] != vfd->root)
|
||||||
{
|
{
|
||||||
if (vg_entry->root) efl_unref(vg_entry->root);
|
if (vg_entry->root[0]) efl_unref(vg_entry->root[0]);
|
||||||
vg_entry->root = efl_ref(vfd->root);
|
vg_entry->root[0] = efl_ref(vfd->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Animatable?
|
||||||
|
if (!vfd->anim_data) return;
|
||||||
|
|
||||||
|
//Start frame
|
||||||
|
if (vfd->anim_data->frame_num == 0)
|
||||||
|
{
|
||||||
|
if (vg_entry->root[1] != vfd->root)
|
||||||
|
{
|
||||||
|
if (vg_entry->root[1]) efl_unref(vg_entry->root[1]);
|
||||||
|
vg_entry->root[1] = efl_ref(vfd->root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//End frame
|
||||||
|
else if (vfd->anim_data->frame_num == (vfd->anim_data->frame_cnt - 1))
|
||||||
|
{
|
||||||
|
if (vg_entry->root[2] != vfd->root)
|
||||||
|
{
|
||||||
|
if (vg_entry->root[2]) efl_unref(vg_entry->root[2]);
|
||||||
|
vg_entry->root[2] = efl_ref(vfd->root);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,11 +351,12 @@ evas_cache_vg_file_open(const Eina_File *file, const char *key)
|
||||||
hash_key = eina_strbuf_new();
|
hash_key = eina_strbuf_new();
|
||||||
eina_strbuf_append_printf(hash_key, "%s/%s", eina_file_filename_get(file), key);
|
eina_strbuf_append_printf(hash_key, "%s/%s", eina_file_filename_get(file), key);
|
||||||
vfd = eina_hash_find(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key));
|
vfd = eina_hash_find(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key));
|
||||||
if (!vfd)
|
if (!vfd || vfd->no_share)
|
||||||
{
|
{
|
||||||
vfd = _vg_load_from_file(file, key);
|
vfd = _vg_load_from_file(file, key);
|
||||||
//File exists.
|
//File exists.
|
||||||
if (vfd) eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
|
if (vfd && !vfd->no_share)
|
||||||
|
eina_hash_add(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vfd);
|
||||||
}
|
}
|
||||||
eina_strbuf_free(hash_key);
|
eina_strbuf_free(hash_key);
|
||||||
return vfd;
|
return vfd;
|
||||||
|
@ -356,8 +414,24 @@ evas_cache_vg_entry_create(const Eina_File *file,
|
||||||
return vg_entry;
|
return vg_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
evas_cache_vg_anim_duration_get(const Vg_Cache_Entry* vg_entry)
|
||||||
|
{
|
||||||
|
if (!vg_entry->vfd->anim_data) return 0;
|
||||||
|
return vg_entry->vfd->anim_data->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
evas_cache_vg_anim_frame_count_get(const Vg_Cache_Entry* vg_entry)
|
||||||
|
{
|
||||||
|
if (!vg_entry) return 0;
|
||||||
|
Vg_File_Data *vfd = vg_entry->vfd;
|
||||||
|
if (!vfd || !vfd->anim_data) return 0;
|
||||||
|
return vfd->anim_data->frame_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
Efl_VG*
|
Efl_VG*
|
||||||
evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry)
|
evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num)
|
||||||
{
|
{
|
||||||
if (!vg_entry) return NULL;
|
if (!vg_entry) return NULL;
|
||||||
if ((vg_entry->w < 1) || (vg_entry->h < 1)) return NULL;
|
if ((vg_entry->w < 1) || (vg_entry->h < 1)) return NULL;
|
||||||
|
@ -365,7 +439,7 @@ evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry)
|
||||||
Vg_File_Data *vfd = vg_entry->vfd;
|
Vg_File_Data *vfd = vg_entry->vfd;
|
||||||
if (!vfd) return NULL;
|
if (!vfd) return NULL;
|
||||||
|
|
||||||
Efl_VG *root = _cached_root_get(vg_entry);
|
Efl_VG *root = _cached_root_get(vg_entry, frame_num);
|
||||||
if (root) return root;
|
if (root) return root;
|
||||||
|
|
||||||
if (!vfd->static_viewbox)
|
if (!vfd->static_viewbox)
|
||||||
|
@ -374,13 +448,15 @@ evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry)
|
||||||
vfd->view_box.h = vg_entry->h;
|
vfd->view_box.h = vg_entry->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vfd->anim_data) vfd->anim_data->frame_num = frame_num;
|
||||||
|
|
||||||
if (!vfd->loader->file_data(vfd)) return NULL;
|
if (!vfd->loader->file_data(vfd)) return NULL;
|
||||||
|
|
||||||
_caching_root_update(vg_entry);
|
_caching_root_update(vg_entry);
|
||||||
|
|
||||||
_local_transform(vg_entry->root, vg_entry->w, vg_entry->h, vfd);
|
_local_transform(vg_entry->root[0], vg_entry->w, vg_entry->h, vfd);
|
||||||
|
|
||||||
return vg_entry->root;
|
return vg_entry->root[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -393,6 +469,13 @@ evas_cache_vg_entry_del(Vg_Cache_Entry *vg_entry)
|
||||||
ERR("Failed to delete vg_entry = (%p) from hash", vg_entry);
|
ERR("Failed to delete vg_entry = (%p) from hash", vg_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Eina_Size2D
|
||||||
|
evas_cache_vg_entry_default_size_get(const Vg_Cache_Entry *vg_entry)
|
||||||
|
{
|
||||||
|
if (!vg_entry) return EINA_SIZE2D(0, 0);
|
||||||
|
return EINA_SIZE2D(vg_entry->vfd->w, vg_entry->vfd->h);
|
||||||
|
}
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info)
|
evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue