mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13:00 +08:00
line mask: support all direction and inversion
This commit is contained in:
parent
9b91dc057e
commit
b1d4d6faef
@ -20,6 +20,77 @@
|
|||||||
* TYPEDEFS
|
* 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
|
typedef struct
|
||||||
{
|
{
|
||||||
lv_point_t p1;
|
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_color_t line_buf[LV_HOR_RES_MAX];
|
||||||
lv_opa_t mask_buf[LV_HOR_RES_MAX];
|
lv_opa_t mask_buf[LV_HOR_RES_MAX];
|
||||||
lv_mask_line_param_t line_mask_param;
|
lv_mask_line_param_t line_mask_param1;
|
||||||
line_mask_param.origo.x = 0;
|
// lv_mask_line_points_init(&line_mask_param1, 10, 0, 100, 200, LV_LINE_MASK_SIDE_RIGHT);
|
||||||
line_mask_param.origo.y = 0;
|
lv_mask_line_angle_init(&line_mask_param1, 50, 1, -20, LV_LINE_MASK_SIDE_RIGHT);
|
||||||
line_mask_param.steep = 987;
|
|
||||||
line_mask_param.flat = 1;
|
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*/
|
/*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) {
|
if(style->body.main_color.full != style->body.grad_color.full) {
|
||||||
memset(mask_buf, LV_OPA_COVER, draw_a_width);
|
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);
|
lv_mask_apply(&vdb_buf_tmp[draw_rel_a.x1], line_buf, mask_buf, draw_a_width);
|
||||||
} else {
|
} else {
|
||||||
memcpy(&vdb_buf_tmp[draw_rel_a.x1], line_buf, draw_a_width * sizeof(lv_color_t));
|
memcpy(&vdb_buf_tmp[draw_rel_a.x1], line_buf, draw_a_width * sizeof(lv_color_t));
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
* INCLUDES
|
* INCLUDES
|
||||||
*********************/
|
*********************/
|
||||||
#include "lv_mask.h"
|
#include "lv_mask.h"
|
||||||
|
#include "../lv_misc/lv_math.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@ -19,6 +20,10 @@
|
|||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* 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
|
* 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;
|
lv_mask_line_param_t * p = (lv_mask_line_param_t *)param;
|
||||||
|
|
||||||
/*make to points absolute to the origo*/
|
/*Make to points relative to the origo*/
|
||||||
abs_x -= p->origo.x;
|
|
||||||
abs_y -= p->origo.y;
|
abs_y -= p->origo.y;
|
||||||
|
abs_x -= p->origo.x;
|
||||||
|
|
||||||
if(p->flat) {
|
/*Handle special cases*/
|
||||||
lv_coord_t y_at_x;
|
if(p->steep == 0) {
|
||||||
|
/*Horizontal*/
|
||||||
/* At the beginning of the mask if the limit line is greater then the mask's y.
|
if(p->flat) {
|
||||||
* Then the mask is in the "wrong" area*/
|
/*Non sense: Can't be on the right/left of a horizontal line*/
|
||||||
y_at_x = (int32_t)((int32_t)p->steep * abs_x) >> 10;
|
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;
|
||||||
if(p->steep > 0) {
|
else if(p->side == LV_LINE_MASK_SIDE_BOTTOM && abs_y > p->origo.y) return;
|
||||||
if(y_at_x > abs_y) {
|
else {
|
||||||
memset(mask_buf, 0x00, len);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(y_at_x < abs_y) {
|
|
||||||
memset(mask_buf, 0x00, len);
|
memset(mask_buf, 0x00, len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*Vertical*/
|
||||||
/* At the end of the mask if the limit line is smaller then the mask's y.
|
else {
|
||||||
* Then the mask is in the "good" area*/
|
/*Non sense: Can't be on the top/bottom of a vertical line*/
|
||||||
y_at_x = (int32_t)((int32_t)p->steep * (abs_x + len)) >> 10;
|
if(p->side == LV_LINE_MASK_SIDE_TOP || p->side == LV_LINE_MASK_SIDE_BOTTOM) return;
|
||||||
if(p->steep > 0) {
|
else if(p->side == LV_LINE_MASK_SIDE_RIGHT && abs_x > 0) return;
|
||||||
if(y_at_x < abs_y) {
|
else if(p->side == LV_LINE_MASK_SIDE_LEFT) {
|
||||||
return;
|
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 {
|
else {
|
||||||
if(y_at_x > abs_y) {
|
memset(mask_buf, 0x00, len);
|
||||||
return;
|
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 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
|
* 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 {
|
typedef struct {
|
||||||
lv_point_t origo;
|
lv_point_t origo;
|
||||||
lv_coord_t steep;
|
lv_coord_t steep;
|
||||||
uint8_t flat :1;
|
uint8_t flat :1;
|
||||||
|
lv_line_mask_side_t side :2;
|
||||||
|
uint8_t inv:1;
|
||||||
}lv_mask_line_param_t;
|
}lv_mask_line_param_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
lv_area_t rect;
|
||||||
|
lv_coord_t radius;
|
||||||
|
}lv_mask_radius_param_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL PROTOTYPES
|
* 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_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
|
* MACROS
|
||||||
|
Loading…
x
Reference in New Issue
Block a user