Last active
March 22, 2026 12:57
-
-
Save vtorri/af7db9193a5c90c43fabfc7b9a8e7ac3 to your computer and use it in GitHub Desktop.
example of usage of ThorVG for lottie files with the EFL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* gcc -g -Wall -Wextra -o efl_lot efl_lot.c `pkgconf --cflags --libs eina ecore evas ecore-evas thorvg-1` */ | |
| #include <stdio.h> | |
| //#include <windows.h> | |
| #include <Eina.h> | |
| #include <Ecore.h> | |
| #include <Evas.h> | |
| #include <Ecore_Evas.h> | |
| #include <thorvg_capi.h> | |
| typedef struct | |
| { | |
| Evas_Object *o; | |
| Tvg_Canvas canvas; | |
| Tvg_Animation animation; | |
| unsigned int *pixels; | |
| float total; | |
| float duration; | |
| int current; | |
| } Data; | |
| static Ecore_Timer *timer; | |
| static Eina_Bool | |
| _anim_cb(void *data) | |
| { | |
| Data *d = data; | |
| int w; | |
| int h; | |
| d->current++; | |
| if (d->current > d->total) | |
| d->current = 0; | |
| tvg_animation_set_frame(d->animation, d->current); | |
| tvg_canvas_update(d->canvas); | |
| tvg_canvas_draw(d->canvas, true); // true or false ?? | |
| tvg_canvas_sync(d->canvas); | |
| evas_object_image_data_set(d->o, d->pixels); | |
| evas_object_geometry_get(d->o, NULL, NULL, &w, &h); | |
| evas_object_image_data_update_add(d->o, 0, 0, w, h); | |
| return ECORE_CALLBACK_RENEW; | |
| } | |
| static void _quit(Ecore_Evas *ee) | |
| { | |
| ecore_main_loop_quit(); | |
| (void)ee; | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| Ecore_Evas *ee; | |
| Evas *evas; | |
| Evas_Object *o; | |
| int w,h; | |
| Evas_Load_Error err; | |
| Tvg_Result res; | |
| Tvg_Canvas canvas; | |
| unsigned int *pixels; | |
| if (argc < 2) | |
| { | |
| printf("Usage: %s file.json\n", argv[0]); | |
| fflush(stdout); | |
| return 1; | |
| } | |
| ///// ThorVG | |
| // init: number of threads: 4 | |
| res = tvg_engine_init(4); | |
| if (res != TVG_RESULT_SUCCESS) | |
| { | |
| printf("no thorvg\n"); | |
| return 0; | |
| } | |
| // canvas - software | |
| canvas = tvg_swcanvas_create(TVG_ENGINE_OPTION_DEFAULT); | |
| // animation for Lottie file | |
| Tvg_Animation animation = tvg_animation_new(); | |
| if (!animation) | |
| { | |
| printf("can not create animation\n"); | |
| return 0; | |
| } | |
| // load Lottie file | |
| Tvg_Paint pict = tvg_animation_get_picture(animation); | |
| res = tvg_picture_load(pict, argv[1]); | |
| if (res != TVG_RESULT_SUCCESS) | |
| { | |
| tvg_animation_del(animation); | |
| printf("no lottie file\n"); | |
| return 0; | |
| } | |
| // get Lottie file size | |
| float width, height; | |
| tvg_picture_get_size(pict, &width, &height); | |
| // set half size | |
| w = width / 2; | |
| h = height / 2; | |
| tvg_picture_set_size(pict, w, h); | |
| //tvg_paint_scale(pict, 0.75f); | |
| // add picture to the canvas | |
| tvg_canvas_add(canvas, pict); | |
| //////// EFL | |
| ecore_evas_init(); | |
| ee = ecore_evas_new(NULL, 0, 0, 1, 1, NULL); | |
| if (!ee) | |
| { | |
| printf("no ee\n"); | |
| return 0; | |
| } | |
| evas = ecore_evas_get(ee); | |
| ecore_evas_title_set(ee, "thorVG Lottie"); | |
| ecore_evas_callback_delete_request_set(ee, _quit); | |
| o = evas_object_rectangle_add(evas); | |
| evas_object_move(o, 0, 0); | |
| evas_object_resize(o, w, h); | |
| evas_object_color_set(o, 255, 0, 0, 255); | |
| evas_object_show(o); | |
| o = evas_object_image_filled_add(evas); | |
| evas_object_image_alpha_set(o, EINA_TRUE); | |
| evas_object_image_size_set(o, w, h); | |
| pixels = evas_object_image_data_get(o, EINA_TRUE); | |
| //evas_object_image_pixels_dirty_set(o, EINA_TRUE); | |
| evas_object_move(o, 0, 0); | |
| evas_object_resize(o, w, h); | |
| evas_object_show(o); | |
| // set pixels to write to in tvg canvas | |
| tvg_swcanvas_set_target(canvas, (uint32_t*)pixels, w, w, h, TVG_COLORSPACE_ARGB8888S); | |
| float duration, total; | |
| tvg_animation_get_duration(animation, &duration); | |
| tvg_animation_get_total_frame(animation, &total); | |
| Data data; | |
| data.total = total; | |
| data.duration = duration; | |
| data.canvas = canvas; | |
| data.current = 0; | |
| data.pixels = pixels; | |
| data.animation = animation; | |
| data.o = o; | |
| timer = ecore_timer_add(duration / total, _anim_cb, &data); | |
| evas_object_image_data_set(o, pixels); | |
| evas_object_image_data_update_add(o, 0, 0, w, h); | |
| ecore_evas_resize(ee, w, h); | |
| ecore_evas_show(ee); | |
| ecore_main_loop_begin(); | |
| tvg_animation_del(animation); | |
| tvg_canvas_destroy(canvas); | |
| tvg_engine_term(); | |
| ecore_evas_shutdown(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
int main(int argc, char *argv[])
{
...
data.begin_time = ecore_time_get(); //capture the begin time
...
}
_anim_cb()
{
...
float current_time = (float) ecore_time_get();
d->progress = (current_time - data.begin_time) / data.duration ; //get the animation progress
if (progresss > 1) progress -= 1.0f; //repeat
tvg_animation_set_frame(d->animation, d->progress ;
...
}