test(draw): add blend mode test to lv_demo_render
@ -692,13 +692,127 @@ static void layer_normal_cb(lv_obj_t * parent)
|
||||
layer_core_cb(parent, LV_BLEND_MODE_NORMAL);
|
||||
}
|
||||
|
||||
static void layer_additive_cb(lv_obj_t * parent)
|
||||
static void create_blend_mode_image_buffer(lv_obj_t * canvas)
|
||||
{
|
||||
return; /*Not working*/
|
||||
lv_canvas_fill_bg(canvas, lv_color_hex3(0x844), LV_OPA_COVER);
|
||||
|
||||
lv_layer_t layer;
|
||||
lv_canvas_init_layer(canvas, &layer);
|
||||
|
||||
lv_draw_label_dsc_t dsc;
|
||||
lv_draw_label_dsc_init(&dsc);
|
||||
dsc.color = lv_color_hex(0xff0000);
|
||||
dsc.text = "R";
|
||||
|
||||
lv_area_t coords = {0, 0, 100, 60};
|
||||
|
||||
lv_draw_label(&layer, &dsc, &coords);
|
||||
dsc.color = lv_color_hex(0x00ff00);
|
||||
dsc.text = "G";
|
||||
coords.x1 = 11;
|
||||
lv_draw_label(&layer, &dsc, &coords);
|
||||
|
||||
dsc.color = lv_color_hex(0x0000ff);
|
||||
dsc.text = "B";
|
||||
coords.x1 = 23;
|
||||
lv_draw_label(&layer, &dsc, &coords);
|
||||
|
||||
dsc.color = lv_color_hex(0xffffff);
|
||||
dsc.text = "W";
|
||||
coords.y1 = 14;
|
||||
coords.x1 = 4;
|
||||
lv_draw_label(&layer, &dsc, &coords);
|
||||
|
||||
dsc.color = lv_color_hex(0x000000);
|
||||
dsc.text = "K";
|
||||
coords.x1 = 20;
|
||||
lv_draw_label(&layer, &dsc, &coords);
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
}
|
||||
|
||||
static lv_obj_t * create_blend_mode_obj(lv_obj_t * parent, int32_t col, int32_t row, const void * src,
|
||||
lv_blend_mode_t blend_mode)
|
||||
{
|
||||
lv_obj_t * obj = lv_image_create(parent);
|
||||
lv_image_set_src(obj, src);
|
||||
lv_image_set_blend_mode(obj, blend_mode);
|
||||
lv_obj_set_style_image_opa(obj, opa_saved, 0);
|
||||
lv_obj_set_style_image_recolor(obj, lv_color_hex(0x00ff00), 0);
|
||||
|
||||
add_to_cell(obj, col, row);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void blend_mode_cb(lv_obj_t * parent)
|
||||
{
|
||||
|
||||
static const int32_t grid_cols[] = {53, 53, 53, 53, 53, 53, 53, 53, 53, LV_GRID_TEMPLATE_LAST};
|
||||
static const int32_t grid_rows[] = {32, 40, 40, 40, 40, 40, 40, LV_GRID_TEMPLATE_LAST};
|
||||
lv_obj_set_grid_dsc_array(parent, grid_cols, grid_rows);
|
||||
|
||||
/*Make the parent darker for additive blending*/
|
||||
lv_obj_set_style_bg_color(parent, lv_color_hex3(0x008), 0);
|
||||
layer_core_cb(parent, LV_BLEND_MODE_ADDITIVE);
|
||||
lv_obj_set_style_bg_color(parent, lv_color_hex(0x808080), 0);
|
||||
|
||||
static uint8_t buf_rgb565[LV_CANVAS_BUF_SIZE(36, 30, 16, LV_DRAW_BUF_STRIDE_ALIGN)];
|
||||
static uint8_t buf_rgb888[LV_CANVAS_BUF_SIZE(36, 30, 24, LV_DRAW_BUF_STRIDE_ALIGN)];
|
||||
static uint8_t buf_xrgb8888[LV_CANVAS_BUF_SIZE(36, 30, 32, LV_DRAW_BUF_STRIDE_ALIGN)];
|
||||
static uint8_t buf_argb8888[LV_CANVAS_BUF_SIZE(36, 30, 32, LV_DRAW_BUF_STRIDE_ALIGN)];
|
||||
|
||||
/*The canvas will stay in the top left corner to show the original image*/
|
||||
lv_obj_t * canvas = lv_canvas_create(lv_screen_active());
|
||||
|
||||
const char * cf_txt[] = {"RGB565", "RGB888.", "XRGB8888", "ARGB8888"};
|
||||
lv_color_format_t cf_values[] = {LV_COLOR_FORMAT_RGB565, LV_COLOR_FORMAT_RGB888, LV_COLOR_FORMAT_XRGB8888, LV_COLOR_FORMAT_ARGB8888};
|
||||
uint8_t * cf_bufs[] = {buf_rgb565, buf_rgb888, buf_xrgb8888, buf_argb8888};
|
||||
static lv_image_dsc_t image_dscs[4];
|
||||
|
||||
const char * mode_txt[] = {"Add.", "Sub.", "Mul."};
|
||||
lv_blend_mode_t mode_values[] = {LV_BLEND_MODE_ADDITIVE, LV_BLEND_MODE_SUBTRACTIVE, LV_BLEND_MODE_MULTIPLY};
|
||||
|
||||
uint32_t m;
|
||||
for(m = 0; m < 3; m++) {
|
||||
lv_obj_t * mode_label = lv_label_create(parent);
|
||||
lv_label_set_text(mode_label, mode_txt[m]);
|
||||
lv_obj_set_grid_cell(mode_label, LV_GRID_ALIGN_CENTER, 0, 1, LV_GRID_ALIGN_CENTER, 1 + m * 2, 2);
|
||||
}
|
||||
|
||||
uint32_t cf;
|
||||
for(cf = 0; cf < 4; cf++) {
|
||||
lv_obj_t * cf_label = lv_label_create(parent);
|
||||
lv_label_set_text(cf_label, cf_txt[cf]);
|
||||
lv_obj_set_grid_cell(cf_label, LV_GRID_ALIGN_CENTER, 1 + cf * 2, 2, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
lv_canvas_set_buffer(canvas, cf_bufs[cf], 36, 30, cf_values[cf]);
|
||||
create_blend_mode_image_buffer(canvas);
|
||||
lv_img_dsc_t * img_src = lv_canvas_get_image(canvas);
|
||||
image_dscs[cf] = *img_src;
|
||||
|
||||
for(m = 0; m < 3; m++) {
|
||||
lv_obj_t * img;
|
||||
img = create_blend_mode_obj(parent, 1 + cf * 2, 1 + m * 2, &image_dscs[cf], mode_values[m]);
|
||||
|
||||
img = create_blend_mode_obj(parent, 2 + cf * 2, 1 + m * 2, &image_dscs[cf], mode_values[m]);
|
||||
lv_image_set_rotation(img, 200);
|
||||
|
||||
img = create_blend_mode_obj(parent, 1 + cf * 2, 2 + m * 2, &image_dscs[cf], mode_values[m]);
|
||||
lv_obj_set_style_image_recolor_opa(img, LV_OPA_50, 0);
|
||||
|
||||
img = create_blend_mode_obj(parent, 2 + cf * 2, 2 + m * 2, &image_dscs[cf], mode_values[m]);
|
||||
lv_image_set_rotation(img, 200);
|
||||
lv_obj_set_style_image_recolor_opa(img, LV_OPA_50, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*Show the recolored image to show the original image*/
|
||||
lv_obj_t * img_recolored = lv_image_create(parent);
|
||||
lv_image_set_src(img_recolored, lv_canvas_get_image(canvas));
|
||||
lv_obj_set_style_image_recolor(img_recolored, lv_color_hex(0x00ff00), 0);
|
||||
lv_obj_set_style_image_recolor_opa(img_recolored, LV_OPA_50, 0);
|
||||
lv_obj_set_y(img_recolored, 30);
|
||||
lv_obj_add_flag(img_recolored, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
@ -717,7 +831,7 @@ static scene_dsc_t scenes[] = {
|
||||
{.name = "arc_image", .create_cb = arc_image_cb},
|
||||
{.name = "triangle", .create_cb = triangle_cb},
|
||||
{.name = "layer_normal", .create_cb = layer_normal_cb},
|
||||
{.name = "layer_additive", .create_cb = layer_additive_cb},
|
||||
{.name = "blend_mode", .create_cb = blend_mode_cb},
|
||||
|
||||
{.name = "", .create_cb = NULL}
|
||||
};
|
||||
|
@ -36,6 +36,7 @@ typedef enum {
|
||||
LV_DEMO_RENDER_SCENE_ARC_IMAGE,
|
||||
LV_DEMO_RENDER_SCENE_TRIANGLE,
|
||||
LV_DEMO_RENDER_SCENE_LAYER_NORMAL,
|
||||
LV_DEMO_RENDER_SCENE_BLEND_MODE,
|
||||
_LV_DEMO_RENDER_SCENE_NUM,
|
||||
} lv_demo_render_scene_t;
|
||||
|
||||
|
@ -838,7 +838,7 @@ static lv_result_t layer_get_area(lv_layer_t * layer, lv_obj_t * obj, lv_layer_t
|
||||
}
|
||||
|
||||
*layer_area_out = inverse_clip_coords_for_obj;
|
||||
lv_area_increase(layer_area_out, 1, 1); /*To avoid rounding error*/
|
||||
lv_area_increase(layer_area_out, 5, 5); /*To avoid rounding error*/
|
||||
}
|
||||
else if(layer_type == LV_LAYER_TYPE_SIMPLE) {
|
||||
lv_area_t clip_coords_for_obj;
|
||||
|
@ -340,6 +340,7 @@ static void texture_resize(lv_display_t * disp)
|
||||
#else
|
||||
#error("Unsupported color format")
|
||||
#endif
|
||||
// px_format = SDL_PIXELFORMAT_BGR24;
|
||||
|
||||
dsc->texture = SDL_CreateTexture(dsc->renderer, px_format,
|
||||
SDL_TEXTUREACCESS_STATIC, hor_res, ver_res);
|
||||
|
@ -495,7 +495,7 @@ void lv_color_mix_with_alpha_cache_init(lv_color_mix_alpha_cache_t * cache)
|
||||
LV_ATTRIBUTE_FAST_MEM static inline void blend_non_normal_pixel(lv_color32_t * dest, lv_color32_t src,
|
||||
lv_blend_mode_t mode, lv_color_mix_alpha_cache_t * cache)
|
||||
{
|
||||
lv_color32_t res = {0, 0, 0, 0};
|
||||
lv_color32_t res;
|
||||
switch(mode) {
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
res.red = LV_MIN(dest->red + src.red, 255);
|
||||
@ -516,6 +516,7 @@ LV_ATTRIBUTE_FAST_MEM static inline void blend_non_normal_pixel(lv_color32_t * d
|
||||
LV_LOG_WARN("Not supported blend mode: %d", mode);
|
||||
return;
|
||||
}
|
||||
res.alpha = src.alpha;
|
||||
*dest = lv_color_32_32_mix(res, *dest, cache);
|
||||
}
|
||||
|
||||
|
@ -282,28 +282,28 @@ LV_ATTRIBUTE_FAST_MEM static void rgb565_image_blend(_lv_draw_sw_blend_image_dsc
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_color16_t * dest_buf_c16 = (lv_color16_t *) dest_buf_u16;
|
||||
lv_color16_t * src_buf_c16 = (lv_color16_t *) src_buf_u16;
|
||||
uint16_t res = 0;
|
||||
for(y = 0; y < h; y++) {
|
||||
lv_color16_t * dest_buf_c16 = (lv_color16_t *) dest_buf_u16;
|
||||
lv_color16_t * src_buf_c16 = (lv_color16_t *) src_buf_u16;
|
||||
for(x = 0; x < w; x++) {
|
||||
switch(dsc->blend_mode) {
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
if(src_buf_u16[x] == 0x0000) continue; /*Do not add pure black*/
|
||||
res = LV_MIN(dest_buf_c16[x].red + src_buf_c16[x].red, 31);
|
||||
res += LV_MIN(dest_buf_c16[x].green + src_buf_c16[x].green, 63);
|
||||
res = (LV_MIN(dest_buf_c16[x].red + src_buf_c16[x].red, 31)) << 11;
|
||||
res += (LV_MIN(dest_buf_c16[x].green + src_buf_c16[x].green, 63)) << 5;
|
||||
res += LV_MIN(dest_buf_c16[x].blue + src_buf_c16[x].blue, 31);
|
||||
break;
|
||||
case LV_BLEND_MODE_SUBTRACTIVE:
|
||||
if(src_buf_u16[x] == 0x0000) continue; /*Do not subtract pure black*/
|
||||
res = LV_MAX(dest_buf_c16[x].red - src_buf_c16[x].red, 0);
|
||||
res += LV_MAX(dest_buf_c16[x].green - src_buf_c16[x].green, 0);
|
||||
res = (LV_MAX(dest_buf_c16[x].red - src_buf_c16[x].red, 0)) << 11;
|
||||
res += (LV_MAX(dest_buf_c16[x].green - src_buf_c16[x].green, 0)) << 5;
|
||||
res += LV_MAX(dest_buf_c16[x].blue - src_buf_c16[x].blue, 0);
|
||||
break;
|
||||
case LV_BLEND_MODE_MULTIPLY:
|
||||
if(src_buf_u16[x] == 0xffff) continue; /*Do not multiply with pure white (considered as 1)*/
|
||||
res = (dest_buf_c16[x].red * src_buf_c16[x].red) >> 5;
|
||||
res += (dest_buf_c16[x].green * src_buf_c16[x].green) >> 6;
|
||||
res = ((dest_buf_c16[x].red * src_buf_c16[x].red) >> 5) << 11;
|
||||
res += ((dest_buf_c16[x].green * src_buf_c16[x].green) >> 6) << 5;
|
||||
res += (dest_buf_c16[x].blue * src_buf_c16[x].blue) >> 5;
|
||||
break;
|
||||
default:
|
||||
@ -312,7 +312,7 @@ LV_ATTRIBUTE_FAST_MEM static void rgb565_image_blend(_lv_draw_sw_blend_image_dsc
|
||||
}
|
||||
|
||||
if(mask_buf == NULL) {
|
||||
lv_color_16_16_mix(res, dest_buf_u16[x], opa);
|
||||
dest_buf_u16[x] = lv_color_16_16_mix(res, dest_buf_u16[x], opa);
|
||||
}
|
||||
else {
|
||||
if(opa >= LV_OPA_MAX) dest_buf_u16[x] = lv_color_16_16_mix(res, dest_buf_u16[x], mask_buf[x]);
|
||||
@ -384,28 +384,27 @@ LV_ATTRIBUTE_FAST_MEM static void rgb888_image_blend(_lv_draw_sw_blend_image_dsc
|
||||
mask_buf += mask_stride;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
lv_color16_t * dest_buf_c16 = (lv_color16_t *) dest_buf_u16;
|
||||
uint16_t res = 0;
|
||||
for(y = 0; y < h; y++) {
|
||||
lv_color16_t * dest_buf_c16 = (lv_color16_t *) dest_buf_u16;
|
||||
for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) {
|
||||
switch(dsc->blend_mode) {
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
res = LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 0] >> 3), 31);
|
||||
res += LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63);
|
||||
res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 2] >> 3), 31);
|
||||
res = (LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 2] >> 3), 31)) << 11;
|
||||
res += (LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63)) << 5;
|
||||
res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 0] >> 3), 31);
|
||||
break;
|
||||
case LV_BLEND_MODE_SUBTRACTIVE:
|
||||
res = LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 0] >> 3), 0);
|
||||
res += LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0);
|
||||
res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 2] >> 3), 0);
|
||||
res = (LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3), 0)) << 11;
|
||||
res += (LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0)) << 5;
|
||||
res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3), 0);
|
||||
break;
|
||||
case LV_BLEND_MODE_MULTIPLY:
|
||||
res = (dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 0] >> 3)) >> 5;
|
||||
res += (dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6;
|
||||
res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 2] >> 3)) >> 5;
|
||||
res = ((dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 2] >> 3)) >> 5) << 11;
|
||||
res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5;
|
||||
res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 1] >> 3)) >> 5;
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
|
||||
@ -413,7 +412,7 @@ LV_ATTRIBUTE_FAST_MEM static void rgb888_image_blend(_lv_draw_sw_blend_image_dsc
|
||||
}
|
||||
|
||||
if(mask_buf == NULL) {
|
||||
lv_color_16_16_mix(res, dest_buf_u16[dest_x], opa);
|
||||
dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], opa);
|
||||
}
|
||||
else {
|
||||
if(opa >= LV_OPA_MAX) dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], mask_buf[dest_x]);
|
||||
@ -488,25 +487,25 @@ LV_ATTRIBUTE_FAST_MEM static void argb8888_image_blend(_lv_draw_sw_blend_image_d
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_color16_t * dest_buf_c16 = (lv_color16_t *) dest_buf_u16;
|
||||
uint16_t res = 0;
|
||||
for(y = 0; y < h; y++) {
|
||||
lv_color16_t * dest_buf_c16 = (lv_color16_t *) dest_buf_u16;
|
||||
for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) {
|
||||
switch(dsc->blend_mode) {
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
res = LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 0] >> 3), 31);
|
||||
res += LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63);
|
||||
res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 2] >> 3), 31);
|
||||
res = (LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 2] >> 3), 31)) << 11;
|
||||
res += (LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63)) << 5;
|
||||
res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 0] >> 3), 31);
|
||||
break;
|
||||
case LV_BLEND_MODE_SUBTRACTIVE:
|
||||
res = LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 0] >> 3), 0);
|
||||
res += LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0);
|
||||
res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 2] >> 3), 0);
|
||||
res = (LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3), 0)) << 11;
|
||||
res += (LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0)) << 5;
|
||||
res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3), 0);
|
||||
break;
|
||||
case LV_BLEND_MODE_MULTIPLY:
|
||||
res = (dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 0] >> 3)) >> 5;
|
||||
res += (dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6;
|
||||
res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 2] >> 3)) >> 5;
|
||||
res = ((dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 2] >> 3)) >> 5) << 11;
|
||||
res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5;
|
||||
res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5;
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
|
||||
@ -514,10 +513,10 @@ LV_ATTRIBUTE_FAST_MEM static void argb8888_image_blend(_lv_draw_sw_blend_image_d
|
||||
}
|
||||
|
||||
if(mask_buf == NULL && opa >= LV_OPA_MAX) {
|
||||
lv_color_16_16_mix(res, dest_buf_u16[dest_x], src_buf_u8[src_x + 3]);
|
||||
dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], src_buf_u8[src_x + 3]);
|
||||
}
|
||||
else if(mask_buf == NULL && opa < LV_OPA_MAX) {
|
||||
lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(opa, src_buf_u8[src_x + 3]));
|
||||
dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(opa, src_buf_u8[src_x + 3]));
|
||||
}
|
||||
else {
|
||||
if(opa >= LV_OPA_MAX) dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], mask_buf[dest_x]);
|
||||
|
@ -195,6 +195,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_color_to_rgb888(_lv_draw_sw_blend_fi
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_image_to_rgb888(_lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size)
|
||||
{
|
||||
|
||||
switch(dsc->src_color_format) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
rgb565_image_blend(dsc, dest_px_size);
|
||||
@ -492,19 +493,19 @@ LV_ATTRIBUTE_FAST_MEM static inline void blend_non_normal_pixel(uint8_t * dest,
|
||||
uint8_t res[3] = {0, 0, 0};
|
||||
switch(mode) {
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
res[0] = LV_MIN(dest[0] + src.red, 255);
|
||||
res[0] = LV_MIN(dest[0] + src.blue, 255);
|
||||
res[1] = LV_MIN(dest[1] + src.green, 255);
|
||||
res[2] = LV_MIN(dest[2] + src.blue, 255);
|
||||
res[2] = LV_MIN(dest[2] + src.red, 255);
|
||||
break;
|
||||
case LV_BLEND_MODE_SUBTRACTIVE:
|
||||
res[0] = LV_MAX(dest[0] - src.red, 0);
|
||||
res[0] = LV_MAX(dest[0] - src.blue, 0);
|
||||
res[1] = LV_MAX(dest[1] - src.green, 0);
|
||||
res[2] = LV_MAX(dest[2] - src.blue, 0);
|
||||
res[2] = LV_MAX(dest[2] - src.red, 0);
|
||||
break;
|
||||
case LV_BLEND_MODE_MULTIPLY:
|
||||
res[0] = (dest[0] * src.red) >> 8;
|
||||
res[0] = (dest[0] * src.blue) >> 8;
|
||||
res[1] = (dest[1] * src.green) >> 8;
|
||||
res[2] = (dest[2] * src.blue) >> 8;
|
||||
res[2] = (dest[2] * src.red) >> 8;
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("Not supported blend mode: %d", mode);
|
||||
@ -517,10 +518,6 @@ LV_ATTRIBUTE_FAST_MEM static inline void lv_color_24_24_mix(const uint8_t * src,
|
||||
{
|
||||
|
||||
if(mix == 0) return;
|
||||
// dest[0] = 0xff;
|
||||
// dest[1] = 0x00;
|
||||
// dest[2] = 0x00;
|
||||
// return;
|
||||
|
||||
if(mix >= LV_OPA_MAX) {
|
||||
dest[0] = src[0];
|
||||
|
@ -237,6 +237,7 @@ void lv_image_set_offset_y(lv_obj_t * obj, int32_t y)
|
||||
|
||||
void lv_image_set_rotation(lv_obj_t * obj, int32_t angle)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) {
|
||||
@ -281,6 +282,8 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle)
|
||||
|
||||
void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) {
|
||||
x = 0;
|
||||
@ -323,6 +326,8 @@ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y)
|
||||
|
||||
void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
/*If scale is set internally, do no overwrite it*/
|
||||
@ -337,6 +342,8 @@ void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom)
|
||||
|
||||
void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
/*If scale is set internally, do no overwrite it*/
|
||||
@ -351,6 +358,8 @@ void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom)
|
||||
|
||||
void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
/*If scale is set internally, do no overwrite it*/
|
||||
@ -363,8 +372,24 @@ void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom)
|
||||
scale_update(obj, img->scale_x, zoom);
|
||||
}
|
||||
|
||||
void lv_image_set_blend_mode(lv_obj_t * obj, lv_blend_mode_t blend_mode)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
/*If scale is set internally, do no overwrite it*/
|
||||
if(img->blend_mode == blend_mode) return;
|
||||
|
||||
img->blend_mode = blend_mode;
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
void lv_image_set_antialias(lv_obj_t * obj, bool antialias)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
if(antialias == img->antialias) return;
|
||||
|
||||
@ -375,6 +400,7 @@ void lv_image_set_antialias(lv_obj_t * obj, bool antialias)
|
||||
void lv_image_set_align(lv_obj_t * obj, lv_image_align_t align)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
if(align == img->align) return;
|
||||
|
||||
@ -462,6 +488,15 @@ int32_t lv_image_get_scale_y(lv_obj_t * obj)
|
||||
return img->scale_y;
|
||||
}
|
||||
|
||||
lv_blend_mode_t lv_image_get_blend_mode(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
return img->blend_mode;
|
||||
}
|
||||
|
||||
bool lv_image_get_antialias(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
@ -474,7 +509,9 @@ bool lv_image_get_antialias(lv_obj_t * obj)
|
||||
lv_image_align_t lv_image_get_align(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
return img->align;
|
||||
}
|
||||
|
||||
@ -671,6 +708,7 @@ static void draw_image(lv_event_t * e)
|
||||
draw_dsc.scale_y = img->scale_y;
|
||||
draw_dsc.rotation = img->rotation;
|
||||
draw_dsc.antialias = img->antialias;
|
||||
draw_dsc.blend_mode = img->blend_mode;
|
||||
draw_dsc.src = img->src;
|
||||
|
||||
lv_area_t img_area = {obj->coords.x1, obj->coords.y1,
|
||||
|
@ -47,10 +47,11 @@ typedef struct {
|
||||
uint32_t scale_x; /**< 256 means no zoom, 512 double size, 128 half size*/
|
||||
uint32_t scale_y; /**< 256 means no zoom, 512 double size, 128 half size*/
|
||||
lv_point_t pivot; /**< Rotation center of the image*/
|
||||
uint8_t src_type : 2; /**< See: lv_image_src_t*/
|
||||
uint8_t cf : 5; /**< Color format from `lv_color_format_t`*/
|
||||
uint8_t antialias : 1; /**< Apply anti-aliasing in transformations (rotate, zoom)*/
|
||||
uint8_t align: 4; /**< Image size mode when image size and object size is different. See `lv_image_align_t`*/
|
||||
uint32_t src_type : 2; /**< See: lv_image_src_t*/
|
||||
uint32_t cf : 5; /**< Color format from `lv_color_format_t`*/
|
||||
uint32_t antialias : 1; /**< Apply anti-aliasing in transformations (rotate, zoom)*/
|
||||
uint32_t align: 4; /**< Image size mode when image size and object size is different. See `lv_image_align_t`*/
|
||||
uint32_t blend_mode: 4; /**< Element of `lv_blend_mode_t`*/
|
||||
} lv_image_t;
|
||||
|
||||
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_image_class;
|
||||
@ -202,6 +203,13 @@ void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom);
|
||||
*/
|
||||
void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom);
|
||||
|
||||
/**
|
||||
* Set the blend mode of an image.
|
||||
* @param obj pointer to an image object
|
||||
* @param blend_mode the new blend mode
|
||||
*/
|
||||
void lv_image_set_blend_mode(lv_obj_t * obj, lv_blend_mode_t blend_mode);
|
||||
|
||||
/**
|
||||
* Enable/disable anti-aliasing for the transformations (rotate, zoom) or not.
|
||||
* The quality is better with anti-aliasing looks better but slower.
|
||||
@ -282,6 +290,13 @@ int32_t lv_image_get_scale_x(lv_obj_t * obj);
|
||||
*/
|
||||
int32_t lv_image_get_scale_y(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the current blend mode of the image
|
||||
* @param obj pointer to an image object
|
||||
* @return the current blend mode
|
||||
*/
|
||||
lv_blend_mode_t lv_image_get_blend_mode(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get whether the transformations (rotate, zoom) are anti-aliased or not
|
||||
* @param obj pointer to an image object
|
||||
|
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |