mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-26 02:37:01 +08:00
feat(draw): add vg-lite draw unit (#5010)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
@@ -357,6 +357,19 @@ menu "LVGL configuration"
|
||||
config LV_USE_DRAW_PXP
|
||||
bool "Use NXP's PXP on iMX RTxxx platforms."
|
||||
|
||||
config LV_USE_DRAW_VG_LITE
|
||||
bool "Use VG-Lite GPU."
|
||||
|
||||
config LV_VG_LITE_USE_GPU_INIT
|
||||
bool "Enbale VG-Lite custom external 'gpu_init()' function."
|
||||
default n
|
||||
depends on LV_USE_DRAW_VG_LITE
|
||||
|
||||
config LV_VG_LITE_USE_ASSERT
|
||||
bool "Enable VG-Lite assert."
|
||||
default n
|
||||
depends on LV_USE_DRAW_VG_LITE
|
||||
|
||||
config LV_USE_GPU_SDL
|
||||
bool "Use SDL renderer API"
|
||||
default n
|
||||
|
||||
@@ -128,6 +128,17 @@
|
||||
/* Draw using cached SDL textures*/
|
||||
#define LV_USE_DRAW_SDL 0
|
||||
|
||||
/* Use VG-Lite GPU. */
|
||||
#define LV_USE_DRAW_VG_LITE 0
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
/* Enbale VG-Lite custom external 'gpu_init()' function */
|
||||
#define LV_VG_LITE_USE_GPU_INIT 0
|
||||
|
||||
/* Enable VG-Lite assert. */
|
||||
#define LV_VG_LITE_USE_ASSERT 0
|
||||
#endif
|
||||
|
||||
/*=================
|
||||
* OPERATING SYSTEM
|
||||
*=================*/
|
||||
|
||||
@@ -419,6 +419,8 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc,
|
||||
if(g.bpp == LV_IMGFONT_BPP) dsc->format = LV_DRAW_LETTER_BITMAP_FORMAT_IMAGE;
|
||||
else dsc->format = LV_DRAW_LETTER_BITMAP_FORMAT_A8;
|
||||
|
||||
dsc->g = &g;
|
||||
|
||||
cb(draw_unit, dsc, NULL, NULL);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ typedef struct {
|
||||
lv_draw_glyph_bitmap_format_t format;
|
||||
const lv_area_t * letter_coords;
|
||||
const lv_area_t * bg_coords;
|
||||
const lv_font_glyph_dsc_t * g;
|
||||
lv_color_t color;
|
||||
lv_opa_t opa;
|
||||
} lv_draw_glyph_dsc_t;
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* @file lv_draw_buf_vg_lite.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void * buf_malloc(size_t size, lv_color_format_t color_format);
|
||||
static void buf_free(void * buf);
|
||||
static void * buf_align(void * buf, lv_color_format_t color_format);
|
||||
static void invalidate_cache(void * buf, uint32_t stride, lv_color_format_t color_format, const lv_area_t * area);
|
||||
static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format);
|
||||
static void * buf_go_to_xy(const void * buf, uint32_t stride, lv_color_format_t color_format, int32_t x,
|
||||
int32_t y);
|
||||
static void buf_clear(void * buf, uint32_t w, uint32_t h, lv_color_format_t color_format, const lv_area_t * a);
|
||||
static void buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area_to_copy,
|
||||
void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area_to_copy,
|
||||
lv_color_format_t color_format);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_buf_vg_lite_init_handlers(void)
|
||||
{
|
||||
lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
|
||||
|
||||
handlers->buf_malloc_cb = buf_malloc;
|
||||
handlers->buf_free_cb = buf_free;
|
||||
handlers->align_pointer_cb = buf_align;
|
||||
handlers->invalidate_cache_cb = invalidate_cache;
|
||||
handlers->width_to_stride_cb = width_to_stride;
|
||||
handlers->go_to_xy_cb = buf_go_to_xy;
|
||||
handlers->buf_clear_cb = buf_clear;
|
||||
handlers->buf_copy_cb = buf_copy;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void * buf_malloc(size_t size_bytes, lv_color_format_t color_format)
|
||||
{
|
||||
LV_UNUSED(color_format);
|
||||
size_bytes = LV_VG_LITE_ALIGN(size_bytes, LV_VG_LITE_BUF_ALIGN);
|
||||
return aligned_alloc(LV_VG_LITE_BUF_ALIGN, size_bytes);
|
||||
}
|
||||
|
||||
static void buf_free(void * buf)
|
||||
{
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void * buf_align(void * buf, lv_color_format_t color_format)
|
||||
{
|
||||
LV_UNUSED(color_format);
|
||||
return (void *)LV_VG_LITE_ALIGN((lv_uintptr_t)buf, LV_VG_LITE_BUF_ALIGN);
|
||||
}
|
||||
|
||||
static void invalidate_cache(void * buf, uint32_t stride, lv_color_format_t color_format, const lv_area_t * area)
|
||||
{
|
||||
}
|
||||
|
||||
static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format)
|
||||
{
|
||||
return lv_vg_lite_width_to_stride(w, lv_vg_lite_vg_fmt(color_format));
|
||||
}
|
||||
|
||||
static void * buf_go_to_xy(const void * buf, uint32_t stride, lv_color_format_t color_format, int32_t x,
|
||||
int32_t y)
|
||||
{
|
||||
const uint8_t * buf_tmp = buf;
|
||||
buf_tmp += stride * y;
|
||||
buf_tmp += x * lv_color_format_get_size(color_format);
|
||||
|
||||
return (void *)buf_tmp;
|
||||
}
|
||||
|
||||
static void buf_clear(void * buf, uint32_t w, uint32_t h, lv_color_format_t color_format, const lv_area_t * a)
|
||||
{
|
||||
#if 0
|
||||
if(LV_VG_LITE_IS_ALIGNED(buf, LV_VG_LITE_BUF_ALIGN)) {
|
||||
/* finish outstanding buffers */
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
|
||||
|
||||
vg_lite_buffer_t dest_buf;
|
||||
LV_ASSERT(lv_vg_lite_buffer_init(&dest_buf, buf, w, h, lv_vg_lite_vg_fmt(color_format), false));
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&dest_buf);
|
||||
|
||||
vg_lite_rectangle_t rect;
|
||||
lv_vg_lite_rect(&rect, a);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_clear(&dest_buf, &rect, 0));
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t px_size = lv_color_format_get_size(color_format);
|
||||
uint32_t stride = lv_draw_buf_width_to_stride(w, color_format);
|
||||
uint8_t * bufc = buf;
|
||||
|
||||
/*Got the first pixel of each buffer*/
|
||||
bufc += stride * a->y1;
|
||||
bufc += a->x1 * px_size;
|
||||
|
||||
uint32_t line_length = lv_area_get_width(a) * px_size;
|
||||
int32_t y;
|
||||
for(y = a->y1; y <= a->y2; y++) {
|
||||
lv_memzero(bufc, line_length);
|
||||
bufc += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area_to_copy,
|
||||
void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area_to_copy,
|
||||
lv_color_format_t color_format)
|
||||
{
|
||||
#if 0
|
||||
if(LV_VG_LITE_IS_ALIGNED(dest_buf, LV_VG_LITE_BUF_ALIGN)
|
||||
&& LV_VG_LITE_IS_ALIGNED(src_buf, LV_VG_LITE_BUF_ALIGN)) {
|
||||
vg_lite_buffer_t dest;
|
||||
LV_ASSERT(lv_vg_lite_buffer_init(&dest, dest_buf, dest_w, dest_h, lv_vg_lite_vg_fmt(color_format), false));
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&dest);
|
||||
|
||||
vg_lite_buffer_t src;
|
||||
LV_ASSERT(lv_vg_lite_buffer_init(&src, src_buf, src_w, src_h, lv_vg_lite_vg_fmt(color_format), false));
|
||||
LV_VG_LITE_ASSERT_SRC_BUFFER(&src);
|
||||
|
||||
vg_lite_rectangle_t src_rect;
|
||||
lv_vg_lite_rect(&src_rect, src_area_to_copy);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_blit_rect(&dest, &src,
|
||||
&src_rect,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_NONE, 0,
|
||||
VG_LITE_FILTER_POINT));
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t px_size = lv_color_format_get_size(color_format);
|
||||
uint8_t * dest_bufc = dest_buf;
|
||||
uint8_t * src_bufc = src_buf;
|
||||
|
||||
uint32_t dest_stride = lv_draw_buf_width_to_stride(dest_w, color_format);
|
||||
uint32_t src_stride = lv_draw_buf_width_to_stride(src_w, color_format);
|
||||
|
||||
/*Got the first pixel of each buffer*/
|
||||
dest_bufc += dest_stride * dest_area_to_copy->y1;
|
||||
dest_bufc += dest_area_to_copy->x1 * px_size;
|
||||
|
||||
src_bufc += src_stride * src_area_to_copy->y1;
|
||||
src_bufc += src_area_to_copy->x1 * px_size;
|
||||
|
||||
uint32_t line_length = lv_area_get_width(dest_area_to_copy) * px_size;
|
||||
int32_t y;
|
||||
for(y = dest_area_to_copy->y1; y <= dest_area_to_copy->y2; y++) {
|
||||
lv_memcpy(dest_bufc, src_bufc, line_length);
|
||||
dest_bufc += dest_stride;
|
||||
src_bufc += src_stride;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* @file lv_vg_lite_draw.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "../lv_draw.h"
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include "lv_vg_lite_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define VG_LITE_DRAW_UNIT_ID 2
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
|
||||
|
||||
static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
|
||||
|
||||
static int32_t draw_delete(lv_draw_unit_t * draw_unit);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_init(void)
|
||||
{
|
||||
#if LV_VG_LITE_USE_GPU_INIT
|
||||
extern void gpu_init(void);
|
||||
static bool inited = false;
|
||||
if(!inited) {
|
||||
gpu_init();
|
||||
inited = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_vg_lite_dump_info();
|
||||
|
||||
lv_draw_buf_vg_lite_init_handlers();
|
||||
|
||||
lv_draw_vg_lite_unit_t * unit = lv_draw_create_unit(sizeof(lv_draw_vg_lite_unit_t));
|
||||
unit->base_unit.dispatch_cb = draw_dispatch;
|
||||
unit->base_unit.evaluate_cb = draw_evaluate;
|
||||
unit->base_unit.delete_cb = draw_delete;
|
||||
|
||||
lv_vg_lite_path_init(unit);
|
||||
|
||||
lv_vg_lite_decoder_init();
|
||||
}
|
||||
|
||||
void lv_draw_vg_lite_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void draw_execute(lv_draw_vg_lite_unit_t * u)
|
||||
{
|
||||
lv_draw_task_t * t = u->task_act;
|
||||
lv_draw_unit_t * draw_unit = (lv_draw_unit_t *)u;
|
||||
|
||||
lv_layer_t * layer = u->base_unit.target_layer;
|
||||
|
||||
lv_vg_lite_buffer_init(
|
||||
&u->target_buffer,
|
||||
layer->buf,
|
||||
lv_area_get_width(&layer->buf_area),
|
||||
lv_area_get_height(&layer->buf_area),
|
||||
lv_vg_lite_vg_fmt(layer->color_format),
|
||||
false);
|
||||
|
||||
vg_lite_identity(&u->global_matrix);
|
||||
vg_lite_translate(-layer->buf_area.x1, -layer->buf_area.y1, &u->global_matrix);
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_LABEL:
|
||||
lv_draw_vg_lite_label(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
lv_draw_vg_lite_fill(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_BORDER:
|
||||
lv_draw_vg_lite_border(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_BOX_SHADOW:
|
||||
lv_draw_vg_lite_box_shadow(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
lv_draw_vg_lite_img(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_ARC:
|
||||
lv_draw_vg_lite_arc(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LINE:
|
||||
lv_draw_vg_lite_line(draw_unit, t->draw_dsc);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LAYER:
|
||||
lv_draw_vg_lite_layer(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
lv_draw_vg_lite_triangle(draw_unit, t->draw_dsc);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_MASK_RECTANGLE:
|
||||
lv_draw_vg_lite_mask_rect(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
case LV_DRAW_TASK_TYPE_VECTOR:
|
||||
lv_draw_vg_lite_vector(draw_unit, t->draw_dsc);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
/* Layers manage it for themselves. */
|
||||
if(t->type != LV_DRAW_TASK_TYPE_LAYER) {
|
||||
}
|
||||
#endif
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
|
||||
}
|
||||
|
||||
static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
|
||||
{
|
||||
lv_draw_vg_lite_unit_t * draw_vg_lite_unit = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
|
||||
/* Return immediately if it's busy with draw task. */
|
||||
if(draw_vg_lite_unit->task_act) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return if target buffer format is not supported. */
|
||||
if(!lv_vg_lite_is_dest_cf_supported(layer->color_format)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try to get an ready to draw. */
|
||||
lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, VG_LITE_DRAW_UNIT_ID);
|
||||
|
||||
/* Return 0 is no selection, some tasks can be supported by other units. */
|
||||
if(!t || t->preferred_draw_unit_id != VG_LITE_DRAW_UNIT_ID) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void * buf = lv_draw_layer_alloc_buf(layer);
|
||||
if(!buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
|
||||
draw_vg_lite_unit->base_unit.target_layer = layer;
|
||||
draw_vg_lite_unit->base_unit.clip_area = &t->clip_area;
|
||||
draw_vg_lite_unit->task_act = t;
|
||||
|
||||
draw_execute(draw_vg_lite_unit);
|
||||
|
||||
draw_vg_lite_unit->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
draw_vg_lite_unit->task_act = NULL;
|
||||
|
||||
/* The draw unit is free now. Request a new dispatching as it can get a new task. */
|
||||
lv_draw_dispatch_request();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task)
|
||||
{
|
||||
LV_UNUSED(draw_unit);
|
||||
|
||||
switch(task->type) {
|
||||
#if LV_USE_FREETYPE && LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_OUTLINE
|
||||
case LV_DRAW_TASK_TYPE_LABEL: {
|
||||
const lv_draw_label_dsc_t * label_dsc = task->draw_dsc;
|
||||
if(lv_freetype_is_outline_font(label_dsc->font)) {
|
||||
task->preference_score = 0;
|
||||
task->preferred_draw_unit_id = VG_LITE_DRAW_UNIT_ID;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
case LV_DRAW_TASK_TYPE_BORDER:
|
||||
case LV_DRAW_TASK_TYPE_BOX_SHADOW:
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
case LV_DRAW_TASK_TYPE_LAYER:
|
||||
case LV_DRAW_TASK_TYPE_LINE:
|
||||
case LV_DRAW_TASK_TYPE_ARC:
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
// case LV_DRAW_TASK_TYPE_MASK_RECTANGLE:
|
||||
// case LV_DRAW_TASK_TYPE_MASK_BITMAP:
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
case LV_DRAW_TASK_TYPE_VECTOR:
|
||||
#endif
|
||||
task->preference_score = 80;
|
||||
task->preferred_draw_unit_id = VG_LITE_DRAW_UNIT_ID;
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t draw_delete(lv_draw_unit_t * draw_unit)
|
||||
{
|
||||
lv_draw_vg_lite_unit_t * unit = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
lv_vg_lite_path_deinit(unit);
|
||||
lv_vg_lite_decoder_deinit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file lv_vg_lite_draw.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_VG_LITE_DRAW_H
|
||||
#define LV_VG_LITE_DRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "../lv_draw.h"
|
||||
#include "../../draw/lv_draw_vector.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_buf_vg_lite_init_handlers(void);
|
||||
|
||||
void lv_draw_vg_lite_init(void);
|
||||
|
||||
void lv_draw_vg_lite_deinit(void);
|
||||
|
||||
void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vg_lite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc);
|
||||
|
||||
void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VG_LITE_DRAW_H*/
|
||||
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_arc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
#include "lv_vg_lite_math.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include <math.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define TWO_PI 6.283185307179586476925286766559
|
||||
#define DEG_TO_RAD 0.017453292519943295769236907684886
|
||||
#define RAD_TO_DEG 57.295779513082320876798154814105
|
||||
#define radians(deg) ((deg) * DEG_TO_RAD)
|
||||
#define degrees(rad) ((rad) * RAD_TO_DEG)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width <= 0)
|
||||
return;
|
||||
if(dsc->start_angle == dsc->end_angle)
|
||||
return;
|
||||
|
||||
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
|
||||
lv_area_t clip_area;
|
||||
if(!_lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) {
|
||||
/*Fully clipped, nothing to do*/
|
||||
return;
|
||||
}
|
||||
|
||||
float start_angle = dsc->start_angle;
|
||||
float end_angle = dsc->end_angle;
|
||||
float sweep_angle = end_angle - start_angle;
|
||||
|
||||
while(sweep_angle < 0) {
|
||||
sweep_angle += 360;
|
||||
}
|
||||
|
||||
while(sweep_angle > 360) {
|
||||
sweep_angle -= 360;
|
||||
}
|
||||
|
||||
/*If the angles are the same then there is nothing to draw*/
|
||||
if(math_zero(sweep_angle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32);
|
||||
lv_vg_lite_path_set_quality(path, VG_LITE_HIGH);
|
||||
lv_vg_lite_path_set_bonding_box_area(path, &clip_area);
|
||||
|
||||
float radius_out = dsc->radius;
|
||||
float radius_in = dsc->radius - dsc->width;
|
||||
float half_width = dsc->width * 0.5f;
|
||||
float radius_center = radius_out - half_width;
|
||||
float cx = dsc->center.x;
|
||||
float cy = dsc->center.y;
|
||||
|
||||
vg_lite_fill_t fill = VG_LITE_FILL_NON_ZERO;
|
||||
|
||||
if(math_equal(sweep_angle, 360)) {
|
||||
lv_vg_lite_path_append_circle(path, cx, cy, radius_out, radius_out);
|
||||
lv_vg_lite_path_append_circle(path, cx, cy, radius_in, radius_in);
|
||||
fill = VG_LITE_FILL_EVEN_ODD;
|
||||
}
|
||||
else {
|
||||
/* radius_out start point */
|
||||
float start_angle_rad = MATH_RADIANS(start_angle);
|
||||
float start_x = radius_out * MATH_COSF(start_angle_rad) + cx;
|
||||
float start_y = radius_out * MATH_SINF(start_angle_rad) + cy;
|
||||
|
||||
/* radius_in start point */
|
||||
float end_angle_rad = MATH_RADIANS(end_angle);
|
||||
float end_x = radius_in * MATH_COSF(end_angle_rad) + cx;
|
||||
float end_y = radius_in * MATH_SINF(end_angle_rad) + cy;
|
||||
|
||||
/* radius_out arc */
|
||||
lv_vg_lite_path_append_arc(path,
|
||||
cx, cy,
|
||||
radius_out,
|
||||
start_angle,
|
||||
sweep_angle,
|
||||
false);
|
||||
|
||||
/* line to radius_in */
|
||||
lv_vg_lite_path_line_to(path, end_x, end_y);
|
||||
|
||||
/* radius_in arc */
|
||||
lv_vg_lite_path_append_arc(path,
|
||||
cx, cy,
|
||||
radius_in,
|
||||
end_angle,
|
||||
-sweep_angle,
|
||||
false);
|
||||
|
||||
/* close arc */
|
||||
lv_vg_lite_path_line_to(path, start_x, start_y);
|
||||
lv_vg_lite_path_close(path);
|
||||
|
||||
/* draw round */
|
||||
if(dsc->rounded && half_width > 0) {
|
||||
float rcx1 = cx + radius_center * MATH_COSF(end_angle_rad);
|
||||
float rcy1 = cy + radius_center * MATH_SINF(end_angle_rad);
|
||||
lv_vg_lite_path_append_circle(path, rcx1, rcy1, half_width, half_width);
|
||||
|
||||
float rcx2 = cx + radius_center * MATH_COSF(start_angle_rad);
|
||||
float rcy2 = cy + radius_center * MATH_SINF(start_angle_rad);
|
||||
lv_vg_lite_path_append_circle(path, rcx2, rcy2, half_width, half_width);
|
||||
}
|
||||
}
|
||||
|
||||
lv_vg_lite_path_end(path);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
|
||||
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
|
||||
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
fill,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
color));
|
||||
|
||||
if(dsc->img_src) {
|
||||
vg_lite_buffer_t src_buf;
|
||||
lv_image_decoder_dsc_t decoder_dsc;
|
||||
if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src)) {
|
||||
vg_lite_matrix_t path_matrix;
|
||||
vg_lite_identity(&path_matrix);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
fill,
|
||||
&path_matrix,
|
||||
&src_buf,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
VG_LITE_PATTERN_COLOR,
|
||||
0,
|
||||
color,
|
||||
VG_LITE_FILTER_BI_LINEAR));
|
||||
lv_image_decoder_close(&decoder_dsc);
|
||||
}
|
||||
}
|
||||
|
||||
lv_vg_lite_path_drop(u, path);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_border.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(dsc->side == LV_BORDER_SIDE_NONE)
|
||||
return;
|
||||
|
||||
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
|
||||
lv_area_t clip_area;
|
||||
if(!_lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) {
|
||||
/*Fully clipped, nothing to do*/
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t w = lv_area_get_width(coords);
|
||||
int32_t h = lv_area_get_height(coords);
|
||||
int32_t r_out = dsc->radius;
|
||||
if(r_out) {
|
||||
int32_t r_short = LV_MIN(w, h) / 2;
|
||||
r_out = LV_MIN(r_out, r_short);
|
||||
}
|
||||
|
||||
int32_t border_w = dsc->width;
|
||||
int32_t r_in = LV_MAX(0, r_out - border_w);
|
||||
|
||||
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_S16);
|
||||
lv_vg_lite_path_set_quality(path, dsc->radius == 0 ? VG_LITE_LOW : VG_LITE_HIGH);
|
||||
lv_vg_lite_path_set_bonding_box_area(path, &clip_area);
|
||||
|
||||
/* outer rect */
|
||||
lv_vg_lite_path_append_rect(path,
|
||||
coords->x1, coords->y1,
|
||||
w, h,
|
||||
r_out, r_out);
|
||||
|
||||
/* inner rect */
|
||||
lv_vg_lite_path_append_rect(path,
|
||||
coords->x1 + border_w, coords->y1 + border_w,
|
||||
w - border_w * 2, h - border_w * 2,
|
||||
r_in, r_in);
|
||||
|
||||
lv_vg_lite_path_end(path);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
|
||||
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
|
||||
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
color));
|
||||
|
||||
lv_vg_lite_path_drop(u, path);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_box_shadow.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
/*Calculate the rectangle which is blurred to get the shadow in `shadow_area`*/
|
||||
lv_area_t core_area;
|
||||
core_area.x1 = coords->x1 + dsc->ofs_x - dsc->spread;
|
||||
core_area.x2 = coords->x2 + dsc->ofs_x + dsc->spread;
|
||||
core_area.y1 = coords->y1 + dsc->ofs_y - dsc->spread;
|
||||
core_area.y2 = coords->y2 + dsc->ofs_y + dsc->spread;
|
||||
|
||||
/*Calculate the bounding box of the shadow*/
|
||||
lv_area_t shadow_area;
|
||||
shadow_area.x1 = core_area.x1 - dsc->width / 2 - 1;
|
||||
shadow_area.x2 = core_area.x2 + dsc->width / 2 + 1;
|
||||
shadow_area.y1 = core_area.y1 - dsc->width / 2 - 1;
|
||||
shadow_area.y2 = core_area.y2 + dsc->width / 2 + 1;
|
||||
|
||||
lv_opa_t opa = dsc->opa;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
/*Get clipped draw area which is the real draw area.
|
||||
*It is always the same or inside `shadow_area`*/
|
||||
lv_area_t draw_area;
|
||||
if(!_lv_area_intersect(&draw_area, &shadow_area, draw_unit->clip_area)) return;
|
||||
|
||||
lv_draw_border_dsc_t border_dsc;
|
||||
lv_draw_border_dsc_init(&border_dsc);
|
||||
border_dsc.width = 3;
|
||||
border_dsc.color = dsc->color;
|
||||
border_dsc.radius = dsc->radius;
|
||||
|
||||
lv_area_move(&draw_area, dsc->ofs_x, dsc->ofs_y);
|
||||
draw_area = core_area;
|
||||
int32_t half_w = dsc->width / 2;
|
||||
|
||||
for(int32_t w = 0; w < half_w; w++) {
|
||||
border_dsc.opa = lv_map(w, 0, half_w, dsc->opa / 4, LV_OPA_0);
|
||||
border_dsc.radius++;
|
||||
lv_area_increase(&draw_area, 1, 1);
|
||||
lv_draw_vg_lite_border(draw_unit, &border_dsc, &draw_area);
|
||||
|
||||
/* fill center */
|
||||
if(dsc->ofs_x || dsc->ofs_y) {
|
||||
lv_draw_fill_dsc_t fill_dsc;
|
||||
lv_draw_fill_dsc_init(&fill_dsc);
|
||||
fill_dsc.radius = dsc->radius;
|
||||
fill_dsc.opa = dsc->opa;
|
||||
fill_dsc.color = dsc->color;
|
||||
lv_draw_vg_lite_fill(draw_unit, &fill_dsc, &core_area);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_fill.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_GRADIENT_MAX_STOPS > VLC_MAX_GRADIENT_STOPS
|
||||
#error "LV_GRADIENT_MAX_STOPS must be equal or less than VLC_MAX_GRADIENT_STOPS"
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
|
||||
lv_area_t clip_area;
|
||||
if(!_lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) {
|
||||
/*Fully clipped, nothing to do*/
|
||||
return;
|
||||
}
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
|
||||
int32_t w = lv_area_get_width(coords);
|
||||
int32_t h = lv_area_get_height(coords);
|
||||
int32_t r = dsc->radius;
|
||||
if(r) {
|
||||
int32_t r_short = LV_MIN(w, h) / 2;
|
||||
r = LV_MIN(r, r_short);
|
||||
}
|
||||
|
||||
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_S16);
|
||||
lv_vg_lite_path_set_quality(path, dsc->radius == 0 ? VG_LITE_LOW : VG_LITE_HIGH);
|
||||
lv_vg_lite_path_set_bonding_box_area(path, &clip_area);
|
||||
lv_vg_lite_path_append_rect(path, coords->x1, coords->y1, w, h, r, r);
|
||||
lv_vg_lite_path_end(path);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
|
||||
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
|
||||
if(dsc->grad.dir != LV_GRAD_DIR_NONE) {
|
||||
lv_vg_lite_draw_linear_grad(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
coords,
|
||||
&dsc->grad,
|
||||
&matrix,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
VG_LITE_BLEND_SRC_OVER);
|
||||
}
|
||||
else { /* normal fill */
|
||||
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
color));
|
||||
}
|
||||
|
||||
lv_vg_lite_path_drop(u, path);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_img.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
#include "lv_vg_lite_decoder.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
|
||||
/* The coordinates passed in by coords are not transformed,
|
||||
* so the transformed area needs to be calculated once.
|
||||
*/
|
||||
lv_area_t image_tf_area;
|
||||
_lv_image_buf_get_transformed_area(
|
||||
&image_tf_area,
|
||||
lv_area_get_width(coords),
|
||||
lv_area_get_height(coords),
|
||||
dsc->rotation,
|
||||
dsc->scale_x,
|
||||
dsc->scale_y,
|
||||
&dsc->pivot);
|
||||
lv_area_move(&image_tf_area, coords->x1, coords->y1);
|
||||
|
||||
lv_area_t clip_area;
|
||||
if(!_lv_area_intersect(&clip_area, &image_tf_area, draw_unit->clip_area)) {
|
||||
/*Fully clipped, nothing to do*/
|
||||
return;
|
||||
}
|
||||
|
||||
vg_lite_buffer_t src_buf;
|
||||
lv_image_decoder_dsc_t decoder_dsc;
|
||||
if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* image opa */
|
||||
lv_opa_t opa = dsc->opa;
|
||||
vg_lite_color_t color = 0;
|
||||
if(opa < LV_OPA_MAX) {
|
||||
lv_memset(&color, opa, sizeof(color));
|
||||
src_buf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
||||
}
|
||||
|
||||
bool has_recolor = dsc->recolor_opa >= LV_OPA_MIN;
|
||||
bool has_trasform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
|
||||
vg_lite_filter_t filter = has_trasform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT;
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
lv_vg_lite_image_matrix(&matrix, coords->x1, coords->y1, dsc);
|
||||
|
||||
LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf);
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
|
||||
/* If clipping is not required, blit directly */
|
||||
if(_lv_area_is_in(&image_tf_area, draw_unit->clip_area, false) && !has_recolor) {
|
||||
/* The image area is the coordinates relative to the image itself */
|
||||
lv_area_t src_area = *coords;
|
||||
lv_area_move(&src_area, -coords->x1, -coords->y1);
|
||||
|
||||
/* rect is used to crop the pixel-aligned padding area */
|
||||
vg_lite_rectangle_t rect;
|
||||
lv_vg_lite_rect(&rect, &src_area);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_blit_rect(
|
||||
&u->target_buffer,
|
||||
&src_buf,
|
||||
&rect,
|
||||
&matrix,
|
||||
lv_vg_lite_blend_mode(dsc->blend_mode),
|
||||
color,
|
||||
filter));
|
||||
}
|
||||
else {
|
||||
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_S16);
|
||||
lv_vg_lite_path_append_rect(
|
||||
path,
|
||||
clip_area.x1, clip_area.y1,
|
||||
lv_area_get_width(&clip_area), lv_area_get_height(&clip_area),
|
||||
0, 0);
|
||||
lv_vg_lite_path_set_bonding_box_area(path, &clip_area);
|
||||
lv_vg_lite_path_end(path);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
|
||||
vg_lite_matrix_t path_matrix;
|
||||
vg_lite_identity(&path_matrix);
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
&path_matrix,
|
||||
&src_buf,
|
||||
&matrix,
|
||||
lv_vg_lite_blend_mode(dsc->blend_mode),
|
||||
VG_LITE_PATTERN_COLOR,
|
||||
lv_vg_lite_color(dsc->recolor, dsc->recolor_opa, true),
|
||||
color,
|
||||
filter));
|
||||
|
||||
lv_vg_lite_path_drop(u, path);
|
||||
}
|
||||
|
||||
lv_image_decoder_close(&decoder_dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,313 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_label.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#include "../../libs/freetype/lv_freetype.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define PATH_QUALITY VG_LITE_MEDIUM
|
||||
#define PATH_DATA_COORD_FORMAT VG_LITE_S16
|
||||
#define PATH_REF_SIZE 128
|
||||
#define FT_F26DOT6_SHIFT 6
|
||||
|
||||
/** After converting the font reference size, it is also necessary to scale the 26dot6 data
|
||||
* in the path to the real physical size
|
||||
*/
|
||||
#define FT_F26DOT6_TO_PATH_SCALE(x) (LV_FREETYPE_F26DOT6_TO_FLOAT(x) / (1 << FT_F26DOT6_SHIFT))
|
||||
|
||||
#define SUPPORT_OUTLINE_FONT (LV_USE_FREETYPE && LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_OUTLINE)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
|
||||
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area);
|
||||
|
||||
static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc);
|
||||
|
||||
#if SUPPORT_OUTLINE_FONT
|
||||
static void freetype_outline_event_cb(lv_event_t * e);
|
||||
static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
#if SUPPORT_OUTLINE_FONT
|
||||
static bool is_init = false;
|
||||
if(!is_init) {
|
||||
lv_freetype_outline_set_ref_size(PATH_REF_SIZE);
|
||||
lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, draw_unit);
|
||||
is_init = true;
|
||||
}
|
||||
#endif /*SUPPORT_OUTLINE_FONT*/
|
||||
|
||||
lv_draw_label_iterate_letters(draw_unit, dsc, coords, draw_letter_cb);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
|
||||
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area)
|
||||
{
|
||||
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
if(glyph_draw_dsc) {
|
||||
if(glyph_draw_dsc->bitmap == NULL) {
|
||||
#if LV_USE_FONT_PLACEHOLDER
|
||||
/* Draw a placeholder rectangle*/
|
||||
lv_draw_border_dsc_t border_draw_dsc;
|
||||
lv_draw_border_dsc_init(&border_draw_dsc);
|
||||
border_draw_dsc.opa = glyph_draw_dsc->opa;
|
||||
border_draw_dsc.color = glyph_draw_dsc->color;
|
||||
border_draw_dsc.width = 1;
|
||||
lv_draw_vg_lite_border(draw_unit, &border_draw_dsc, glyph_draw_dsc->bg_coords);
|
||||
#endif
|
||||
}
|
||||
else if(glyph_draw_dsc->format == LV_DRAW_LETTER_BITMAP_FORMAT_A8
|
||||
|| glyph_draw_dsc->format == LV_DRAW_LETTER_BITMAP_FORMAT_IMAGE) {
|
||||
#if SUPPORT_OUTLINE_FONT
|
||||
if(lv_freetype_is_outline_font(glyph_draw_dsc->g->resolved_font)) {
|
||||
draw_letter_outline(u, glyph_draw_dsc);
|
||||
}
|
||||
else
|
||||
#endif /*SUPPORT_OUTLINE_FONT*/
|
||||
{
|
||||
draw_letter_bitmap(u, glyph_draw_dsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(fill_draw_dsc && fill_area) {
|
||||
lv_draw_vg_lite_fill(draw_unit, fill_draw_dsc, fill_area);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc)
|
||||
{
|
||||
lv_area_t clip_area;
|
||||
if(!_lv_area_intersect(&clip_area, u->base_unit.clip_area, dsc->letter_coords)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t image_area = *dsc->letter_coords;
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
vg_lite_translate(image_area.x1, image_area.y1, &matrix);
|
||||
|
||||
vg_lite_buffer_t src_buf;
|
||||
lv_vg_lite_buffer_init(
|
||||
&src_buf,
|
||||
dsc->bitmap,
|
||||
lv_area_get_width(&image_area),
|
||||
lv_area_get_height(&image_area),
|
||||
VG_LITE_A8,
|
||||
false);
|
||||
|
||||
vg_lite_color_t color;
|
||||
color = lv_vg_lite_color(dsc->color, dsc->opa, true);
|
||||
|
||||
LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf);
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
|
||||
/* If clipping is not required, blit directly */
|
||||
if(_lv_area_is_in(&image_area, u->base_unit.clip_area, false)) {
|
||||
/* The image area is the coordinates relative to the image itself */
|
||||
lv_area_t src_area = image_area;
|
||||
lv_area_move(&src_area, -image_area.x1, -image_area.y1);
|
||||
|
||||
/* rect is used to crop the pixel-aligned padding area */
|
||||
vg_lite_rectangle_t rect;
|
||||
lv_vg_lite_rect(&rect, &src_area);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_blit_rect(
|
||||
&u->target_buffer,
|
||||
&src_buf,
|
||||
&rect,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
color,
|
||||
VG_LITE_FILTER_LINEAR));
|
||||
}
|
||||
else {
|
||||
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_S16);
|
||||
lv_vg_lite_path_append_rect(
|
||||
path,
|
||||
clip_area.x1, clip_area.y1,
|
||||
lv_area_get_width(&clip_area), lv_area_get_height(&clip_area),
|
||||
0, 0);
|
||||
lv_vg_lite_path_set_bonding_box_area(path, &clip_area);
|
||||
lv_vg_lite_path_end(path);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
|
||||
vg_lite_matrix_t path_matrix;
|
||||
vg_lite_identity(&path_matrix);
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
&path_matrix,
|
||||
&src_buf,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
VG_LITE_PATTERN_COLOR,
|
||||
color,
|
||||
color,
|
||||
VG_LITE_FILTER_LINEAR));
|
||||
|
||||
lv_vg_lite_path_drop(u, path);
|
||||
}
|
||||
}
|
||||
|
||||
#if SUPPORT_OUTLINE_FONT
|
||||
|
||||
static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc)
|
||||
{
|
||||
/* get clip area */
|
||||
lv_area_t path_clip_area;
|
||||
if(!_lv_area_intersect(&path_clip_area, u->base_unit.clip_area, dsc->letter_coords)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* vg-lite bounding_box will crop the pixels on the edge, so +1px is needed here */
|
||||
path_clip_area.x2++;
|
||||
path_clip_area.y2++;
|
||||
|
||||
lv_vg_lite_path_t * outline = (lv_vg_lite_path_t *)dsc->bitmap;
|
||||
lv_point_t pos = {dsc->letter_coords->x1, dsc->letter_coords->y1};
|
||||
|
||||
/* calc convert matrix */
|
||||
float scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(dsc->g->resolved_font));
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
|
||||
/* convert to vg-lite coordinate */
|
||||
vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &matrix);
|
||||
|
||||
/* scale size */
|
||||
vg_lite_scale(scale, scale, &matrix);
|
||||
|
||||
/* Cartesian coordinates to LCD coordinates */
|
||||
lv_vg_lite_matrix_flip_y(&matrix);
|
||||
|
||||
/* calc inverse matrix */
|
||||
vg_lite_matrix_t result;
|
||||
if(!lv_vg_lite_matrix_inverse(&result, &matrix)) {
|
||||
LV_LOG_ERROR("no inverse matrix");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_point_precise_t p1 = { path_clip_area.x1, path_clip_area.y1 };
|
||||
lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1);
|
||||
|
||||
lv_point_precise_t p2 = { path_clip_area.x2, path_clip_area.y2 };
|
||||
lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2);
|
||||
|
||||
/* Since the font uses Cartesian coordinates, the y coordinates need to be reversed */
|
||||
lv_vg_lite_path_set_bonding_box(outline, p1_res.x, p2_res.y, p2_res.x, p1_res.y);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(outline);
|
||||
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
|
||||
&u->target_buffer, vg_lite_path, VG_LITE_FILL_NON_ZERO,
|
||||
&matrix, VG_LITE_BLEND_SRC_OVER, lv_vg_lite_color(dsc->color, dsc->opa, true)));
|
||||
}
|
||||
|
||||
static void vg_lite_outline_push(const lv_freetype_outline_event_param_t * param)
|
||||
{
|
||||
lv_vg_lite_path_t * outline = param->outline;
|
||||
LV_ASSERT_NULL(outline);
|
||||
|
||||
lv_freetype_outline_type_t type = param->type;
|
||||
switch(type) {
|
||||
case LV_FREETYPE_OUTLINE_END:
|
||||
lv_vg_lite_path_end(outline);
|
||||
break;
|
||||
case LV_FREETYPE_OUTLINE_MOVE_TO:
|
||||
lv_vg_lite_path_move_to(outline, param->to.x, param->to.y);
|
||||
break;
|
||||
case LV_FREETYPE_OUTLINE_LINE_TO:
|
||||
lv_vg_lite_path_line_to(outline, param->to.x, param->to.y);
|
||||
break;
|
||||
case LV_FREETYPE_OUTLINE_CUBIC_TO:
|
||||
lv_vg_lite_path_cubic_to(outline, param->control1.x, param->control1.y,
|
||||
param->control2.x, param->control2.y,
|
||||
param->to.x, param->to.y);
|
||||
break;
|
||||
case LV_FREETYPE_OUTLINE_CONIC_TO:
|
||||
lv_vg_lite_path_quad_to(outline, param->control1.x, param->control1.y,
|
||||
param->to.x, param->to.y);
|
||||
break;
|
||||
default:
|
||||
LV_LOG_ERROR("unknown point type: %d", type);
|
||||
LV_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void freetype_outline_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_freetype_outline_event_param_t * param = lv_event_get_param(e);
|
||||
switch(code) {
|
||||
case LV_EVENT_CREATE:
|
||||
param->outline = lv_vg_lite_path_create(PATH_DATA_COORD_FORMAT);
|
||||
break;
|
||||
case LV_EVENT_DELETE:
|
||||
lv_vg_lite_path_destroy(param->outline);
|
||||
break;
|
||||
case LV_EVENT_INSERT:
|
||||
vg_lite_outline_push(param);
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("unknown event code: %d", code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*SUPPORT_OUTLINE_FONT*/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_layer.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
lv_layer_t * layer = (lv_layer_t *)draw_dsc->src;
|
||||
|
||||
/*It can happen that nothing was draw on a layer and therefore its buffer is not allocated.
|
||||
*In this case just return. */
|
||||
if(layer->buf == NULL)
|
||||
return;
|
||||
|
||||
lv_image_dsc_t img_dsc;
|
||||
lv_memzero(&img_dsc, sizeof(lv_image_dsc_t));
|
||||
img_dsc.header.w = lv_area_get_width(&layer->buf_area);
|
||||
img_dsc.header.h = lv_area_get_height(&layer->buf_area);
|
||||
img_dsc.header.cf = layer->color_format;
|
||||
img_dsc.header.always_zero = 0;
|
||||
img_dsc.data = layer->buf;
|
||||
|
||||
lv_draw_image_dsc_t new_draw_dsc = *draw_dsc;
|
||||
new_draw_dsc.src = &img_dsc;
|
||||
|
||||
lv_draw_vg_lite_img(draw_unit, &new_draw_dsc, coords);
|
||||
lv_cache_lock();
|
||||
lv_cache_invalidate_by_src(&img_dsc, LV_CACHE_SRC_TYPE_POINTER);
|
||||
lv_cache_unlock();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_line.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
#include "lv_vg_lite_math.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define SQ(x) ((x) * (x))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
|
||||
float p1_x = dsc->p1.x;
|
||||
float p1_y = dsc->p1.y;
|
||||
float p2_x = dsc->p2.x;
|
||||
float p2_y = dsc->p2.y;
|
||||
|
||||
if(p1_x == p2_x && p1_y == p2_y)
|
||||
return;
|
||||
|
||||
float half_w = dsc->width * 0.5f;
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
rel_clip_area.x1 = LV_MIN(p1_x, p2_x) - half_w;
|
||||
rel_clip_area.x2 = LV_MAX(p1_x, p2_x) + half_w;
|
||||
rel_clip_area.y1 = LV_MIN(p1_y, p2_y) - half_w;
|
||||
rel_clip_area.y2 = LV_MAX(p1_y, p2_y) + half_w;
|
||||
|
||||
if(!_lv_area_intersect(&rel_clip_area, &rel_clip_area, draw_unit->clip_area)) {
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
}
|
||||
|
||||
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
|
||||
int32_t dash_width = dsc->dash_width;
|
||||
int32_t dash_gap = dsc->dash_gap;
|
||||
int32_t dash_l = dash_width + dash_gap;
|
||||
|
||||
float dx = p2_x - p1_x;
|
||||
float dy = p2_y - p1_y;
|
||||
float inv_dl = math_fast_inv_sqrtf(SQ(dx) + SQ(dy));
|
||||
float w_dx = dsc->width * dy * inv_dl;
|
||||
float w_dy = dsc->width * dx * inv_dl;
|
||||
float w2_dx = w_dx / 2;
|
||||
float w2_dy = w_dy / 2;
|
||||
|
||||
int32_t ndash = 0;
|
||||
if(dash_width && dash_l * inv_dl < 1.0f) {
|
||||
ndash = (1.0f / inv_dl + dash_l - 1) / dash_l;
|
||||
}
|
||||
|
||||
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32);
|
||||
lv_vg_lite_path_set_quality(path, VG_LITE_MEDIUM);
|
||||
lv_vg_lite_path_set_bonding_box_area(path, &rel_clip_area);
|
||||
|
||||
/* head point */
|
||||
float head_start_x = p1_x + w2_dx;
|
||||
float head_start_y = p1_y - w2_dy;
|
||||
float head_end_x = p1_x - w2_dx;
|
||||
float head_end_y = p1_y + w2_dy;
|
||||
|
||||
/* tali point */
|
||||
float tali_start_x = p2_x - w2_dx;
|
||||
float tali_start_y = p2_y + w2_dy;
|
||||
float tali_end_x = p2_x + w2_dx;
|
||||
float tali_end_y = p2_y - w2_dy;
|
||||
|
||||
/*
|
||||
head_start tali_end
|
||||
*-----------------*
|
||||
/| |\
|
||||
/ | | \
|
||||
arc_c *( *p1 p2* )* arc_c
|
||||
\ | | /
|
||||
\| |/
|
||||
*-----------------*
|
||||
head_end tali_start
|
||||
*/
|
||||
|
||||
/* move to start point */
|
||||
lv_vg_lite_path_move_to(path, head_start_x, head_start_y);
|
||||
|
||||
/* draw line head */
|
||||
if(dsc->round_start) {
|
||||
float arc_cx = p1_x - w2_dy;
|
||||
float arc_cy = p1_y - w2_dx;
|
||||
|
||||
/* start 90deg arc */
|
||||
lv_vg_lite_path_append_arc_right_angle(path,
|
||||
head_start_x, head_start_y,
|
||||
p1_x, p1_y,
|
||||
arc_cx, arc_cy);
|
||||
|
||||
/* end 90deg arc */
|
||||
lv_vg_lite_path_append_arc_right_angle(path,
|
||||
arc_cx, arc_cy,
|
||||
p1_x, p1_y,
|
||||
head_end_x, head_end_y);
|
||||
}
|
||||
else {
|
||||
lv_vg_lite_path_line_to(path, head_end_x, head_end_y);
|
||||
}
|
||||
|
||||
/* draw line body */
|
||||
lv_vg_lite_path_line_to(path, tali_start_x, tali_start_y);
|
||||
|
||||
/* draw line tail */
|
||||
if(dsc->round_end) {
|
||||
float arc_cx = p2_x + w2_dy;
|
||||
float arc_cy = p2_y + w2_dx;
|
||||
lv_vg_lite_path_append_arc_right_angle(path,
|
||||
tali_start_x, tali_start_y,
|
||||
p2_x, p2_y,
|
||||
arc_cx, arc_cy);
|
||||
lv_vg_lite_path_append_arc_right_angle(path,
|
||||
arc_cx, arc_cy,
|
||||
p2_x, p2_y,
|
||||
tali_end_x, tali_end_y);
|
||||
}
|
||||
else {
|
||||
lv_vg_lite_path_line_to(path, tali_end_x, tali_end_y);
|
||||
}
|
||||
|
||||
/* close draw line body */
|
||||
lv_vg_lite_path_line_to(path, head_start_x, head_start_y);
|
||||
|
||||
for(int32_t i = 0; i < ndash; i++) {
|
||||
float start_x = p1_x - w2_dx + dx * (i * dash_l + dash_width) * inv_dl;
|
||||
float start_y = p1_y + w2_dy + dy * (i * dash_l + dash_width) * inv_dl;
|
||||
|
||||
lv_vg_lite_path_move_to(path, start_x, start_y);
|
||||
lv_vg_lite_path_line_to(path,
|
||||
p1_x + w2_dx + dx * (i * dash_l + dash_width) * inv_dl,
|
||||
p1_y - w2_dy + dy * (i * dash_l + dash_width) * inv_dl);
|
||||
lv_vg_lite_path_line_to(path,
|
||||
p1_x + w2_dx + dx * (i + 1) * dash_l * inv_dl,
|
||||
p1_y - w2_dy + dy * (i + 1) * dash_l * inv_dl);
|
||||
lv_vg_lite_path_line_to(path,
|
||||
p1_x - w2_dx + dx * (i + 1) * dash_l * inv_dl,
|
||||
p1_y + w2_dy + dy * (i + 1) * dash_l * inv_dl);
|
||||
lv_vg_lite_path_line_to(path, start_x, start_y);
|
||||
}
|
||||
|
||||
lv_vg_lite_path_end(path);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
|
||||
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
|
||||
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
color));
|
||||
|
||||
lv_vg_lite_path_drop(u, path);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_rect.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
LV_UNUSED(coords);
|
||||
|
||||
lv_area_t draw_area;
|
||||
if(!_lv_area_intersect(&draw_area, &dsc->area, draw_unit->clip_area)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_sw_mask_radius_param_t param;
|
||||
lv_draw_sw_mask_radius_init(¶m, &dsc->area, dsc->radius, false);
|
||||
|
||||
void * masks[2] = {0};
|
||||
masks[0] = ¶m;
|
||||
|
||||
uint32_t area_w = lv_area_get_width(&draw_area);
|
||||
lv_opa_t * mask_buf = lv_malloc(area_w);
|
||||
|
||||
int32_t y;
|
||||
for(y = draw_area.y1; y <= draw_area.y2; y++) {
|
||||
lv_memset(mask_buf, 0xff, area_w);
|
||||
lv_draw_sw_mask_res_t res = lv_draw_sw_mask_apply(masks, mask_buf, draw_area.x1, y, area_w);
|
||||
if(res == LV_DRAW_SW_MASK_RES_FULL_COVER) continue;
|
||||
|
||||
lv_layer_t * target_layer = draw_unit->target_layer;
|
||||
lv_color32_t * c32_buf = lv_draw_layer_go_to_xy(target_layer, draw_area.x1 - target_layer->buf_area.x1,
|
||||
y - target_layer->buf_area.y1);
|
||||
|
||||
if(res == LV_DRAW_SW_MASK_RES_TRANSP) {
|
||||
uint32_t i;
|
||||
for(i = 0; i < area_w; i++) {
|
||||
c32_buf[i].alpha = 0x00;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint32_t i;
|
||||
for(i = 0; i < area_w; i++) {
|
||||
if(mask_buf[i] != LV_OPA_COVER) {
|
||||
c32_buf[i].alpha = LV_OPA_MIX2(c32_buf[i].alpha, mask_buf[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lv_free(mask_buf);
|
||||
lv_draw_sw_mask_free_param(¶m);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_triangle.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->bg_opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_area_t tri_area;
|
||||
tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
tri_area.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
tri_area.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
tri_area.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
|
||||
bool is_common;
|
||||
lv_area_t clip_area;
|
||||
is_common = _lv_area_intersect(&clip_area, &tri_area, draw_unit->clip_area);
|
||||
if(!is_common) return;
|
||||
|
||||
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
||||
|
||||
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32);
|
||||
lv_vg_lite_path_set_bonding_box_area(path, &clip_area);
|
||||
lv_vg_lite_path_move_to(path, dsc->p[0].x, dsc->p[0].y);
|
||||
lv_vg_lite_path_line_to(path, dsc->p[1].x, dsc->p[1].y);
|
||||
lv_vg_lite_path_line_to(path, dsc->p[2].x, dsc->p[2].y);
|
||||
lv_vg_lite_path_close(path);
|
||||
lv_vg_lite_path_end(path);
|
||||
|
||||
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
|
||||
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
|
||||
|
||||
if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {
|
||||
lv_vg_lite_draw_linear_grad(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
&tri_area,
|
||||
&dsc->bg_grad,
|
||||
&matrix,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
VG_LITE_BLEND_SRC_OVER);
|
||||
}
|
||||
else { /* normal fill */
|
||||
vg_lite_color_t color = lv_vg_lite_color(dsc->bg_color, dsc->bg_opa, true);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
&matrix,
|
||||
VG_LITE_BLEND_SRC_OVER,
|
||||
color));
|
||||
}
|
||||
|
||||
lv_vg_lite_path_drop(u, path);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_type.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_VG_LITE_TYPE_H
|
||||
#define LV_DRAW_VG_LITE_TYPE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include "../lv_draw.h"
|
||||
#include <vg_lite.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct _lv_draw_vg_lite_unit_t {
|
||||
lv_draw_unit_t base_unit;
|
||||
struct _lv_draw_task_t * task_act;
|
||||
vg_lite_buffer_t target_buffer;
|
||||
vg_lite_matrix_t global_matrix;
|
||||
lv_ll_t path_free_ll;
|
||||
int path_max_cnt;
|
||||
} lv_draw_vg_lite_unit_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VG_LITE_DRAW_H*/
|
||||
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
* @file lv_draw_vg_lite_vector.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vg_lite.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC
|
||||
|
||||
#include "lv_draw_vg_lite_type.h"
|
||||
#include "lv_vg_lite_path.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc);
|
||||
static void lv_matrix_to_vg(vg_lite_matrix_t * desy, const lv_matrix_t * src);
|
||||
static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src);
|
||||
static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend);
|
||||
static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule);
|
||||
static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->task_list == NULL)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = dsc->base.layer;
|
||||
if(layer->buf == NULL)
|
||||
return;
|
||||
|
||||
_lv_vector_for_each_destroy_tasks(dsc->task_list, task_draw_cb, draw_unit);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static vg_lite_color_t lv_color32_to_vg(lv_color32_t color, lv_opa_t opa)
|
||||
{
|
||||
uint8_t a = LV_OPA_MIX2(color.alpha, opa);
|
||||
if(a < LV_OPA_MAX) {
|
||||
color.red = LV_UDIV255(color.red * opa);
|
||||
color.green = LV_UDIV255(color.green * opa);
|
||||
color.blue = LV_UDIV255(color.blue * opa);
|
||||
}
|
||||
return (uint32_t)a << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red;
|
||||
}
|
||||
|
||||
static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc)
|
||||
{
|
||||
lv_draw_vg_lite_unit_t * u = ctx;
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
|
||||
|
||||
/* clear area */
|
||||
if(!path) {
|
||||
/* clear color needs to ignore fill_dsc.opa */
|
||||
vg_lite_color_t c = lv_color32_to_vg(dsc->fill_dsc.color, LV_OPA_COVER);
|
||||
vg_lite_rectangle_t rect;
|
||||
lv_vg_lite_rect(&rect, &dsc->scissor_area);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_clear(&u->target_buffer, &rect, c));
|
||||
return;
|
||||
}
|
||||
|
||||
/* set scissor area */
|
||||
lv_vg_lite_set_scissor_area(&dsc->scissor_area);
|
||||
|
||||
/* convert color */
|
||||
vg_lite_color_t vg_color = lv_color32_to_vg(dsc->fill_dsc.color, dsc->fill_dsc.opa);
|
||||
|
||||
/* transform matrix */
|
||||
vg_lite_matrix_t matrix;
|
||||
lv_matrix_to_vg(&matrix, &dsc->matrix);
|
||||
|
||||
/* convert path */
|
||||
lv_vg_lite_path_t * lv_vg_path = lv_vg_lite_path_get(u, VG_LITE_FP32);
|
||||
lv_path_to_vg(lv_vg_path, path);
|
||||
vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(lv_vg_path);
|
||||
LV_VG_LITE_ASSERT_PATH(vg_path);
|
||||
|
||||
/* convert blend mode and fill rule */
|
||||
vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode);
|
||||
vg_lite_fill_t fill = lv_fill_to_vg(dsc->fill_dsc.fill_rule);
|
||||
|
||||
/* get path bounds */
|
||||
float min_x, min_y, max_x, max_y;
|
||||
lv_vg_lite_path_get_bonding_box(lv_vg_path, &min_x, &min_y, &max_x, &max_y);
|
||||
|
||||
switch(dsc->fill_dsc.style) {
|
||||
case LV_VECTOR_DRAW_STYLE_SOLID: {
|
||||
/* normal draw shape */
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
|
||||
&u->target_buffer,
|
||||
vg_path,
|
||||
fill,
|
||||
&matrix,
|
||||
blend,
|
||||
vg_color));
|
||||
}
|
||||
break;
|
||||
case LV_VECTOR_DRAW_STYLE_PATTERN: {
|
||||
/* draw image */
|
||||
vg_lite_buffer_t image_buffer;
|
||||
lv_image_decoder_dsc_t decoder_dsc;
|
||||
if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src)) {
|
||||
lv_matrix_t m = dsc->matrix;
|
||||
lv_matrix_translate(&m, min_x, min_y);
|
||||
lv_matrix_multiply(&m, &dsc->fill_dsc.matrix);
|
||||
|
||||
vg_lite_matrix_t src_matrix;
|
||||
lv_matrix_to_vg(&src_matrix, &m);
|
||||
|
||||
vg_lite_matrix_t path_matrix;
|
||||
vg_lite_identity(&path_matrix);
|
||||
|
||||
vg_lite_color_t recolor = lv_vg_lite_color(dsc->fill_dsc.img_dsc.recolor, dsc->fill_dsc.img_dsc.recolor_opa, true);
|
||||
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern(
|
||||
&u->target_buffer,
|
||||
vg_path,
|
||||
fill,
|
||||
&path_matrix,
|
||||
&image_buffer,
|
||||
&src_matrix,
|
||||
blend,
|
||||
VG_LITE_PATTERN_COLOR,
|
||||
recolor,
|
||||
vg_color,
|
||||
VG_LITE_FILTER_BI_LINEAR));
|
||||
lv_image_decoder_close(&decoder_dsc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LV_VECTOR_DRAW_STYLE_GRADIENT: {
|
||||
/* draw gradient */
|
||||
lv_area_t grad_area;
|
||||
lv_area_set(&grad_area, min_x, min_y, max_x, max_y);
|
||||
lv_vector_gradient_style_t style = dsc->fill_dsc.gradient.style;
|
||||
vg_lite_gradient_spreadmode_t spreadmode = lv_spread_to_vg(dsc->fill_dsc.gradient.spread);
|
||||
LV_UNUSED(spreadmode);
|
||||
|
||||
if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) {
|
||||
lv_vg_lite_draw_linear_grad(
|
||||
&u->target_buffer,
|
||||
vg_path,
|
||||
&grad_area,
|
||||
&dsc->fill_dsc.gradient.grad,
|
||||
&matrix,
|
||||
fill,
|
||||
blend);
|
||||
}
|
||||
else if(style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
|
||||
if(vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) {
|
||||
/* TODO: radial gradient */
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("radial gradient is not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("unknown style: %d", dsc->fill_dsc.style);
|
||||
break;
|
||||
}
|
||||
|
||||
/* drop path */
|
||||
lv_vg_lite_path_drop(u, lv_vg_path);
|
||||
|
||||
/* disable scissor */
|
||||
lv_vg_lite_disable_scissor();
|
||||
}
|
||||
|
||||
static void lv_matrix_to_vg(vg_lite_matrix_t * dest, const lv_matrix_t * src)
|
||||
{
|
||||
lv_memcpy(dest, src, sizeof(lv_matrix_t));
|
||||
}
|
||||
|
||||
static vg_lite_quality_t lv_quality_to_vg(lv_vector_path_quality_t quality)
|
||||
{
|
||||
switch(quality) {
|
||||
case LV_VECTOR_PATH_QUALITY_LOW:
|
||||
return VG_LITE_LOW;
|
||||
case LV_VECTOR_PATH_QUALITY_MEDIUM:
|
||||
return VG_LITE_MEDIUM;
|
||||
case LV_VECTOR_PATH_QUALITY_HIGH:
|
||||
return VG_LITE_HIGH;
|
||||
default:
|
||||
return VG_LITE_MEDIUM;
|
||||
}
|
||||
}
|
||||
|
||||
static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src)
|
||||
{
|
||||
lv_vg_lite_path_set_quality(dest, lv_quality_to_vg(src->quality));
|
||||
|
||||
uint32_t pidx = 0;
|
||||
for(uint32_t i = 0; i < src->ops.size; i++) {
|
||||
lv_vector_path_op_t * op = LV_ARRAY_GET(&src->ops, i, uint8_t);
|
||||
switch(*op) {
|
||||
case LV_VECTOR_PATH_OP_MOVE_TO: {
|
||||
lv_fpoint_t * pt = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
|
||||
lv_vg_lite_path_move_to(dest, pt->x, pt->y);
|
||||
pidx += 1;
|
||||
}
|
||||
break;
|
||||
case LV_VECTOR_PATH_OP_LINE_TO: {
|
||||
lv_fpoint_t * pt = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
|
||||
lv_vg_lite_path_line_to(dest, pt->x, pt->y);
|
||||
pidx += 1;
|
||||
}
|
||||
break;
|
||||
case LV_VECTOR_PATH_OP_QUAD_TO: {
|
||||
lv_fpoint_t * pt1 = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
|
||||
lv_fpoint_t * pt2 = LV_ARRAY_GET(&src->points, pidx + 1, lv_fpoint_t);
|
||||
lv_vg_lite_path_quad_to(dest, pt1->x, pt1->y, pt2->x, pt2->y);
|
||||
pidx += 2;
|
||||
}
|
||||
break;
|
||||
case LV_VECTOR_PATH_OP_CUBIC_TO: {
|
||||
lv_fpoint_t * pt1 = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
|
||||
lv_fpoint_t * pt2 = LV_ARRAY_GET(&src->points, pidx + 1, lv_fpoint_t);
|
||||
lv_fpoint_t * pt3 = LV_ARRAY_GET(&src->points, pidx + 2, lv_fpoint_t);
|
||||
lv_vg_lite_path_cubic_to(dest, pt1->x, pt1->y, pt2->x, pt2->y, pt3->x, pt3->y);
|
||||
pidx += 3;
|
||||
}
|
||||
break;
|
||||
case LV_VECTOR_PATH_OP_CLOSE: {
|
||||
lv_vg_lite_path_close(dest);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lv_vg_lite_path_end(dest);
|
||||
lv_vg_lite_path_update_bonding_box(dest);
|
||||
}
|
||||
|
||||
static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend)
|
||||
{
|
||||
switch(blend) {
|
||||
case LV_VECTOR_BLEND_SRC_OVER:
|
||||
return VG_LITE_BLEND_SRC_OVER;
|
||||
case LV_VECTOR_BLEND_SCREEN:
|
||||
return VG_LITE_BLEND_SCREEN;
|
||||
case LV_VECTOR_BLEND_MULTIPLY:
|
||||
return VG_LITE_BLEND_MULTIPLY;
|
||||
case LV_VECTOR_BLEND_NONE:
|
||||
return VG_LITE_BLEND_NONE;
|
||||
case LV_VECTOR_BLEND_ADDITIVE:
|
||||
return VG_LITE_BLEND_ADDITIVE;
|
||||
case LV_VECTOR_BLEND_SRC_IN:
|
||||
return VG_LITE_BLEND_SRC_IN;
|
||||
case LV_VECTOR_BLEND_DST_OVER:
|
||||
return VG_LITE_BLEND_DST_OVER;
|
||||
case LV_VECTOR_BLEND_DST_IN:
|
||||
return VG_LITE_BLEND_DST_IN;
|
||||
case LV_VECTOR_BLEND_SUBTRACTIVE:
|
||||
return VG_LITE_BLEND_SUBTRACT;
|
||||
default:
|
||||
return VG_LITE_BLEND_SRC_OVER;
|
||||
}
|
||||
}
|
||||
|
||||
static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule)
|
||||
{
|
||||
switch(fill_rule) {
|
||||
case LV_VECTOR_FILL_NONZERO:
|
||||
return VG_LITE_FILL_NON_ZERO;
|
||||
case LV_VECTOR_FILL_EVENODD:
|
||||
return VG_LITE_FILL_EVEN_ODD;
|
||||
default:
|
||||
return VG_LITE_FILL_NON_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread)
|
||||
{
|
||||
switch(spread) {
|
||||
case LV_VECTOR_GRADIENT_SPREAD_PAD:
|
||||
return VG_LITE_GRADIENT_SPREAD_PAD;
|
||||
case LV_VECTOR_GRADIENT_SPREAD_REPEAT:
|
||||
return VG_LITE_GRADIENT_SPREAD_REPEAT;
|
||||
case LV_VECTOR_GRADIENT_SPREAD_REFLECT:
|
||||
return VG_LITE_GRADIENT_SPREAD_REFLECT;
|
||||
default:
|
||||
return VG_LITE_GRADIENT_SPREAD_FILL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file lv_vg_lite_decoder.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_VG_LITE_DECODER_H
|
||||
#define LV_VG_LITE_DECODER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lv_image_decoder.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_vg_lite_decoder_init(void);
|
||||
|
||||
void lv_vg_lite_decoder_deinit(void);
|
||||
|
||||
lv_result_t lv_vg_lite_decoder_post_process(lv_image_decoder_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VG_LITE_DECODER_H*/
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file lv_vg_lite_math.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vg_lite_math.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
float math_fast_inv_sqrtf(float number)
|
||||
{
|
||||
int32_t i;
|
||||
float x2, y;
|
||||
const float threehalfs = 1.5f;
|
||||
|
||||
x2 = number * 0.5f;
|
||||
y = number;
|
||||
i = *(int32_t *)&y; /* evil floating point bit level hacking */
|
||||
i = 0x5f3759df - (i >> 1); /* what the fuck? */
|
||||
y = *(float *)&i;
|
||||
y = y * (threehalfs - (x2 * y * y)); /* 1st iteration */
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file lv_vg_lite_math.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_VG_LITE_MATH_H
|
||||
#define LV_VG_LITE_MATH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <float.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define MATH_PI 3.14159265358979323846f
|
||||
#define MATH_HALF_PI 1.57079632679489661923f
|
||||
#define MATH_TWO_PI 6.28318530717958647692f
|
||||
#define DEG_TO_RAD 0.017453292519943295769236907684886
|
||||
#define RAD_TO_DEG 57.295779513082320876798154814105
|
||||
|
||||
#define MATH_TANF(x) tanf(x)
|
||||
#define MATH_SINF(x) sinf(x)
|
||||
#define MATH_COSF(x) cosf(x)
|
||||
#define MATH_ASINF(x) asinf(x)
|
||||
#define MATH_FABSF(x) fabsf(x)
|
||||
#define MATH_SQRTF(x) sqrtf(x)
|
||||
|
||||
#define MATH_RADIANS(deg) ((deg) * DEG_TO_RAD)
|
||||
#define MATD_DEGRESS(rad) ((rad) * RAD_TO_DEG)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static inline bool math_zero(float a)
|
||||
{
|
||||
return (MATH_FABSF(a) < FLT_EPSILON);
|
||||
}
|
||||
|
||||
static inline bool math_equal(float a, float b)
|
||||
{
|
||||
return math_zero(a - b);
|
||||
}
|
||||
|
||||
float math_fast_inv_sqrtf(float number);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VG_LITE_MATH_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @file lv_vg_lite_path.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_VG_LITE_PATH_H
|
||||
#define LV_VG_LITE_PATH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vg_lite_utils.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
typedef struct _lv_vg_lite_path_t lv_vg_lite_path_t;
|
||||
struct _lv_draw_vg_lite_unit_t;
|
||||
|
||||
typedef void (*lv_vg_lite_path_iter_cb_t)(void * user_data, uint8_t op_code, const float * data, uint32_t len);
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_vg_lite_path_init(struct _lv_draw_vg_lite_unit_t * unit);
|
||||
|
||||
void lv_vg_lite_path_deinit(struct _lv_draw_vg_lite_unit_t * unit);
|
||||
|
||||
lv_vg_lite_path_t * lv_vg_lite_path_create(vg_lite_format_t data_format);
|
||||
|
||||
void lv_vg_lite_path_destroy(lv_vg_lite_path_t * path);
|
||||
|
||||
lv_vg_lite_path_t * lv_vg_lite_path_get(struct _lv_draw_vg_lite_unit_t * unit, vg_lite_format_t data_format);
|
||||
|
||||
void lv_vg_lite_path_drop(struct _lv_draw_vg_lite_unit_t * unit, lv_vg_lite_path_t * path);
|
||||
|
||||
void lv_vg_lite_path_reset(lv_vg_lite_path_t * path, vg_lite_format_t data_format);
|
||||
|
||||
void lv_vg_lite_path_set_bonding_box_area(lv_vg_lite_path_t * path, const lv_area_t * area);
|
||||
|
||||
void lv_vg_lite_path_set_bonding_box(lv_vg_lite_path_t * path,
|
||||
float min_x, float min_y,
|
||||
float max_x, float max_y);
|
||||
|
||||
void lv_vg_lite_path_get_bonding_box(lv_vg_lite_path_t * path,
|
||||
float * min_x, float * min_y,
|
||||
float * max_x, float * max_y);
|
||||
|
||||
bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path);
|
||||
|
||||
void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality);
|
||||
|
||||
vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path);
|
||||
|
||||
void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path,
|
||||
float x, float y);
|
||||
|
||||
void lv_vg_lite_path_line_to(lv_vg_lite_path_t * path,
|
||||
float x, float y);
|
||||
|
||||
void lv_vg_lite_path_quad_to(lv_vg_lite_path_t * path,
|
||||
float cx, float cy,
|
||||
float x, float y);
|
||||
|
||||
void lv_vg_lite_path_cubic_to(lv_vg_lite_path_t * path,
|
||||
float cx1, float cy1,
|
||||
float cx2, float cy2,
|
||||
float x, float y);
|
||||
|
||||
void lv_vg_lite_path_close(lv_vg_lite_path_t * path);
|
||||
|
||||
void lv_vg_lite_path_end(lv_vg_lite_path_t * path);
|
||||
|
||||
void lv_vg_lite_path_append_rect(lv_vg_lite_path_t * path,
|
||||
float x, float y,
|
||||
float w, float h,
|
||||
float rx, float ry);
|
||||
|
||||
void lv_vg_lite_path_append_circle(lv_vg_lite_path_t * path,
|
||||
float cx, float cy,
|
||||
float rx, float ry);
|
||||
|
||||
void lv_vg_lite_path_append_arc_right_angle(lv_vg_lite_path_t * path,
|
||||
float start_x, float start_y,
|
||||
float center_x, float center_y,
|
||||
float end_x, float end_y);
|
||||
|
||||
void lv_vg_lite_path_append_arc(lv_vg_lite_path_t * path,
|
||||
float cx, float cy,
|
||||
float radius,
|
||||
float start_angle,
|
||||
float sweep,
|
||||
bool pie);
|
||||
|
||||
uint8_t lv_vg_lite_vlc_op_arg_len(uint8_t vlc_op);
|
||||
|
||||
uint8_t lv_vg_lite_path_format_len(vg_lite_format_t format);
|
||||
|
||||
void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_iter_cb_t cb, void * user_data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VG_LITE_PATH_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* @file lv_vg_lite_utils.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_VG_LITE_UTILS_H
|
||||
#define LV_VG_LITE_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lvgl.h"
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <vg_lite.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_VG_LITE_BUF_ALIGN 64
|
||||
|
||||
#define LV_VG_LITE_IS_ERROR(err) (err > 0)
|
||||
|
||||
#define VLC_GET_OP_CODE(ptr) (*((uint8_t*)ptr))
|
||||
|
||||
#if LV_VG_LITE_USE_ASSERT
|
||||
#define LV_VG_LITE_ASSERT(expr) LV_ASSERT(expr)
|
||||
#else
|
||||
#define LV_VG_LITE_ASSERT(expr)
|
||||
#endif
|
||||
|
||||
#define LV_VG_LITE_CHECK_ERROR(expr) \
|
||||
do { \
|
||||
vg_lite_error_t error = expr; \
|
||||
if (LV_VG_LITE_IS_ERROR(error)) { \
|
||||
LV_LOG_ERROR("Execute '" #expr "' error(%d): %s", \
|
||||
(int)error, lv_vg_lite_error_string(error)); \
|
||||
LV_VG_LITE_ASSERT(false); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LV_VG_LITE_ASSERT_PATH(path) LV_VG_LITE_ASSERT(lv_vg_lite_path_check(path))
|
||||
#define LV_VG_LITE_ASSERT_SRC_BUFFER(buffer) LV_VG_LITE_ASSERT(lv_vg_lite_buffer_check(buffer, true))
|
||||
#define LV_VG_LITE_ASSERT_DEST_BUFFER(buffer) LV_VG_LITE_ASSERT(lv_vg_lite_buffer_check(buffer, false))
|
||||
|
||||
#define LV_VG_LITE_ALIGN(number, align_bytes) \
|
||||
(((number) + ((align_bytes)-1)) & ~((align_bytes)-1))
|
||||
|
||||
#define LV_VG_LITE_IS_ALIGNED(num, align) (((uintptr_t)(num) & ((align)-1)) == 0)
|
||||
|
||||
#define LV_VG_LITE_IS_INDEX_FMT(fmt) \
|
||||
((fmt) == VG_LITE_INDEX_1 \
|
||||
|| (fmt) == VG_LITE_INDEX_2 \
|
||||
|| (fmt) == VG_LITE_INDEX_4 \
|
||||
|| (fmt) == VG_LITE_INDEX_8)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_VG_LITE_IMAGE_FLAG_ALLOCED = 1 << 0,
|
||||
LV_VG_LITE_IMAGE_FLAG_ALIGNED = 1 << 1,
|
||||
LV_VG_LITE_IMAGE_FLAG_PRE_MUL = 1 << 2,
|
||||
} lv_vg_lite_image_flag_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/* Print info */
|
||||
|
||||
void lv_vg_lite_dump_info(void);
|
||||
|
||||
const char * lv_vg_lite_error_string(vg_lite_error_t error);
|
||||
|
||||
const char * lv_vg_lite_feature_string(vg_lite_feature_t feature);
|
||||
|
||||
const char * lv_vg_lite_buffer_format_string(vg_lite_buffer_format_t format);
|
||||
|
||||
const char * lv_vg_lite_filter_string(vg_lite_filter_t filter);
|
||||
|
||||
const char * lv_vg_lite_blend_string(vg_lite_blend_t blend);
|
||||
|
||||
const char * lv_vg_lite_global_alpha_string(vg_lite_global_alpha_t global_alpha);
|
||||
|
||||
const char * lv_vg_lite_fill_rule_string(vg_lite_fill_t fill_rule);
|
||||
|
||||
const char * lv_vg_lite_image_mode_string(vg_lite_buffer_image_mode_t image_mode);
|
||||
|
||||
const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op);
|
||||
|
||||
void lv_vg_lite_path_dump_info(const vg_lite_path_t * path);
|
||||
|
||||
void lv_vg_lite_buffer_dump_info(const vg_lite_buffer_t * buffer);
|
||||
|
||||
void lv_vg_lite_matrix_dump_info(const vg_lite_matrix_t * matrix);
|
||||
|
||||
bool lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf);
|
||||
|
||||
bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf);
|
||||
|
||||
/* Converter */
|
||||
|
||||
vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf);
|
||||
|
||||
void lv_vg_lite_buffer_format_bytes(
|
||||
vg_lite_buffer_format_t format,
|
||||
uint32_t * mul,
|
||||
uint32_t * div,
|
||||
uint32_t * bytes_align);
|
||||
|
||||
uint32_t lv_vg_lite_width_to_stride(uint32_t w, vg_lite_buffer_format_t color_format);
|
||||
|
||||
uint32_t lv_vg_lite_width_align(uint32_t w);
|
||||
|
||||
bool lv_vg_lite_buffer_init(
|
||||
vg_lite_buffer_t * buffer,
|
||||
const void * ptr,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
vg_lite_buffer_format_t format,
|
||||
bool tiled);
|
||||
|
||||
void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc);
|
||||
|
||||
bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src);
|
||||
|
||||
vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode);
|
||||
|
||||
uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format);
|
||||
|
||||
vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul);
|
||||
|
||||
void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area);
|
||||
|
||||
/* Param checker */
|
||||
|
||||
bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src);
|
||||
|
||||
bool lv_vg_lite_path_check(const vg_lite_path_t * path);
|
||||
|
||||
/* Wrapper */
|
||||
|
||||
bool lv_vg_lite_support_blend_normal(void);
|
||||
|
||||
bool lv_vg_lite_16px_align(void);
|
||||
|
||||
void lv_vg_lite_draw_linear_grad(
|
||||
vg_lite_buffer_t * buffer,
|
||||
vg_lite_path_t * path,
|
||||
const lv_area_t * area,
|
||||
const lv_grad_dsc_t * grad,
|
||||
const vg_lite_matrix_t * matrix,
|
||||
vg_lite_fill_t fill,
|
||||
vg_lite_blend_t blend);
|
||||
|
||||
void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult);
|
||||
|
||||
void lv_vg_lite_matrix_flip_y(vg_lite_matrix_t * matrix);
|
||||
|
||||
bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix);
|
||||
|
||||
lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * matrix, const lv_point_precise_t * point);
|
||||
|
||||
void lv_vg_lite_set_scissor_area(const lv_area_t * area);
|
||||
|
||||
void lv_vg_lite_disable_scissor(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*VG_LITE_UTILS_H*/
|
||||
@@ -350,6 +350,35 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use VG-Lite GPU. */
|
||||
#ifndef LV_USE_DRAW_VG_LITE
|
||||
#ifdef CONFIG_LV_USE_DRAW_VG_LITE
|
||||
#define LV_USE_DRAW_VG_LITE CONFIG_LV_USE_DRAW_VG_LITE
|
||||
#else
|
||||
#define LV_USE_DRAW_VG_LITE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
/* Enbale VG-Lite custom external 'gpu_init()' function */
|
||||
#ifndef LV_VG_LITE_USE_GPU_INIT
|
||||
#ifdef CONFIG_LV_VG_LITE_USE_GPU_INIT
|
||||
#define LV_VG_LITE_USE_GPU_INIT CONFIG_LV_VG_LITE_USE_GPU_INIT
|
||||
#else
|
||||
#define LV_VG_LITE_USE_GPU_INIT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Enable VG-Lite assert. */
|
||||
#ifndef LV_VG_LITE_USE_ASSERT
|
||||
#ifdef CONFIG_LV_VG_LITE_USE_ASSERT
|
||||
#define LV_VG_LITE_USE_ASSERT CONFIG_LV_VG_LITE_USE_ASSERT
|
||||
#else
|
||||
#define LV_VG_LITE_USE_ASSERT 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*=================
|
||||
* OPERATING SYSTEM
|
||||
*=================*/
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
#if LV_USE_DRAW_SDL
|
||||
#include "draw/sdl/lv_draw_sdl.h"
|
||||
#endif
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
#include "draw/vg_lite/lv_draw_vg_lite.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -192,6 +195,10 @@ void lv_init(void)
|
||||
_lv_image_decoder_init();
|
||||
lv_bin_decoder_init(); /*LVGL built-in binary image decoder*/
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
lv_draw_vg_lite_init();
|
||||
#endif
|
||||
|
||||
_lv_cache_init();
|
||||
_lv_cache_builtin_init();
|
||||
lv_cache_lock();
|
||||
@@ -357,6 +364,10 @@ void lv_deinit(void)
|
||||
lv_draw_vglite_deinit();
|
||||
#endif
|
||||
|
||||
#if LV_USE_DRAW_VG_LITE
|
||||
lv_draw_vg_lite_deinit();
|
||||
#endif
|
||||
|
||||
#if LV_USE_DRAW_SW
|
||||
lv_draw_sw_deinit();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user