LVGL 库提交

This commit is contained in:
2026-08-30 08:57:07 +08:00
parent 26c9098630
commit e2f199c6bf
1056 changed files with 556743 additions and 45 deletions
+238
View File
@@ -0,0 +1,238 @@
/**
* @file lv_lottie.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_lottie_private.h"
#include "../../lv_conf_internal.h"
#if LV_USE_LOTTIE
#if LV_USE_THORVG_EXTERNAL
#include <thorvg_capi.h>
#else
#include "../../libs/thorvg/thorvg_capi.h"
#endif
#include "../../misc/lv_timer.h"
#include "../../core/lv_obj_class_private.h"
#include "../../misc/cache/lv_cache.h"
/*********************
* DEFINES
*********************/
#define MY_CLASS (&lv_lottie_class)
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_lottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_lottie_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void anim_exec_cb(void * var, int32_t v);
static void lottie_update(lv_lottie_t * lottie, int32_t v);
/**********************
* STATIC VARIABLES
**********************/
const lv_obj_class_t lv_lottie_class = {
.constructor_cb = lv_lottie_constructor,
.destructor_cb = lv_lottie_destructor,
.width_def = LV_DPI_DEF,
.height_def = LV_DPI_DEF,
.instance_size = sizeof(lv_lottie_t),
.base_class = &lv_canvas_class,
.name = "lv_lottie",
};
/**********************
* GLOBAL VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_obj_t * lv_lottie_create(lv_obj_t * parent)
{
LV_LOG_INFO("begin");
lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
lv_obj_class_init_obj(obj);
return obj;
}
void lv_lottie_set_buffer(lv_obj_t * obj, int32_t w, int32_t h, void * buf)
{
lv_lottie_t * lottie = (lv_lottie_t *)obj;
int32_t stride = lv_draw_buf_width_to_stride(w, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED);
buf = lv_draw_buf_align(buf, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED);
tvg_swcanvas_set_target(lottie->tvg_canvas, buf, stride / 4, w, h, TVG_COLORSPACE_ARGB8888);
tvg_canvas_push(lottie->tvg_canvas, lottie->tvg_paint);
lv_canvas_set_buffer(obj, buf, w, h, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED);
tvg_picture_set_size(lottie->tvg_paint, w, h);
/* Rendered output images are premultiplied */
lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj);
lv_draw_buf_set_flag(draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED);
/*Force updating when the buffer changes*/
float f_current;
tvg_animation_get_frame(lottie->tvg_anim, &f_current);
anim_exec_cb(obj, (int32_t) f_current);
}
void lv_lottie_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf)
{
if(draw_buf->header.cf != LV_COLOR_FORMAT_ARGB8888 && draw_buf->header.cf != LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) {
LV_LOG_WARN("The draw buf needs to have ARGB8888 or ARGB8888_PREMULTIPLIED color format");
return;
}
lv_lottie_t * lottie = (lv_lottie_t *)obj;
tvg_swcanvas_set_target(lottie->tvg_canvas, (void *)draw_buf->data, draw_buf->header.stride / 4,
draw_buf->header.w, draw_buf->header.h, TVG_COLORSPACE_ARGB8888);
tvg_canvas_push(lottie->tvg_canvas, lottie->tvg_paint);
lv_canvas_set_draw_buf(obj, draw_buf);
tvg_picture_set_size(lottie->tvg_paint, draw_buf->header.w, draw_buf->header.h);
/* Rendered output images are premultiplied */
lv_draw_buf_set_flag(draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED);
/*Force updating when the buffer changes*/
float f_current;
tvg_animation_get_frame(lottie->tvg_anim, &f_current);
anim_exec_cb(obj, (int32_t) f_current);
}
void lv_lottie_set_src_data(lv_obj_t * obj, const void * src, size_t src_size)
{
lv_lottie_t * lottie = (lv_lottie_t *)obj;
tvg_picture_load_data(lottie->tvg_paint, src, src_size, "lottie", true);
lv_draw_buf_t * canvas_draw_buf = lv_canvas_get_draw_buf(obj);
if(canvas_draw_buf) {
tvg_picture_set_size(lottie->tvg_paint, canvas_draw_buf->header.w, canvas_draw_buf->header.h);
}
float f_total;
tvg_animation_get_total_frame(lottie->tvg_anim, &f_total);
lv_anim_set_duration(lottie->anim, (int32_t)f_total * 1000 / 60); /*60 FPS*/
lottie->anim->act_time = 0;
lottie->anim->end_value = (int32_t)f_total;
lottie->anim->reverse_play_in_progress = false;
lottie_update(lottie, 0); /*Render immediately*/
}
void lv_lottie_set_src_file(lv_obj_t * obj, const char * src)
{
lv_lottie_t * lottie = (lv_lottie_t *)obj;
tvg_picture_load(lottie->tvg_paint, src);
lv_draw_buf_t * canvas_draw_buf = lv_canvas_get_draw_buf(obj);
if(canvas_draw_buf) {
tvg_picture_set_size(lottie->tvg_paint, canvas_draw_buf->header.w, canvas_draw_buf->header.h);
}
float f_total;
tvg_animation_get_total_frame(lottie->tvg_anim, &f_total);
lv_anim_set_duration(lottie->anim, (int32_t)f_total * 1000 / 60); /*60 FPS*/
lottie->anim->act_time = 0;
lottie->anim->end_value = (int32_t)f_total;
lottie->anim->reverse_play_in_progress = false;
lottie_update(lottie, 0); /*Render immediately*/
}
lv_anim_t * lv_lottie_get_anim(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_lottie_t * lottie = (lv_lottie_t *)obj;
return lottie->anim;
}
/**********************
* STATIC FUNCTIONS
**********************/
static void lv_lottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
LV_UNUSED(class_p);
LV_TRACE_OBJ_CREATE("begin");
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_lottie_t * lottie = (lv_lottie_t *)obj;
lottie->tvg_anim = tvg_animation_new();
lottie->tvg_paint = tvg_animation_get_picture(lottie->tvg_anim);
lottie->tvg_canvas = tvg_swcanvas_create();
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, anim_exec_cb);
lv_anim_set_var(&a, obj);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lottie->anim = lv_anim_start(&a);
LV_TRACE_OBJ_CREATE("finished");
}
static void lv_lottie_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
LV_UNUSED(class_p);
lv_lottie_t * lottie = (lv_lottie_t *)obj;
tvg_animation_del(lottie->tvg_anim);
tvg_canvas_destroy(lottie->tvg_canvas);
}
static void anim_exec_cb(void * var, int32_t v)
{
lv_lottie_t * lottie = var;
/*Do not render not visible animations.*/
if(lv_obj_is_visible(var)) {
lottie_update(lottie, v);
if(lottie->anim) {
lottie->last_rendered_time = lottie->anim->act_time;
}
}
else {
/*Artificially keep the animation on the last rendered frame's time
*To avoid a jump when the widget becomes visible*/
if(lottie->anim) {
lottie->anim->act_time = lottie->last_rendered_time;
}
}
}
static void lottie_update(lv_lottie_t * lottie, int32_t v)
{
lv_obj_t * obj = (lv_obj_t *) lottie;
lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj);
if(draw_buf) {
lv_draw_buf_clear(draw_buf, NULL);
/*Drop old cached image*/
lv_image_cache_drop(lv_image_get_src(obj));
}
tvg_animation_set_frame(lottie->tvg_anim, v);
tvg_canvas_update(lottie->tvg_canvas);
tvg_canvas_draw(lottie->tvg_canvas);
tvg_canvas_sync(lottie->tvg_canvas);
lv_obj_invalidate(obj);
}
#endif /*LV_USE_LOTTIE*/
+102
View File
@@ -0,0 +1,102 @@
/**
* @file lv_lottie.h
*
*/
#ifndef LV_LOTTIE_H
#define LV_LOTTIE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#if LV_USE_LOTTIE
/*Testing of dependencies*/
#if LV_USE_CANVAS == 0
#error "lv_lottie: lv_canvas is required. Enable it in lv_conf.h (LV_USE_CANVAS 1)"
#endif
#if LV_USE_THORVG == 0
#error "lv_lottie: ThorVG is required. Enable it in lv_conf.h (LV_USE_THORVG_INTERNAL/EXTERNAL 1)"
#endif
#include "../../draw/lv_draw_buf.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a lottie animation
* @param parent pointer to the parent widget
* @return pointer to the created Lottie animation widget
*/
lv_obj_t * lv_lottie_create(lv_obj_t * parent);
/**
* Set a buffer for the animation. It also defines the size of the animation
* @param obj pointer to a lottie widget
* @param w width of the animation and buffer
* @param h height of the animation and buffer
* @param buf a static buffer with `width x height x 4` byte size
*/
void lv_lottie_set_buffer(lv_obj_t * obj, int32_t w, int32_t h, void * buf);
/**
* Set a draw buffer for the animation. It also defines the size of the animation
* @param obj pointer to a lottie widget
* @param draw_buf an initialized draw buffer with ARGB8888 color format
*/
void lv_lottie_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf);
/**
* Set the source for the animation as an array
* @param obj pointer to a lottie widget
* @param src the lottie animation converted to an nul terminated array
* @param src_size size of the source array in bytes
*/
void lv_lottie_set_src_data(lv_obj_t * obj, const void * src, size_t src_size);
/**
* Set the source for the animation as a path.
* Lottie doesn't use LVGL's File System API.
* @param obj pointer to a lottie widget
* @param src path to a json file, e.g. "path/to/file.json"
*/
void lv_lottie_set_src_file(lv_obj_t * obj, const char * src);
/**
* Get the LVGL animation which controls the lottie animation
* @param obj pointer to a lottie widget
* @return the LVGL animation
*/
lv_anim_t * lv_lottie_get_anim(lv_obj_t * obj);
/**********************
* GLOBAL VARIABLES
**********************/
/**********************
* MACROS
**********************/
#endif /*LV_USE_LOTTIE*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_LOTTIE_H*/
@@ -0,0 +1,60 @@
/**
* @file lv_lottie_private.h
*
*/
#ifndef LV_LOTTIE_PRIVATE_H
#define LV_LOTTIE_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_LOTTIE
#include "lv_lottie.h"
#include "../canvas/lv_canvas_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
#if LV_USE_THORVG_EXTERNAL
#include <thorvg_capi.h>
#else
#include "../../libs/thorvg/thorvg_capi.h"
#endif
typedef struct {
lv_canvas_t canvas;
Tvg_Paint * tvg_paint;
Tvg_Canvas * tvg_canvas;
Tvg_Animation * tvg_anim;
lv_anim_t * anim;
int32_t last_rendered_time;
} lv_lottie_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#endif /*LV_LOTTIE_H*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_LOTTIE_PRIVATE_H*/