feat(canvas): use draw buffer for canvas
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
committed by
Gabor Kiss-Vamosi
parent
8e7fb71bdb
commit
3ff5f97651
@@ -32,6 +32,37 @@ typedef struct {
|
||||
void * _unaligned; /*Unaligned address of data*/
|
||||
} lv_draw_buf_t;
|
||||
|
||||
/**
|
||||
* Stride alignment for draw buffers.
|
||||
* It may vary between different color formats and hardware.
|
||||
* Refine it to suit your needs.
|
||||
*/
|
||||
|
||||
#define _LV_DRAW_BUF_STRIDE(w, cf) \
|
||||
(((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7) / 8 + (LV_DRAW_BUF_STRIDE_ALIGN) - 1)
|
||||
|
||||
#define _LV_DRAW_BUF_SIZE(w, h, cf) \
|
||||
(_LV_DRAW_BUF_STRIDE(w, cf) * (h))
|
||||
|
||||
/**
|
||||
* Define a static draw buffer with the given width, height, and color format.
|
||||
* Stride alignment is set to LV_DRAW_BUF_STRIDE_ALIGN.
|
||||
*/
|
||||
#define LV_DRAW_BUF_DEFINE(name, _w, _h, _cf) \
|
||||
static uint8_t buf_##name[_LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \
|
||||
static lv_draw_buf_t name = { \
|
||||
.header = { \
|
||||
.w = (_w), \
|
||||
.h = (_h), \
|
||||
.cf = (_cf), \
|
||||
.flags = LV_IMAGE_FLAGS_MODIFIABLE, \
|
||||
.stride = _LV_DRAW_BUF_STRIDE(_w, _cf), \
|
||||
}, \
|
||||
.data_size = sizeof(buf_##name), \
|
||||
.data = buf_##name, \
|
||||
._unaligned = buf_##name, \
|
||||
}
|
||||
|
||||
typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format);
|
||||
|
||||
typedef void (*lv_draw_buf_free_cb)(void * draw_buf);
|
||||
|
||||
@@ -49,26 +49,26 @@ typedef enum _lv_image_flags_t {
|
||||
* For RGB map of the image data, mark if it's pre-multiplied with alpha.
|
||||
* For indexed image, this bit indicated palette data is pre-multiplied with alpha.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_PREMULTIPLIED = 0x01,
|
||||
LV_IMAGE_FLAGS_PREMULTIPLIED = (1 << 0),
|
||||
|
||||
/**
|
||||
* If the image data is malloced and can be processed in place.
|
||||
* In image decoder post processing, this flag means we modify it in-place.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_MODIFIABLE = 0x02,
|
||||
LV_IMAGE_FLAGS_MODIFIABLE = (1 << 1),
|
||||
|
||||
/**
|
||||
* Indicating it's a vector image instead of default raster image.
|
||||
* Some of the flags are not usable for vector image, like PREMULTIPLIED.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_VECTORS = 0x04,
|
||||
LV_IMAGE_FLAGS_VECTORS = (1 << 2),
|
||||
|
||||
/**
|
||||
* The image data is compressed, so decoder needs to decode image firstly.
|
||||
* If this flag is set, the whole image will be decompressed upon decode, and
|
||||
* `get_area_cb` won't be necessary.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_COMPRESSED = 0x08,
|
||||
LV_IMAGE_FLAGS_COMPRESSED = (1 << 3),
|
||||
|
||||
/**
|
||||
* Flags reserved for user, lvgl won't use these bits.
|
||||
|
||||
@@ -64,6 +64,24 @@ typedef uint8_t lv_opa_t;
|
||||
#define LV_OPA_MIN 2 /*Opacities below this will be transparent*/
|
||||
#define LV_OPA_MAX 253 /*Opacities above this will fully cover*/
|
||||
|
||||
#define LV_COLOR_FORMAT_GET_BPP(cf) ( \
|
||||
(cf) == LV_COLOR_FORMAT_I1 ? 1 : \
|
||||
(cf) == LV_COLOR_FORMAT_A1 ? 1 : \
|
||||
(cf) == LV_COLOR_FORMAT_I2 ? 2 : \
|
||||
(cf) == LV_COLOR_FORMAT_A2 ? 2 : \
|
||||
(cf) == LV_COLOR_FORMAT_I4 ? 4 : \
|
||||
(cf) == LV_COLOR_FORMAT_A4 ? 4 : \
|
||||
(cf) == LV_COLOR_FORMAT_L8 ? 8 : \
|
||||
(cf) == LV_COLOR_FORMAT_A8 ? 8 : \
|
||||
(cf) == LV_COLOR_FORMAT_I8 ? 8 : \
|
||||
(cf) == LV_COLOR_FORMAT_RGB565 ? 16 : \
|
||||
(cf) == LV_COLOR_FORMAT_RGB565A8 ? 24 : \
|
||||
(cf) == LV_COLOR_FORMAT_RGB888 ? 24 : \
|
||||
(cf) == LV_COLOR_FORMAT_ARGB8888 ? 32 : \
|
||||
(cf) == LV_COLOR_FORMAT_XRGB8888 ? 32 : \
|
||||
0 \
|
||||
)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
@@ -69,19 +69,40 @@ void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, int32_t w, int32_t h, lv_c
|
||||
LV_ASSERT_NULL(buf);
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
lv_memzero(&canvas->static_buf, sizeof(canvas->static_buf));
|
||||
lv_image_header_init(&canvas->static_buf.header, w, h, cf, stride, 0);
|
||||
canvas->static_buf.data_size = stride * h;
|
||||
canvas->static_buf.data = lv_draw_buf_align(buf, cf);
|
||||
canvas->static_buf._unaligned = buf;
|
||||
canvas->draw_buf = &canvas->static_buf;
|
||||
|
||||
canvas->buf_unaligned = buf;
|
||||
canvas->dsc.header.cf = cf;
|
||||
canvas->dsc.header.w = w;
|
||||
canvas->dsc.header.h = h;
|
||||
canvas->dsc.header.stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
canvas->dsc.data = lv_draw_buf_align(buf, cf);
|
||||
canvas->dsc.data_size = w * h * lv_color_format_get_size(cf);
|
||||
const void * src = lv_image_get_src(obj);
|
||||
if(src) {
|
||||
lv_cache_lock();
|
||||
lv_cache_invalidate_by_src(src, LV_CACHE_SRC_TYPE_POINTER);
|
||||
lv_cache_unlock();
|
||||
}
|
||||
|
||||
lv_image_set_src(obj, &canvas->dsc);
|
||||
lv_cache_lock();
|
||||
lv_cache_invalidate_by_src(&canvas->dsc, LV_CACHE_SRC_TYPE_POINTER);
|
||||
lv_cache_unlock();
|
||||
lv_image_set_src(obj, canvas->draw_buf);
|
||||
}
|
||||
|
||||
void lv_canvas_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
canvas->draw_buf = draw_buf;
|
||||
|
||||
const void * src = lv_image_get_src(obj);
|
||||
if(src) {
|
||||
lv_cache_lock();
|
||||
lv_cache_invalidate_by_src(src, LV_CACHE_SRC_TYPE_POINTER);
|
||||
lv_cache_unlock();
|
||||
}
|
||||
|
||||
lv_image_set_src(obj, draw_buf);
|
||||
}
|
||||
|
||||
void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv_opa_t opa)
|
||||
@@ -89,15 +110,15 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
uint32_t stride = canvas->dsc.header.stride;
|
||||
lv_color_format_t cf = canvas->dsc.header.cf;
|
||||
uint32_t pixel_byte = (lv_color_format_get_bpp(cf) + 7) >> 3;
|
||||
uint8_t * data = (uint8_t *)canvas->dsc.data;
|
||||
data += stride * y + x * pixel_byte; /*draw buf goto x,y */
|
||||
lv_draw_buf_t * draw_buf = canvas->draw_buf;
|
||||
|
||||
lv_color_format_t cf = draw_buf->header.cf;
|
||||
uint32_t stride = draw_buf->header.stride;
|
||||
uint8_t * data = lv_draw_buf_goto_xy(draw_buf, x, y);
|
||||
|
||||
if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
||||
/*Indexed image bpp could be less than 8, calculate again*/
|
||||
uint8_t * buf = (uint8_t *)canvas->dsc.data;
|
||||
uint8_t * buf = (uint8_t *)canvas->draw_buf->data;
|
||||
buf += 8;
|
||||
buf += y * stride;
|
||||
buf += x >> 3;
|
||||
@@ -143,7 +164,10 @@ void lv_canvas_set_palette(lv_obj_t * obj, uint8_t id, lv_color32_t c)
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
|
||||
lv_image_buf_set_palette(&canvas->dsc, id, c);
|
||||
lv_image_dsc_t dsc;
|
||||
lv_draw_buf_to_image(canvas->draw_buf, &dsc);
|
||||
|
||||
lv_image_buf_set_palette(&dsc, id, c);
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
@@ -151,27 +175,34 @@ void lv_canvas_set_palette(lv_obj_t * obj, uint8_t id, lv_color32_t c)
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
lv_color32_t lv_canvas_get_px(lv_obj_t * obj, int32_t x, int32_t y)
|
||||
lv_draw_buf_t * lv_canvas_get_draw_buf(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
uint8_t px_size = lv_color_format_get_size(canvas->dsc.header.cf);
|
||||
const uint8_t * px = canvas->dsc.data + canvas->dsc.header.w * y * px_size + x * px_size;
|
||||
lv_color32_t ret;
|
||||
return canvas->draw_buf;
|
||||
}
|
||||
|
||||
switch(canvas->dsc.header.cf) {
|
||||
lv_color32_t lv_canvas_get_px(lv_obj_t * obj, int32_t x, int32_t y)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_color32_t ret = { 0 };
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
if(canvas->draw_buf == NULL) return ret;
|
||||
|
||||
lv_image_header_t * header = &canvas->draw_buf->header;
|
||||
const uint8_t * px = lv_draw_buf_goto_xy(canvas->draw_buf, x, y);
|
||||
|
||||
switch(header->cf) {
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
ret.red = px[0];
|
||||
ret.green = px[1];
|
||||
ret.blue = px[2];
|
||||
ret.alpha = px[3];
|
||||
ret = *(lv_color32_t *)px;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
ret.red = px[0];
|
||||
ret.red = px[2];
|
||||
ret.green = px[1];
|
||||
ret.blue = px[2];
|
||||
ret.blue = px[0];
|
||||
ret.alpha = 0xFF;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565: {
|
||||
@@ -203,7 +234,7 @@ lv_image_dsc_t * lv_canvas_get_image(lv_obj_t * obj)
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
return &canvas->dsc;
|
||||
return (lv_image_dsc_t *)canvas->draw_buf;
|
||||
}
|
||||
|
||||
const void * lv_canvas_get_buf(lv_obj_t * obj)
|
||||
@@ -211,8 +242,10 @@ const void * lv_canvas_get_buf(lv_obj_t * obj)
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
return canvas->buf_unaligned;
|
||||
if(canvas->draw_buf)
|
||||
return canvas->draw_buf->_unaligned;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@@ -225,60 +258,72 @@ void lv_canvas_copy_buf(lv_obj_t * obj, const void * to_copy, int32_t x, int32_t
|
||||
LV_ASSERT_NULL(to_copy);
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
if(canvas->draw_buf == NULL) return;
|
||||
|
||||
if(x + w - 1 >= (int32_t)canvas->dsc.header.w || y + h - 1 >= (int32_t)canvas->dsc.header.h) {
|
||||
lv_image_header_t * header = &canvas->draw_buf->header;
|
||||
if(x + w - 1 >= (int32_t)header->w || y + h - 1 >= (int32_t)header->h) {
|
||||
LV_LOG_WARN("x or y out of the canvas");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t px_size = lv_color_format_get_size(canvas->dsc.header.cf) >> 3;
|
||||
uint32_t px = canvas->dsc.header.w * y * px_size + x * px_size;
|
||||
uint8_t * to_copy8 = (uint8_t *)to_copy;
|
||||
int32_t i;
|
||||
for(i = 0; i < h; i++) {
|
||||
lv_memcpy((void *)&canvas->dsc.data[px], to_copy8, w * px_size);
|
||||
px += canvas->dsc.header.w * px_size;
|
||||
to_copy8 += w * px_size;
|
||||
}
|
||||
lv_area_t src_area_to_copy;
|
||||
lv_area_set(&src_area_to_copy, 0, 0, w - 1, h - 1);
|
||||
|
||||
lv_area_t dest_area_to_copy;
|
||||
lv_area_set(&dest_area_to_copy, x, y, x + w - 1, y + h - 1);
|
||||
|
||||
lv_draw_buf_copy(
|
||||
canvas->draw_buf->data,
|
||||
header->w,
|
||||
header->h,
|
||||
&dest_area_to_copy,
|
||||
(void *)to_copy,
|
||||
w,
|
||||
h,
|
||||
&src_area_to_copy,
|
||||
header->cf);
|
||||
}
|
||||
|
||||
void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_dsc_t * dsc = lv_canvas_get_image(obj);
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
lv_draw_buf_t * draw_buf = canvas->draw_buf;
|
||||
if(draw_buf == NULL) return;
|
||||
|
||||
lv_image_header_t * header = &draw_buf->header;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(dsc->header.w, dsc->header.cf);
|
||||
|
||||
if(dsc->header.cf == LV_COLOR_FORMAT_RGB565) {
|
||||
uint32_t stride = header->stride;
|
||||
uint8_t * data = draw_buf->data;
|
||||
if(header->cf == LV_COLOR_FORMAT_RGB565) {
|
||||
uint16_t c16 = lv_color_to_u16(color);
|
||||
for(y = 0; y < dsc->header.h; y++) {
|
||||
uint16_t * buf16 = (uint16_t *)(dsc->data + y * stride);
|
||||
for(x = 0; x < dsc->header.w; x++) {
|
||||
for(y = 0; y < header->h; y++) {
|
||||
uint16_t * buf16 = (uint16_t *)(data + y * stride);
|
||||
for(x = 0; x < header->w; x++) {
|
||||
buf16[x] = c16;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(dsc->header.cf == LV_COLOR_FORMAT_XRGB8888 || dsc->header.cf == LV_COLOR_FORMAT_ARGB8888) {
|
||||
else if(header->cf == LV_COLOR_FORMAT_XRGB8888 || header->cf == LV_COLOR_FORMAT_ARGB8888) {
|
||||
uint32_t c32 = lv_color_to_u32(color);
|
||||
if(dsc->header.cf == LV_COLOR_FORMAT_ARGB8888) {
|
||||
if(header->cf == LV_COLOR_FORMAT_ARGB8888) {
|
||||
c32 &= 0x00ffffff;
|
||||
c32 |= opa << 24;
|
||||
}
|
||||
for(y = 0; y < dsc->header.h; y++) {
|
||||
uint32_t * buf32 = (uint32_t *)(dsc->data + y * stride);
|
||||
for(x = 0; x < dsc->header.w; x++) {
|
||||
for(y = 0; y < header->h; y++) {
|
||||
uint32_t * buf32 = (uint32_t *)(data + y * stride);
|
||||
for(x = 0; x < header->w; x++) {
|
||||
buf32[x] = c32;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(dsc->header.cf == LV_COLOR_FORMAT_RGB888) {
|
||||
for(y = 0; y < dsc->header.h; y++) {
|
||||
uint8_t * buf8 = (uint8_t *)(dsc->data + y * stride);
|
||||
for(x = 0; x < dsc->header.w * 3; x += 3) {
|
||||
else if(header->cf == LV_COLOR_FORMAT_RGB888) {
|
||||
for(y = 0; y < header->h; y++) {
|
||||
uint8_t * buf8 = (uint8_t *)(data + y * stride);
|
||||
for(x = 0; x < header->w * 3; x += 3) {
|
||||
buf8[x + 0] = color.blue;
|
||||
buf8[x + 1] = color.green;
|
||||
buf8[x + 2] = color.red;
|
||||
@@ -286,8 +331,8 @@ void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa)
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(y = 0; y < dsc->header.h; y++) {
|
||||
for(x = 0; x < dsc->header.w; x++) {
|
||||
for(y = 0; y < header->h; y++) {
|
||||
for(x = 0; x < header->w; x++) {
|
||||
lv_canvas_set_px(obj, x, y, color, opa);
|
||||
}
|
||||
}
|
||||
@@ -296,17 +341,19 @@ void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa)
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
void lv_canvas_init_layer(lv_obj_t * canvas, lv_layer_t * layer)
|
||||
void lv_canvas_init_layer(lv_obj_t * obj, lv_layer_t * layer)
|
||||
{
|
||||
LV_ASSERT_NULL(canvas);
|
||||
LV_ASSERT_NULL(obj);
|
||||
LV_ASSERT_NULL(layer);
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
if(canvas->draw_buf == NULL) return;
|
||||
|
||||
lv_image_dsc_t * dsc = lv_canvas_get_image(canvas);
|
||||
lv_area_t canvas_area = {0, 0, dsc->header.w - 1, dsc->header.h - 1};
|
||||
lv_image_header_t * header = &canvas->draw_buf->header;
|
||||
lv_area_t canvas_area = {0, 0, header->w - 1, header->h - 1};
|
||||
lv_memzero(layer, sizeof(*layer));
|
||||
|
||||
layer->buf = lv_draw_buf_align((uint8_t *)dsc->data, dsc->header.cf);
|
||||
layer->color_format = dsc->header.cf;
|
||||
layer->buf = canvas->draw_buf->data;
|
||||
layer->color_format = header->cf;
|
||||
layer->buf_area = canvas_area;
|
||||
layer->_clip_area = canvas_area;
|
||||
layer->buf_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), layer->color_format);
|
||||
@@ -327,19 +374,7 @@ void lv_canvas_finish_layer(lv_obj_t * canvas, lv_layer_t * layer)
|
||||
static void lv_canvas_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
{
|
||||
LV_UNUSED(class_p);
|
||||
LV_TRACE_OBJ_CREATE("begin");
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
|
||||
canvas->dsc.header.cf = LV_COLOR_FORMAT_NATIVE;
|
||||
canvas->dsc.header.h = 0;
|
||||
canvas->dsc.header.w = 0;
|
||||
canvas->dsc.data_size = 0;
|
||||
canvas->dsc.data = NULL;
|
||||
|
||||
lv_image_set_src(obj, &canvas->dsc);
|
||||
|
||||
LV_TRACE_OBJ_CREATE("finished");
|
||||
LV_UNUSED(obj);
|
||||
}
|
||||
|
||||
static void lv_canvas_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
@@ -348,9 +383,10 @@ static void lv_canvas_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
LV_TRACE_OBJ_CREATE("begin");
|
||||
|
||||
lv_canvas_t * canvas = (lv_canvas_t *)obj;
|
||||
if(canvas->draw_buf == NULL) return;
|
||||
|
||||
lv_cache_lock();
|
||||
lv_cache_invalidate_by_src(&canvas->dsc, LV_CACHE_SRC_TYPE_POINTER);
|
||||
lv_cache_invalidate_by_src(canvas->draw_buf, LV_CACHE_SRC_TYPE_POINTER);
|
||||
lv_cache_unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_canvas_class;
|
||||
/*Data of canvas*/
|
||||
typedef struct {
|
||||
lv_image_t img;
|
||||
lv_image_dsc_t dsc;
|
||||
const void * buf_unaligned;
|
||||
lv_draw_buf_t * draw_buf;
|
||||
lv_draw_buf_t static_buf;
|
||||
} lv_canvas_t;
|
||||
|
||||
/**********************
|
||||
@@ -63,7 +63,9 @@ lv_obj_t * lv_canvas_create(lv_obj_t * parent);
|
||||
* @param h height of the canvas
|
||||
* @param cf color format. `LV_COLOR_FORMAT...`
|
||||
*/
|
||||
void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, int32_t w, int32_t h, lv_color_format_t cf);
|
||||
void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, int32_t w, int32_t h, lv_color_format_t cf);
|
||||
|
||||
void lv_canvas_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf);
|
||||
|
||||
/**
|
||||
* Set a pixel's color and opacity
|
||||
@@ -95,6 +97,8 @@ void lv_canvas_set_palette(lv_obj_t * canvas, uint8_t id, lv_color32_t c);
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
lv_draw_buf_t * lv_canvas_get_draw_buf(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get a pixel's color and opacity
|
||||
* @param obj pointer to a canvas
|
||||
|
||||
Reference in New Issue
Block a user