feat(blend): add blend difference mode (#7796)

This commit is contained in:
Felix Biego
2025-02-21 21:29:29 +03:00
committed by GitHub
parent fc5c156385
commit 728546adb7
11 changed files with 53 additions and 2 deletions

View File

@@ -1369,7 +1369,7 @@ An initialized ``lv_style_transition_dsc_t`` to describe a transition.
blend_mode blend_mode
~~~~~~~~~~ ~~~~~~~~~~
Describes how to blend the colors to the background. Possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY` Describes how to blend the colors to the background. Possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY/DIFFERENCE`
.. raw:: html .. raw:: html

View File

@@ -391,7 +391,7 @@ props = [
{'name': 'BLEND_MODE', {'name': 'BLEND_MODE',
'style_type': 'num', 'var_type': 'lv_blend_mode_t' , 'default':'`LV_BLEND_MODE_NORMAL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'style_type': 'num', 'var_type': 'lv_blend_mode_t' , 'default':'`LV_BLEND_MODE_NORMAL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
'dsc': "Describes how to blend the colors to the background. Possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY`"}, 'dsc': "Describes how to blend the colors to the background. Possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY/DIFFERENCE`"},
{'name': 'LAYOUT', {'name': 'LAYOUT',
'style_type': 'num', 'var_type': 'uint16_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, 'style_type': 'num', 'var_type': 'uint16_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,

View File

@@ -1018,6 +1018,9 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(lv_color16a_t *
case LV_BLEND_MODE_MULTIPLY: case LV_BLEND_MODE_MULTIPLY:
res.lumi = (dest->lumi * src.lumi) >> 8; res.lumi = (dest->lumi * src.lumi) >> 8;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res.lumi = LV_ABS(dest->lumi - src.lumi);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", mode); LV_LOG_WARN("Not supported blend mode: %d", mode);
return; return;

View File

@@ -1046,6 +1046,11 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(lv_color32_t * d
res.green = (dest->green * src.green) >> 8; res.green = (dest->green * src.green) >> 8;
res.blue = (dest->blue * src.blue) >> 8; res.blue = (dest->blue * src.blue) >> 8;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res.red = LV_ABS(dest->red - src.red);
res.green = LV_ABS(dest->green - src.green);
res.blue = LV_ABS(dest->blue - src.blue);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", mode); LV_LOG_WARN("Not supported blend mode: %d", mode);
return; return;

View File

@@ -1066,6 +1066,9 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest_b
case LV_BLEND_MODE_MULTIPLY: case LV_BLEND_MODE_MULTIPLY:
res = (dest_lumi * src_lumi) >> 8; res = (dest_lumi * src_lumi) >> 8;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res = LV_ABS(dest_lumi - src_lumi);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", mode); LV_LOG_WARN("Not supported blend mode: %d", mode);
return; return;

View File

@@ -880,6 +880,9 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest,
case LV_BLEND_MODE_MULTIPLY: case LV_BLEND_MODE_MULTIPLY:
res = (*dest * src_lumi) >> 8; res = (*dest * src_lumi) >> 8;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res = LV_ABS(*dest - src_lumi);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", mode); LV_LOG_WARN("Not supported blend mode: %d", mode);
return; return;

View File

@@ -495,6 +495,10 @@ static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t *
((((dest_buf_u16[dest_x] >> 5) & 0x3F) * ((l8_to_rgb565(chan_val) >> 2) & 0x3F) >> 6) << 5) | ((((dest_buf_u16[dest_x] >> 5) & 0x3F) * ((l8_to_rgb565(chan_val) >> 2) & 0x3F) >> 6) << 5) |
(((dest_buf_u16[dest_x] & 0x1F) * (l8_to_rgb565(chan_val) & 0x1F)) >> 5); (((dest_buf_u16[dest_x] & 0x1F) * (l8_to_rgb565(chan_val) & 0x1F)) >> 5);
break; break;
case LV_BLEND_MODE_DIFFERENCE:
/*Difference blending mode*/
res = (LV_ABS(dest_buf_u16[dest_x] - l8_to_rgb565(chan_val)));
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
return; return;
@@ -613,6 +617,11 @@ static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t
res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5; res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5;
res += (dest_buf_c16[dest_x].blue * rb) >> 5; res += (dest_buf_c16[dest_x].blue * rb) >> 5;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res = (LV_ABS(dest_buf_c16[dest_x].red - rb)) << 11;
res += (LV_ABS(dest_buf_c16[dest_x].green - g)) << 5;
res += LV_ABS(dest_buf_c16[dest_x].blue - rb);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
return; return;
@@ -728,6 +737,11 @@ static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t *
res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5; res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5;
res += (dest_buf_c16[dest_x].blue * rb) >> 5; res += (dest_buf_c16[dest_x].blue * rb) >> 5;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res = (LV_ABS(dest_buf_c16[dest_x].red - rb)) << 11;
res += (LV_ABS(dest_buf_c16[dest_x].green - g)) << 5;
res += LV_ABS(dest_buf_c16[dest_x].blue - rb);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
return; return;
@@ -841,6 +855,11 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_
res += ((dest_buf_c16[x].green * src_buf_c16[x].green) >> 6) << 5; 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; res += (dest_buf_c16[x].blue * src_buf_c16[x].blue) >> 5;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res = (LV_ABS(dest_buf_c16[x].red - src_buf_c16[x].red)) << 11;
res += (LV_ABS(dest_buf_c16[x].green - src_buf_c16[x].green)) << 5;
res += LV_ABS(dest_buf_c16[x].blue - src_buf_c16[x].blue);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
return; return;
@@ -951,6 +970,11 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_
res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; 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; res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11;
res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5;
res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3));
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
return; return;
@@ -1064,6 +1088,11 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds
res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; 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; res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11;
res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5;
res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3));
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode);
return; return;

View File

@@ -922,6 +922,11 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest,
res[1] = (dest[1] * src.green) >> 8; res[1] = (dest[1] * src.green) >> 8;
res[2] = (dest[2] * src.red) >> 8; res[2] = (dest[2] * src.red) >> 8;
break; break;
case LV_BLEND_MODE_DIFFERENCE:
res[0] = LV_ABS((int16_t)dest[0] - src.blue);
res[1] = LV_ABS((int16_t)dest[1] - src.green);
res[2] = LV_ABS((int16_t)dest[2] - src.red);
break;
default: default:
LV_LOG_WARN("Not supported blend mode: %d", mode); LV_LOG_WARN("Not supported blend mode: %d", mode);
return; return;

View File

@@ -91,6 +91,7 @@ typedef enum {
LV_BLEND_MODE_ADDITIVE, /**< Add the respective color channels*/ LV_BLEND_MODE_ADDITIVE, /**< Add the respective color channels*/
LV_BLEND_MODE_SUBTRACTIVE,/**< Subtract the foreground from the background*/ LV_BLEND_MODE_SUBTRACTIVE,/**< Subtract the foreground from the background*/
LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/ LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/
LV_BLEND_MODE_DIFFERENCE, /**< Absolute difference between foreground and background*/
} lv_blend_mode_t; } lv_blend_mode_t;
/** /**

View File

@@ -190,6 +190,7 @@ lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt)
if(lv_streq("additive", txt)) return LV_BLEND_MODE_ADDITIVE; if(lv_streq("additive", txt)) return LV_BLEND_MODE_ADDITIVE;
if(lv_streq("subtractive", txt)) return LV_BLEND_MODE_SUBTRACTIVE; if(lv_streq("subtractive", txt)) return LV_BLEND_MODE_SUBTRACTIVE;
if(lv_streq("multiply", txt)) return LV_BLEND_MODE_MULTIPLY; if(lv_streq("multiply", txt)) return LV_BLEND_MODE_MULTIPLY;
if(lv_streq("difference", txt)) return LV_BLEND_MODE_DIFFERENCE;
LV_LOG_WARN("%s is an unknown value for blend_mode", txt); LV_LOG_WARN("%s is an unknown value for blend_mode", txt);
return 0; /*Return 0 in lack of a better option. */ return 0; /*Return 0 in lack of a better option. */

View File

@@ -77,6 +77,7 @@
<enum name="additive" help=""/> <enum name="additive" help=""/>
<enum name="subtractive" help=""/> <enum name="subtractive" help=""/>
<enum name="multiply" help=""/> <enum name="multiply" help=""/>
<enum name="difference" help=""/>
</enumdef> </enumdef>
<enumdef name="lv_base_dir"> <enumdef name="lv_base_dir">
<enum name="ltr" help=""/> <enum name="ltr" help=""/>