mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-28 22:30:49 +08:00
fix(draw): fix triangle drawing in SW render
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
static void point_swap(lv_point_t * p1, lv_point_t * p2);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
@@ -56,67 +57,57 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_
|
|||||||
if(!is_common) return;
|
if(!is_common) return;
|
||||||
|
|
||||||
lv_point_t p[3];
|
lv_point_t p[3];
|
||||||
p[0] = dsc->p[0];
|
/*If there is a vertical side use it as p[0] and p[1]*/
|
||||||
p[1] = dsc->p[1];
|
if(dsc->p[0].x == dsc->p[1].x) {
|
||||||
p[2] = dsc->p[2];
|
p[0] = dsc->p[0];
|
||||||
|
|
||||||
/*Order the points like this:
|
|
||||||
* [0]: left bottom
|
|
||||||
* [1]: top
|
|
||||||
* [2]: right bottom*/
|
|
||||||
|
|
||||||
|
|
||||||
if(dsc->p[0].y <= dsc->p[1].y && dsc->p[0].y <= dsc->p[2].y) {
|
|
||||||
p[1] = dsc->p[0];
|
|
||||||
if(dsc->p[1].x < dsc->p[2].x) {
|
|
||||||
p[0] = dsc->p[1];
|
|
||||||
p[2] = dsc->p[2];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p[0] = dsc->p[2];
|
|
||||||
p[2] = dsc->p[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(dsc->p[1].y <= dsc->p[0].y && dsc->p[1].y <= dsc->p[2].y) {
|
|
||||||
p[1] = dsc->p[1];
|
p[1] = dsc->p[1];
|
||||||
if(dsc->p[0].x < dsc->p[2].x) {
|
p[2] = dsc->p[2];
|
||||||
p[0] = dsc->p[0];
|
}
|
||||||
p[2] = dsc->p[2];
|
else if(dsc->p[0].x == dsc->p[2].x) {
|
||||||
}
|
p[0] = dsc->p[0];
|
||||||
else {
|
p[1] = dsc->p[2];
|
||||||
p[0] = dsc->p[2];
|
p[2] = dsc->p[1];
|
||||||
p[2] = dsc->p[0];
|
}
|
||||||
}
|
else if(dsc->p[1].x == dsc->p[2].x) {
|
||||||
|
p[0] = dsc->p[1];
|
||||||
|
p[1] = dsc->p[2];
|
||||||
|
p[2] = dsc->p[0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p[1] = dsc->p[2];
|
p[0] = dsc->p[0];
|
||||||
if(dsc->p[0].x < dsc->p[1].x) {
|
p[1] = dsc->p[1];
|
||||||
p[0] = dsc->p[0];
|
p[2] = dsc->p[2];
|
||||||
p[2] = dsc->p[1];
|
|
||||||
}
|
/*Set the smallest y as p[0]*/
|
||||||
else {
|
if(p[0].y > p[1].y) point_swap(&p[0], &p[1]);
|
||||||
p[0] = dsc->p[1];
|
if(p[0].y > p[2].y) point_swap(&p[0], &p[2]);
|
||||||
p[2] = dsc->p[0];
|
|
||||||
}
|
/*Set the greatest y as p[1]*/
|
||||||
|
if(p[1].y < p[2].y) point_swap(&p[1], &p[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Be sure p[0] is on the top*/
|
||||||
|
if(p[0].y > p[1].y) point_swap(&p[0], &p[1]);
|
||||||
|
|
||||||
|
/*If right == true p[2] is on the right side of the p[0] p[1] line*/
|
||||||
|
bool right = ((p[1].x - p[0].x) * (p[2].y - p[0].y) - (p[1].y - p[0].y) * (p[2].x - p[0].x)) < 0;
|
||||||
|
|
||||||
void * masks[4] = {0};
|
void * masks[4] = {0};
|
||||||
lv_draw_sw_mask_line_param_t mask_left;
|
lv_draw_sw_mask_line_param_t mask_left;
|
||||||
lv_draw_sw_mask_line_param_t mask_right;
|
lv_draw_sw_mask_line_param_t mask_right;
|
||||||
lv_draw_sw_mask_line_param_t mask_bottom;
|
lv_draw_sw_mask_line_param_t mask_bottom;
|
||||||
|
|
||||||
|
lv_draw_sw_mask_line_points_init(&mask_left, p[0].x, p[0].y,
|
||||||
|
p[1].x, p[1].y,
|
||||||
|
right ? LV_DRAW_SW_MASK_LINE_SIDE_RIGHT : LV_DRAW_SW_MASK_LINE_SIDE_LEFT);
|
||||||
|
|
||||||
lv_draw_sw_mask_line_points_init(&mask_left, p[1].x, p[1].y,
|
lv_draw_sw_mask_line_points_init(&mask_right, p[0].x, p[0].y,
|
||||||
p[0].x, p[0].y,
|
|
||||||
LV_DRAW_SW_MASK_LINE_SIDE_RIGHT);
|
|
||||||
|
|
||||||
lv_draw_sw_mask_line_points_init(&mask_right, p[1].x, p[1].y,
|
|
||||||
p[2].x, p[2].y,
|
p[2].x, p[2].y,
|
||||||
LV_DRAW_SW_MASK_LINE_SIDE_LEFT);
|
right ? LV_DRAW_SW_MASK_LINE_SIDE_LEFT : LV_DRAW_SW_MASK_LINE_SIDE_RIGHT);
|
||||||
|
|
||||||
lv_draw_sw_mask_line_points_init(&mask_bottom, p[0].x, p[0].y,
|
lv_draw_sw_mask_line_points_init(&mask_bottom, p[1].x, p[1].y,
|
||||||
p[2].x, p[2].y,
|
p[2].x, p[2].y,
|
||||||
LV_DRAW_SW_MASK_LINE_SIDE_TOP);
|
right ? LV_DRAW_SW_MASK_LINE_SIDE_LEFT : LV_DRAW_SW_MASK_LINE_SIDE_RIGHT);
|
||||||
|
|
||||||
masks[0] = &mask_left;
|
masks[0] = &mask_left;
|
||||||
masks[1] = &mask_right;
|
masks[1] = &mask_right;
|
||||||
@@ -135,7 +126,6 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_
|
|||||||
blend_dsc.blend_mode = LV_BLEND_MODE_NORMAL;
|
blend_dsc.blend_mode = LV_BLEND_MODE_NORMAL;
|
||||||
blend_dsc.src_buf = NULL;
|
blend_dsc.src_buf = NULL;
|
||||||
|
|
||||||
|
|
||||||
lv_grad_dir_t grad_dir = dsc->bg_grad.dir;
|
lv_grad_dir_t grad_dir = dsc->bg_grad.dir;
|
||||||
|
|
||||||
lv_grad_t * grad = lv_gradient_get(&dsc->bg_grad, lv_area_get_width(&tri_area), lv_area_get_height(&tri_area));
|
lv_grad_t * grad = lv_gradient_get(&dsc->bg_grad, lv_area_get_width(&tri_area), lv_area_get_height(&tri_area));
|
||||||
@@ -201,4 +191,12 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_
|
|||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
static void point_swap(lv_point_t * p1, lv_point_t * p2)
|
||||||
|
{
|
||||||
|
lv_point_t tmp = *p1;
|
||||||
|
*p1 = *p2;
|
||||||
|
*p2 = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /*LV_USE_DRAW_SW*/
|
#endif /*LV_USE_DRAW_SW*/
|
||||||
|
|||||||
Reference in New Issue
Block a user