fix(draw): fix triangle drawing in SW render

This commit is contained in:
Gabor Kiss-Vamosi
2023-10-26 21:59:28 +02:00
parent b6fc8d7f62
commit ff98cbd628
+46 -48
View File
@@ -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*/