mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
line mask: support all direction and inversion
This commit is contained in:
parent
9b91dc057e
commit
b1d4d6faef
@ -20,6 +20,77 @@
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
|
||||
/*
|
||||
* 8192
|
||||
8193
|
||||
8196
|
||||
8201
|
||||
8208
|
||||
8217
|
||||
8228
|
||||
8241
|
||||
8256
|
||||
8273
|
||||
8291
|
||||
8312
|
||||
8335
|
||||
8359
|
||||
8386
|
||||
8414
|
||||
8444
|
||||
8476
|
||||
8510
|
||||
8545
|
||||
8583
|
||||
8622
|
||||
8662
|
||||
8705
|
||||
8749
|
||||
8795
|
||||
8842
|
||||
8891
|
||||
8942
|
||||
8994
|
||||
9047
|
||||
9102
|
||||
9159
|
||||
9217
|
||||
9276
|
||||
9337
|
||||
9399
|
||||
9462
|
||||
9527
|
||||
9593
|
||||
9660
|
||||
9729
|
||||
9798
|
||||
9869
|
||||
9941
|
||||
10014
|
||||
10088
|
||||
10164
|
||||
10240
|
||||
10317
|
||||
10396
|
||||
10475
|
||||
10555
|
||||
10636
|
||||
10718
|
||||
10801
|
||||
10885
|
||||
10970
|
||||
11056
|
||||
11142
|
||||
11229
|
||||
11317
|
||||
11406
|
||||
11495
|
||||
11585
|
||||
*
|
||||
*
|
||||
* */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lv_point_t p1;
|
||||
|
@ -97,11 +97,22 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, const lv_s
|
||||
|
||||
lv_color_t line_buf[LV_HOR_RES_MAX];
|
||||
lv_opa_t mask_buf[LV_HOR_RES_MAX];
|
||||
lv_mask_line_param_t line_mask_param;
|
||||
line_mask_param.origo.x = 0;
|
||||
line_mask_param.origo.y = 0;
|
||||
line_mask_param.steep = 987;
|
||||
line_mask_param.flat = 1;
|
||||
lv_mask_line_param_t line_mask_param1;
|
||||
// lv_mask_line_points_init(&line_mask_param1, 10, 0, 100, 200, LV_LINE_MASK_SIDE_RIGHT);
|
||||
lv_mask_line_angle_init(&line_mask_param1, 50, 1, -20, LV_LINE_MASK_SIDE_RIGHT);
|
||||
|
||||
lv_mask_line_param_t line_mask_param2;
|
||||
// lv_mask_line_points_init(&line_mask_param2, 10, 0, 100, 200, LV_LINE_MASK_SIDE_LEFT);
|
||||
lv_mask_line_angle_init(&line_mask_param2, 50, 0, -20, LV_LINE_MASK_SIDE_LEFT);
|
||||
|
||||
|
||||
|
||||
// line_mask_param1.origo.x = 0;
|
||||
// line_mask_param1.origo.y = 0;
|
||||
// line_mask_param1.steep = 300;
|
||||
// line_mask_param1.flat = 1;
|
||||
// line_mask_param1.side = LV_LINE_MASK_SIDE_RIGHT;
|
||||
// line_mask_param1.inv = 0;
|
||||
|
||||
|
||||
/*Fill with a color line-by-line*/
|
||||
@ -113,7 +124,8 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, const lv_s
|
||||
|
||||
if(style->body.main_color.full != style->body.grad_color.full) {
|
||||
memset(mask_buf, LV_OPA_COVER, draw_a_width);
|
||||
lv_mask_line_left(mask_buf, vdb->area.x1 + draw_rel_a.x1, vdb->area.y1 + h, draw_a_width, true, &line_mask_param);
|
||||
lv_mask_line(mask_buf, vdb->area.x1 + draw_rel_a.x1, vdb->area.y1 + h, draw_a_width, &line_mask_param1);
|
||||
lv_mask_line(mask_buf, vdb->area.x1 + draw_rel_a.x1, vdb->area.y1 + h, draw_a_width, &line_mask_param2);
|
||||
lv_mask_apply(&vdb_buf_tmp[draw_rel_a.x1], line_buf, mask_buf, draw_a_width);
|
||||
} else {
|
||||
memcpy(&vdb_buf_tmp[draw_rel_a.x1], line_buf, draw_a_width * sizeof(lv_color_t));
|
||||
|
@ -7,6 +7,7 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_mask.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@ -19,6 +20,10 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, lv_mask_line_param_t * p);
|
||||
static void line_mask_steep(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, lv_mask_line_param_t * p);
|
||||
|
||||
static lv_opa_t mask_mix(lv_opa_t mask_act, lv_opa_t mask_new);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -41,182 +46,360 @@ void lv_mask_apply(lv_color_t * dest_buf, lv_color_t * src_buf, lv_opa_t * mask_
|
||||
}
|
||||
}
|
||||
|
||||
void lv_mask_line_left(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, bool inner, void * param)
|
||||
|
||||
void lv_mask_line_points_init(lv_mask_line_param_t * p, lv_coord_t p1x, lv_coord_t p1y, lv_coord_t p2x, lv_coord_t p2y, lv_line_mask_side_t side)
|
||||
{
|
||||
memset(p, 0x00, sizeof(lv_mask_line_param_t));
|
||||
if(p1y > p2y) {
|
||||
lv_coord_t t;
|
||||
t = p2x;
|
||||
p2x = p1x;
|
||||
p1x = t;
|
||||
|
||||
t = p2y;
|
||||
p2y = p1y;
|
||||
p1y = t;
|
||||
}
|
||||
|
||||
|
||||
p->origo.x = p1x;
|
||||
p->origo.y = p1y;
|
||||
p->side = side;
|
||||
p->flat = (LV_MATH_ABS(p2x-p1x) > LV_MATH_ABS(p2y-p1y)) ? 1 : 0;
|
||||
if(p->flat) {
|
||||
/*Normalize the steep. Delta x should be relative to delta x = 1024*/
|
||||
int32_t m;
|
||||
m = (1 << 20) / (p2x-p1x); /*m is multiplier to normalize y (upscaled by 1024)*/
|
||||
p->steep = (m * (p2y-p1y)) >> 10;
|
||||
} else {
|
||||
/*Normalize the steep. Delta y should be relative to delta x = 1024*/
|
||||
int32_t m;
|
||||
m = (1 << 20) / (p2y-p1y); /*m is multiplier to normalize x (upscaled by 1024)*/
|
||||
p->steep = (m * (p2x-p1x)) >> 10;
|
||||
}
|
||||
|
||||
if(p->side == LV_LINE_MASK_SIDE_LEFT) p->inv = 0;
|
||||
else if(p->side == LV_LINE_MASK_SIDE_RIGHT) p->inv = 1;
|
||||
else if(p->side == LV_LINE_MASK_SIDE_TOP) {
|
||||
if(p->steep > 0) p->inv = 0;
|
||||
else p->inv = 1;
|
||||
}
|
||||
else if(p->side == LV_LINE_MASK_SIDE_BOTTOM) {
|
||||
if(p->steep > 0) p->inv = 1;
|
||||
else p->inv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_mask_line_angle_init(lv_mask_line_param_t * p, lv_coord_t p1x, lv_coord_t p1y, int16_t deg, lv_line_mask_side_t side)
|
||||
{
|
||||
lv_coord_t p2x;
|
||||
lv_coord_t p2y;
|
||||
|
||||
p2x = (lv_trigo_sin(deg - 90) >> 5) + p1x;
|
||||
p2y = (lv_trigo_sin(deg) >> 5) + p1y;
|
||||
|
||||
lv_mask_line_points_init(p, p1x, p1y, p2x, p2y, side);
|
||||
}
|
||||
|
||||
void lv_mask_line(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, void * param)
|
||||
{
|
||||
lv_mask_line_param_t * p = (lv_mask_line_param_t *)param;
|
||||
|
||||
/*make to points absolute to the origo*/
|
||||
abs_x -= p->origo.x;
|
||||
/*Make to points relative to the origo*/
|
||||
abs_y -= p->origo.y;
|
||||
abs_x -= p->origo.x;
|
||||
|
||||
if(p->flat) {
|
||||
lv_coord_t y_at_x;
|
||||
|
||||
/* At the beginning of the mask if the limit line is greater then the mask's y.
|
||||
* Then the mask is in the "wrong" area*/
|
||||
y_at_x = (int32_t)((int32_t)p->steep * abs_x) >> 10;
|
||||
|
||||
if(p->steep > 0) {
|
||||
if(y_at_x > abs_y) {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(y_at_x < abs_y) {
|
||||
/*Handle special cases*/
|
||||
if(p->steep == 0) {
|
||||
/*Horizontal*/
|
||||
if(p->flat) {
|
||||
/*Non sense: Can't be on the right/left of a horizontal line*/
|
||||
if(p->side == LV_LINE_MASK_SIDE_LEFT || p->side == LV_LINE_MASK_SIDE_RIGHT) return;
|
||||
else if(p->side == LV_LINE_MASK_SIDE_TOP && abs_y+1 < p->origo.y) return;
|
||||
else if(p->side == LV_LINE_MASK_SIDE_BOTTOM && abs_y > p->origo.y) return;
|
||||
else {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* At the end of the mask if the limit line is smaller then the mask's y.
|
||||
* Then the mask is in the "good" area*/
|
||||
y_at_x = (int32_t)((int32_t)p->steep * (abs_x + len)) >> 10;
|
||||
if(p->steep > 0) {
|
||||
if(y_at_x < abs_y) {
|
||||
return;
|
||||
/*Vertical*/
|
||||
else {
|
||||
/*Non sense: Can't be on the top/bottom of a vertical line*/
|
||||
if(p->side == LV_LINE_MASK_SIDE_TOP || p->side == LV_LINE_MASK_SIDE_BOTTOM) return;
|
||||
else if(p->side == LV_LINE_MASK_SIDE_RIGHT && abs_x > 0) return;
|
||||
else if(p->side == LV_LINE_MASK_SIDE_LEFT) {
|
||||
if(abs_x + len < 0) return;
|
||||
else {
|
||||
int32_t k = - abs_x;
|
||||
if(k < 0) k = 0;
|
||||
if(k >= 0 && k < len) memset(&mask_buf[k], 0x00, len - k);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(y_at_x > abs_y) {
|
||||
else {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t xe;
|
||||
if(p->steep > 0) xe = ((abs_y << 18) / p->steep);
|
||||
else xe = (((abs_y + 1) << 18) / p->steep);
|
||||
|
||||
int32_t xei = xe >> 8;
|
||||
int32_t xef = xe & 0xFF;
|
||||
|
||||
int32_t sps = p->steep >> 2;
|
||||
if(p->steep < 0) sps = -sps;
|
||||
|
||||
int32_t px_h;
|
||||
if(xef == 0) px_h = 255;
|
||||
else px_h = 255 - (((255 - xef) * sps) >> 8);
|
||||
int32_t k = xei - abs_x;
|
||||
|
||||
if(xef) {
|
||||
if(k >= 0) mask_buf[k] = 255 - (((255-xef) * (255 - px_h)) >> 9);
|
||||
k++;
|
||||
}
|
||||
|
||||
while(px_h > sps) {
|
||||
if(k >= 0) mask_buf[k] = px_h - (sps >> 1);
|
||||
px_h -= sps;
|
||||
k++;
|
||||
if(k >= len) return;
|
||||
}
|
||||
|
||||
if(k < len && k >= 0) {
|
||||
int32_t x_inters = (px_h << 10)/ p->steep;
|
||||
mask_buf[k] = (x_inters * px_h) >> 9; //px_h >> 1; /*Approximation*/
|
||||
}
|
||||
|
||||
k++;
|
||||
if(k < len && k >= 0)
|
||||
{
|
||||
memset(&mask_buf[k] ,0x00, len - k);
|
||||
}
|
||||
} else {
|
||||
lv_coord_t x_at_y;
|
||||
/* At the beginning of the mask if the limit line is greater then the mask's y.
|
||||
* Then the mask is in the "wrong" area*/
|
||||
x_at_y = (int32_t)((int32_t)p->steep * abs_y) >> 10;
|
||||
if(x_at_y < abs_x) {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* At the end of the mask if the limit line is smaller then the mask's y.
|
||||
* Then the mask is in the "good" area*/
|
||||
x_at_y = (int32_t)((int32_t)p->steep * (abs_y)) >> 10;
|
||||
if(x_at_y > abs_x + len) {
|
||||
return;
|
||||
}
|
||||
int32_t xe = ((abs_y << 8) * p->steep) >> 10;
|
||||
int32_t xei = xe >> 8;
|
||||
int32_t xef = xe & 0xFF;
|
||||
|
||||
int32_t xq = (((abs_y + 1) << 8) * p->steep) >> 10;
|
||||
int32_t xqi = xq >> 8;
|
||||
int32_t xqf = xq & 0xFF;
|
||||
|
||||
int32_t k = xei - abs_x;
|
||||
if(xei != xqi && (p->steep < 0 && xef == 0)) {
|
||||
xef = 0xFF;
|
||||
xei = xqi;
|
||||
k--;
|
||||
}
|
||||
|
||||
if(xei == xqi) {
|
||||
|
||||
if(k >= 0 && k < len) {
|
||||
mask_buf[k] = (xef + xqf) >> 1;
|
||||
}
|
||||
k++;
|
||||
|
||||
if(k >= 0 && k < len ) {
|
||||
memset(&mask_buf[k] ,0x00, len - (k));
|
||||
}
|
||||
|
||||
} else {
|
||||
int32_t y_inters;
|
||||
if(p->steep < 0) {
|
||||
y_inters = (xef << 10) / (-p->steep);
|
||||
if(k >= 0 && k < len ) {
|
||||
mask_buf[k] = (y_inters * xef) >> 9;
|
||||
}
|
||||
k--;
|
||||
|
||||
int32_t x_inters = ((255-y_inters) * (-p->steep)) >> 10;
|
||||
|
||||
if(k >= 0 && k < len ) {
|
||||
mask_buf[k] = 255-(((255-y_inters) * x_inters) >> 9);
|
||||
}
|
||||
|
||||
k+=2;
|
||||
|
||||
|
||||
if(k >= 0 && k < len ) {
|
||||
memset(&mask_buf[k] ,0x00, len - (k));
|
||||
}
|
||||
|
||||
} else {
|
||||
y_inters = ((255-xef) << 10) / p->steep;
|
||||
if(k >= 0 && k < len ) {
|
||||
mask_buf[k] = 255 - ((y_inters * (255-xef)) >> 9);
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
int32_t x_inters = ((255-y_inters) * p->steep) >> 10;
|
||||
|
||||
|
||||
if(k >= 0 && k < len ) {
|
||||
mask_buf[k] = ((255-y_inters) * x_inters) >> 9;
|
||||
}
|
||||
k++;
|
||||
|
||||
if(k >= 0 && k < len )
|
||||
{
|
||||
memset(&mask_buf[k] ,0x00, len - (k));
|
||||
}
|
||||
}
|
||||
printf("y: %d, xef: %d, y_inters: %d, %d\n", abs_y, xef, y_inters * 100 / 255);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(p->flat) {
|
||||
line_mask_flat(mask_buf, abs_x, abs_y, len, p);
|
||||
} else {
|
||||
line_mask_steep(mask_buf, abs_x, abs_y, len, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void lv_mask_radius(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, lv_mask_radius_param_t * param)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, lv_mask_line_param_t * p)
|
||||
{
|
||||
lv_coord_t y_at_x;
|
||||
|
||||
/* At the beginning of the mask if the limit line is greater then the mask's y.
|
||||
* Then the mask is in the "wrong" area*/
|
||||
y_at_x = (int32_t)((int32_t)p->steep * abs_x) >> 10;
|
||||
|
||||
if(p->steep > 0) {
|
||||
if(y_at_x > abs_y) {
|
||||
if(p->inv) {
|
||||
return;
|
||||
} else {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(y_at_x < abs_y) {
|
||||
if(p->inv) {
|
||||
return;
|
||||
} else {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At the end of the mask if the limit line is smaller then the mask's y.
|
||||
* Then the mask is in the "good" area*/
|
||||
y_at_x = (int32_t)((int32_t)p->steep * (abs_x + len)) >> 10;
|
||||
if(p->steep > 0) {
|
||||
if(y_at_x < abs_y) {
|
||||
if(p->inv) {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(y_at_x > abs_y) {
|
||||
if(p->inv) {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t xe;
|
||||
if(p->steep > 0) xe = ((abs_y << 18) / p->steep);
|
||||
else xe = (((abs_y + 1) << 18) / p->steep);
|
||||
|
||||
int32_t xei = xe >> 8;
|
||||
int32_t xef = xe & 0xFF;
|
||||
|
||||
int32_t sps = p->steep >> 2;
|
||||
if(p->steep < 0) sps = -sps;
|
||||
|
||||
int32_t px_h;
|
||||
if(xef == 0) px_h = 255;
|
||||
else px_h = 255 - (((255 - xef) * sps) >> 8);
|
||||
int32_t k = xei - abs_x;
|
||||
lv_opa_t m;
|
||||
|
||||
if(xef) {
|
||||
if(k >= 0) {
|
||||
m = 255 - (((255-xef) * (255 - px_h)) >> 9);
|
||||
if(p->inv) m = 255 - m;
|
||||
mask_buf[k] = mask_mix(mask_buf[k], m);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
while(px_h > sps) {
|
||||
if(k >= 0) {
|
||||
m = px_h - (sps >> 1);
|
||||
if(p->inv) m = 255 - m;
|
||||
mask_buf[k] = mask_mix(mask_buf[k], m);
|
||||
}
|
||||
px_h -= sps;
|
||||
k++;
|
||||
if(k >= len) break;
|
||||
}
|
||||
|
||||
if(k < len && k >= 0) {
|
||||
int32_t x_inters = (px_h << 10) / p->steep;
|
||||
m = (x_inters * px_h) >> 9;
|
||||
if(p->inv) m = 255 - m;
|
||||
mask_buf[k] = mask_mix(mask_buf[k], m);
|
||||
}
|
||||
|
||||
if(p->inv) {
|
||||
k = xei - abs_x;
|
||||
if(k > len) k= len;
|
||||
if(k >= 0)
|
||||
{
|
||||
memset(&mask_buf[0], 0x00, k);
|
||||
}
|
||||
} else {
|
||||
k++;
|
||||
if(k < len && k >= 0) {
|
||||
memset(&mask_buf[k], 0x00, len - k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void line_mask_steep(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, lv_mask_line_param_t * p)
|
||||
{
|
||||
int32_t k;
|
||||
lv_coord_t x_at_y;
|
||||
/* At the beginning of the mask if the limit line is greater then the mask's y.
|
||||
* Then the mask is in the "wrong" area*/
|
||||
x_at_y = (int32_t)((int32_t)p->steep * abs_y) >> 10;
|
||||
if(x_at_y < abs_x) {
|
||||
if(p->inv) {
|
||||
return;
|
||||
} else {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* At the end of the mask if the limit line is smaller then the mask's y.
|
||||
* Then the mask is in the "good" area*/
|
||||
x_at_y = (int32_t)((int32_t)p->steep * (abs_y)) >> 10;
|
||||
if(x_at_y > abs_x + len) {
|
||||
if(p->inv) {
|
||||
memset(mask_buf, 0x00, len);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t xe = ((abs_y << 8) * p->steep) >> 10;
|
||||
int32_t xei = xe >> 8;
|
||||
int32_t xef = xe & 0xFF;
|
||||
|
||||
int32_t xq = (((abs_y + 1) << 8) * p->steep) >> 10;
|
||||
int32_t xqi = xq >> 8;
|
||||
int32_t xqf = xq & 0xFF;
|
||||
|
||||
lv_opa_t m;
|
||||
|
||||
k = xei - abs_x;
|
||||
if(xei != xqi && (p->steep < 0 && xef == 0)) {
|
||||
xef = 0xFF;
|
||||
xei = xqi;
|
||||
k--;
|
||||
}
|
||||
|
||||
if(xei == xqi) {
|
||||
if(k >= 0 && k < len) {
|
||||
m = (xef + xqf) >> 1;
|
||||
if(p->inv) m = 255 - m;
|
||||
mask_buf[k] = mask_mix(mask_buf[k], m);
|
||||
}
|
||||
k++;
|
||||
|
||||
if(p->inv) {
|
||||
k = xei - abs_x;
|
||||
if(k > len) k= len;
|
||||
if(k >= 0) memset(&mask_buf[0], 0x00, k);
|
||||
|
||||
} else {
|
||||
if(k >= 0 && k < len ) memset(&mask_buf[k] ,0x00, len - (k));
|
||||
}
|
||||
|
||||
} else {
|
||||
int32_t y_inters;
|
||||
if(p->steep < 0) {
|
||||
y_inters = (xef << 10) / (-p->steep);
|
||||
if(k >= 0 && k < len ) {
|
||||
m = (y_inters * xef) >> 9;
|
||||
if(p->inv) m = 255 - m;
|
||||
mask_buf[k] = mask_mix(mask_buf[k], m);
|
||||
}
|
||||
k--;
|
||||
|
||||
int32_t x_inters = ((255-y_inters) * (-p->steep)) >> 10;
|
||||
|
||||
if(k >= 0 && k < len ) {
|
||||
m = 255-(((255-y_inters) * x_inters) >> 9);
|
||||
if(p->inv) mask_buf[k] = 255 - mask_buf[k];
|
||||
}
|
||||
|
||||
k+=2;
|
||||
|
||||
if(p->inv) {
|
||||
k = xei - abs_x - 1;
|
||||
|
||||
if(k > len) k= len;
|
||||
if(k >= 0) memset(&mask_buf[0], 0x00, k);
|
||||
|
||||
} else {
|
||||
if(k >= 0 && k < len ) memset(&mask_buf[k] ,0x00, len - (k));
|
||||
}
|
||||
|
||||
} else {
|
||||
y_inters = ((255-xef) << 10) / p->steep;
|
||||
if(k >= 0 && k < len ) {
|
||||
m = 255 - ((y_inters * (255-xef)) >> 9);
|
||||
if(p->inv) m = 255 - m;
|
||||
mask_buf[k] = mask_mix(mask_buf[k], m);
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
int32_t x_inters = ((255-y_inters) * p->steep) >> 10;
|
||||
if(k >= 0 && k < len ) {
|
||||
m = ((255-y_inters) * x_inters) >> 9;
|
||||
if(p->inv) m = 255 - m;
|
||||
mask_buf[k] = mask_mix(mask_buf[k], m);
|
||||
}
|
||||
k++;
|
||||
|
||||
if(p->inv) {
|
||||
k = xei - abs_x;
|
||||
if(k > len) k= len;
|
||||
if(k >= 0) memset(&mask_buf[0], 0x00, k);
|
||||
|
||||
} else {
|
||||
if(k >= 0 && k < len ) memset(&mask_buf[k] ,0x00, len - (k));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static lv_opa_t mask_mix(lv_opa_t mask_act, lv_opa_t mask_new)
|
||||
{
|
||||
if(mask_new > LV_OPA_MAX) return mask_act;
|
||||
if(mask_new < LV_OPA_MIN) return 0;
|
||||
|
||||
return (uint16_t)((uint16_t) (mask_act * mask_new) >> 8);
|
||||
|
||||
}
|
||||
|
@ -24,17 +24,36 @@ extern "C" {
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
enum {
|
||||
LV_LINE_MASK_SIDE_LEFT = 0,
|
||||
LV_LINE_MASK_SIDE_RIGHT,
|
||||
LV_LINE_MASK_SIDE_TOP,
|
||||
LV_LINE_MASK_SIDE_BOTTOM,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_line_mask_side_t;
|
||||
|
||||
typedef struct {
|
||||
lv_point_t origo;
|
||||
lv_coord_t steep;
|
||||
uint8_t flat :1;
|
||||
lv_line_mask_side_t side :2;
|
||||
uint8_t inv:1;
|
||||
}lv_mask_line_param_t;
|
||||
|
||||
typedef struct {
|
||||
lv_area_t rect;
|
||||
lv_coord_t radius;
|
||||
}lv_mask_radius_param_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_mask_apply(lv_color_t * dest_buf, lv_color_t * src_buf, lv_opa_t * mask_buf, lv_coord_t len);
|
||||
void lv_mask_line_left(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, bool inner, void * param);
|
||||
|
||||
void lv_mask_line_points_init(lv_mask_line_param_t * p, lv_coord_t p1x, lv_coord_t p1y, lv_coord_t p2x, lv_coord_t p2y, lv_line_mask_side_t side);
|
||||
void lv_mask_line_angle_init(lv_mask_line_param_t * p, lv_coord_t p1x, lv_coord_t p1y, int16_t deg, lv_line_mask_side_t side);
|
||||
void lv_mask_line(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t len, void * param);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
Loading…
x
Reference in New Issue
Block a user