move antialiasing and refr_task to the display level

This commit is contained in:
Gabor Kiss-Vamosi
2019-03-30 06:03:23 +01:00
parent 438ae64502
commit eb6daa51d7
14 changed files with 593 additions and 502 deletions

View File

@@ -112,6 +112,24 @@ void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)
lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr);
}
/**
* Get the a pointer to the screen refresher task.
* It's parameters can be modified with `lv_task_...` functions,
* @param disp pointer to a display
* @return pointer to the display refresher task. (NULL on error)
*/
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp)
{
if(!disp) disp = lv_disp_get_default();
if(!disp) {
LV_LOG_WARN("lv_disp_get_refr_task: no display registered to get its top layer");
return NULL;
}
return disp->refr_task;
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@@ -62,6 +62,14 @@ lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);
*/
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
/**
* Get the a pointer to the screen refresher task.
* It's parameters can be modified with `lv_task_...` functions,
* @param disp pointer to a display
* @return pointer to the display refresher task. (NULL on error)
*/
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp) ;
/*------------------------------------------------
* To improve backward compatibility
* Recommended only if you have one display

View File

@@ -35,7 +35,7 @@ extern "C" {
/*Error check of lv_conf.h*/
#if LV_HOR_RES_MAX == 0 || LV_VER_RES_MAX == 0
#error "LittlevGL: LV_HOR_RES and LV_VER_RES must be greater than 0"
#error "LittlevGL: LV_HOR_RES_MAX and LV_VER_RES_MAX must be greater than 0"
#endif
#if LV_ANTIALIAS > 1

View File

@@ -30,7 +30,6 @@
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_refr_task(void * param);
static void lv_refr_join_area(void);
static void lv_refr_areas(void);
static void lv_refr_area(const lv_area_t * area_p);
@@ -59,9 +58,7 @@ static lv_disp_t * disp_refr; /*Display being refreshed*/
*/
void lv_refr_init(void)
{
lv_task_t * task;
task = lv_task_create(lv_refr_task, LV_REFR_PERIOD, LV_TASK_PRIO_MID, NULL);
lv_task_ready(task); /*Be sure the screen will be refreshed immediately on start up*/
/*Nothing to do*/
}
/**
@@ -72,7 +69,7 @@ void lv_refr_init(void)
*/
void lv_refr_now(void)
{
lv_refr_task(NULL);
lv_disp_refr_task(NULL);
}
@@ -133,77 +130,72 @@ lv_disp_t * lv_refr_get_disp_refreshing(void)
return disp_refr;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Called periodically to handle the refreshing
* @param param unused
* @param param point to a `lv_disp_t` to refresh
*/
static void lv_refr_task(void * param)
void lv_disp_refr_task(void * param)
{
(void)param;
LV_LOG_TRACE("lv_refr_task: started");
uint32_t start = lv_tick_get();
LV_LL_READ(LV_GC_ROOT(_lv_disp_ll), disp_refr) {
LV_LOG_TRACE("lv_refr_task: refreshing a display");
disp_refr = param;
lv_refr_join_area();
lv_refr_join_area();
lv_refr_areas();
lv_refr_areas();
/*If refresh happened ...*/
if(disp_refr->inv_p != 0) {
/*In true double buffered mode copy the refreshed areas to the new VDB to keep it up to date*/
if(lv_disp_is_true_double_buf(disp_refr)) {
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
/*If refresh happened ...*/
if(disp_refr->inv_p != 0) {
/*In true double buffered mode copy the refreshed areas to the new VDB to keep it up to date*/
if(lv_disp_is_true_double_buf(disp_refr)) {
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
/*Flush the content of the VDB*/
lv_refr_vdb_flush();
/*Flush the content of the VDB*/
lv_refr_vdb_flush();
/* With true double buffering the flushing should be only the address change of the current frame buffer.
* Wait until the address change is ready and copy the changed content to the other frame buffer (new active VDB)
* to keep the buffers synchronized*/
while(vdb->flushing);
/* With true double buffering the flushing should be only the address change of the current frame buffer.
* Wait until the address change is ready and copy the changed content to the other frame buffer (new active VDB)
* to keep the buffers synchronized*/
while(vdb->flushing);
uint8_t * buf_act = (uint8_t *) vdb->buf_act;
uint8_t * buf_ina = (uint8_t *) vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
uint8_t * buf_act = (uint8_t *) vdb->buf_act;
uint8_t * buf_ina = (uint8_t *) vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
uint16_t a;
for(a = 0; a < disp_refr->inv_p; a++) {
if(disp_refr->inv_area_joined[a] == 0) {
lv_coord_t y;
uint32_t start_offs = (hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
uint16_t a;
for(a = 0; a < disp_refr->inv_p; a++) {
if(disp_refr->inv_area_joined[a] == 0) {
lv_coord_t y;
uint32_t start_offs = (hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);
start_offs += hres * sizeof(lv_color_t);
}
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);
start_offs += hres * sizeof(lv_color_t);
}
}
} /*End of true double buffer handling*/
/*Clean up*/
memset(disp_refr->inv_areas, 0, sizeof(disp_refr->inv_areas));
memset(disp_refr->inv_area_joined, 0, sizeof(disp_refr->inv_area_joined));
disp_refr->inv_p = 0;
/*Call monitor cb if present*/
if(disp_refr->driver.monitor_cb) {
disp_refr->driver.monitor_cb(&disp_refr->driver, lv_tick_elaps(start), px_num);
}
} /*End of true double buffer handling*/
/*Clean up*/
memset(disp_refr->inv_areas, 0, sizeof(disp_refr->inv_areas));
memset(disp_refr->inv_area_joined, 0, sizeof(disp_refr->inv_area_joined));
disp_refr->inv_p = 0;
/*Call monitor cb if present*/
if(disp_refr->driver.monitor_cb) {
disp_refr->driver.monitor_cb(&disp_refr->driver, lv_tick_elaps(start), px_num);
}
}
LV_LOG_TRACE("lv_refr_task: ready");
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Join the areas which has got common parts

View File

@@ -66,6 +66,12 @@ void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);
*/
lv_disp_t * lv_refr_get_disp_refreshing(void);
/**
* Called periodically to handle the refreshing
* @param param point to a `lv_disp_t` to refresh
*/
void lv_disp_refr_task(void * param);
/**********************
* STATIC FUNCTIONS
**********************/

View File

@@ -40,7 +40,7 @@
* STATIC FUNCTIONS
**********************/
#if LV_ANTIALIAS != 0
#if LV_ANTIALIAS
/**
* Get the opacity of a pixel based it's position in a line segment

View File

@@ -51,7 +51,7 @@ typedef uint8_t lv_img_src_t;
* GLOBAL PROTOTYPES
**********************/
#if LV_ANTIALIAS != 0
#if LV_ANTIALIAS
/**
* Get the opacity of a pixel based it's position in a line segment

View File

@@ -9,6 +9,7 @@
#include <stdio.h>
#include <stdbool.h>
#include "lv_draw.h"
#include "../lv_core/lv_refr.h"
#include "../lv_misc/lv_math.h"
/*********************
@@ -129,38 +130,41 @@ void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv
else {
bool dir_ori = false;
#if LV_ANTIALIAS
lv_point_t p_tmp;
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
if(aa) {
lv_point_t p_tmp;
if(main_line.hor) {
if(main_line.p1.y < main_line.p2.y) {
dir_ori = true;
p_tmp.x = main_line.p2.x;
p_tmp.y = main_line.p2.y - 1;
line_init(&main_line, &p1, &p_tmp);
main_line.sy = LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
if(main_line.hor) {
if(main_line.p1.y < main_line.p2.y) {
dir_ori = true;
p_tmp.x = main_line.p2.x;
p_tmp.y = main_line.p2.y - 1;
line_init(&main_line, &p1, &p_tmp);
main_line.sy = LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
}
else if(main_line.p1.y > main_line.p2.y) {
dir_ori = false;
p_tmp.x = main_line.p2.x;
p_tmp.y = main_line.p2.y + 1;
line_init(&main_line, &p1, &p_tmp);
main_line.sy = -LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
}
}
else if(main_line.p1.y > main_line.p2.y) {
dir_ori = false;
p_tmp.x = main_line.p2.x;
p_tmp.y = main_line.p2.y + 1;
line_init(&main_line, &p1, &p_tmp);
main_line.sy = -LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
}
}
else {
if(main_line.p1.x < main_line.p2.x) {
dir_ori = true;
p_tmp.x = main_line.p2.x - 1;
p_tmp.y = main_line.p2.y;
line_init(&main_line, &p1, &p_tmp);
main_line.sx = LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
}
else if(main_line.p1.x > main_line.p2.x) {
dir_ori = false;
p_tmp.x = main_line.p2.x + 1;
p_tmp.y = main_line.p2.y;
line_init(&main_line, &p1, &p_tmp);
main_line.sx = -LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
else {
if(main_line.p1.x < main_line.p2.x) {
dir_ori = true;
p_tmp.x = main_line.p2.x - 1;
p_tmp.y = main_line.p2.y;
line_init(&main_line, &p1, &p_tmp);
main_line.sx = LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
}
else if(main_line.p1.x > main_line.p2.x) {
dir_ori = false;
p_tmp.x = main_line.p2.x + 1;
p_tmp.y = main_line.p2.y;
line_init(&main_line, &p1, &p_tmp);
main_line.sx = -LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
}
}
}
#endif
@@ -202,7 +206,6 @@ static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const
lv_coord_t width_1 = width & 0x1;
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t) style->line.opa * opa_scale) >> 8;
lv_area_t act_area;
act_area.x1 = main_line->p1.x - width_half;
act_area.x2 = main_line->p2.x + width_half + width_1;
@@ -221,7 +224,7 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
{
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t) style->line.opa * opa_scale) >> 8;
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
lv_point_t vect_main, vect_norm;
vect_main.x = main_line->p2.x - main_line->p1.x;
vect_main.y = main_line->p2.y - main_line->p1.y;
@@ -278,7 +281,7 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
if(sqr >= width_sqr) {
width = i;
#if LV_ANTIALIAS
width--;
if(aa) width--;
#endif
break;
}
@@ -288,11 +291,13 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
}
#if LV_ANTIALIAS
lv_coord_t width_safe = width;
if(width == 0) width_safe = 1;
lv_coord_t aa_last_corner;
aa_last_corner = 0;
lv_coord_t width_safe = width;
if(aa) {
if(width == 0) width_safe = 1;
aa_last_corner = 0;
}
#endif
lv_coord_t x_center_ofs = 0;
@@ -312,54 +317,54 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
pattern[i].x -= x_center_ofs;
pattern[i].y -= y_center_ofs;
#if LV_ANTIALIAS
if(i != 0) {
if(main_line->hor) {
if(pattern[i - 1].x != pattern[i].x) {
lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y;
if(main_line->sy < 0) {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1,
seg_w, mask, style->line.color, opa);
if(aa) {
if(i != 0) {
if(main_line->hor) {
if(pattern[i - 1].x != pattern[i].x) {
lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y;
if(main_line->sy < 0) {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1,
seg_w, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1,
-seg_w, mask, style->line.color, opa);
} else {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y,
seg_w, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1,
-seg_w, mask, style->line.color, opa);
} else {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y,
seg_w, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y,
-seg_w, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y,
-seg_w, mask, style->line.color, opa);
}
aa_last_corner = i;
}
aa_last_corner = i;
}
} else {
if(pattern[i - 1].y != pattern[i].y) {
lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x;
if(main_line->sx < 0) {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w, mask, style->line.color, opa);
} else {
if(pattern[i - 1].y != pattern[i].y) {
lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x;
if(main_line->sx < 0) {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p2.y + pattern[aa_last_corner].y + 1,
-seg_w, mask, style->line.color, opa);
} else {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p2.y + pattern[aa_last_corner].y + 1,
-seg_w, mask, style->line.color, opa);
} else {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1,
-seg_w, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1,
-seg_w, mask, style->line.color, opa);
}
aa_last_corner = i;
}
aa_last_corner = i;
}
}
}
#endif
}
#if LV_ANTIALIAS
/*Add the last part of anti-aliasing for the perpendicular ending*/
if(width != 0) { /*Due to rounding error with very thin lines it looks ugly*/
if(width != 0 && aa) { /*Due to rounding error with very thin lines it looks ugly*/
if(main_line->hor) {
lv_coord_t seg_w = pattern[width_safe - 1].y - pattern[aa_last_corner].y;
if(main_line->sy < 0) {
@@ -402,25 +407,25 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
/*Shift the anti aliasing on the edges (-1, 1 or 0 (zero only in case width == 0))*/
lv_coord_t aa_shift1;
lv_coord_t aa_shift2;
if(main_line->hor == false) {
if(main_line->sx < 0) {
aa_shift1 = -1;
aa_shift2 = width == 0 ? 0 : aa_shift1;
if(aa) {
if(main_line->hor == false) {
if(main_line->sx < 0) {
aa_shift1 = -1;
aa_shift2 = width == 0 ? 0 : aa_shift1;
} else {
aa_shift2 = 1;
aa_shift1 = width == 0 ? 0 : aa_shift2;
}
} else {
aa_shift2 = 1;
aa_shift1 = width == 0 ? 0 : aa_shift2;
}
} else {
if(main_line->sy < 0) {
aa_shift1 = -1;
aa_shift2 = width == 0 ? 0 : aa_shift1;
} else {
aa_shift2 = 1;
aa_shift1 = width == 0 ? 0 : aa_shift2;
if(main_line->sy < 0) {
aa_shift1 = -1;
aa_shift2 = width == 0 ? 0 : aa_shift1;
} else {
aa_shift2 = 1;
aa_shift1 = width == 0 ? 0 : aa_shift2;
}
}
}
#endif
volatile lv_point_t prev_p;
@@ -446,10 +451,12 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
}
#if LV_ANTIALIAS
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
main_line->p_act.x - prev_p.x, mask, style->line.color, opa);
if(aa) {
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
main_line->p_act.x - prev_p.x, mask, style->line.color, opa);
}
#endif
first_run = false;
@@ -473,10 +480,12 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
}
#if LV_ANTIALIAS
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
if(aa) {
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
}
#endif
}
/*Rather a vertical line*/
@@ -500,10 +509,12 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
}
#if LV_ANTIALIAS
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
main_line->p_act.y - prev_p.y, mask, style->line.color, opa);
if(aa) {
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
main_line->p_act.y - prev_p.y, mask, style->line.color, opa);
}
#endif
first_run = false;
@@ -529,10 +540,12 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
}
#if LV_ANTIALIAS
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
if(aa) {
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
}
#endif
}
}

View File

@@ -9,6 +9,7 @@
#include "lv_draw_rect.h"
#include "../lv_misc/lv_circ.h"
#include "../lv_misc/lv_math.h"
#include "../lv_core/lv_refr.h"
/*********************
* DEFINES
@@ -102,6 +103,7 @@ void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_sty
static void lv_draw_rect_main_mid(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
{
uint16_t radius = style->body.radius;
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
lv_color_t mcolor = style->body.main_color;
lv_color_t gcolor = style->body.grad_color;
@@ -124,13 +126,14 @@ static void lv_draw_rect_main_mid(const lv_area_t * coords, const lv_area_t * ma
work_area.y2 = coords->y2 - radius;
if(style->body.radius != 0) {
#if LV_ANTIALIAS
work_area.y1 += 2;
work_area.y2 -= 2;
#else
work_area.y1 += 1;
work_area.y2 -= 1;
#endif
if(aa) {
work_area.y1 += 2;
work_area.y2 -= 2;
} else {
work_area.y1 += 1;
work_area.y2 -= 1;
}
}
lv_draw_fill(&work_area, mask, mcolor, opa);
@@ -141,13 +144,13 @@ static void lv_draw_rect_main_mid(const lv_area_t * coords, const lv_area_t * ma
lv_color_t act_color;
if(style->body.radius != 0) {
#if LV_ANTIALIAS
row_start += 2;
row_end -= 2;
#else
row_start += 1;
row_end -= 1;
#endif
if(aa) {
row_start += 2;
row_end -= 2;
} else {
row_start += 1;
row_end -= 1;
}
}
if(row_start < 0) row_start = 0;
@@ -171,6 +174,7 @@ static void lv_draw_rect_main_mid(const lv_area_t * coords, const lv_area_t * ma
static void lv_draw_rect_main_corner(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
{
uint16_t radius = style->body.radius;
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
lv_color_t mcolor = style->body.main_color;
lv_color_t gcolor = style->body.grad_color;
@@ -187,17 +191,17 @@ static void lv_draw_rect_main_corner(const lv_area_t * coords, const lv_area_t *
lv_point_t rt_origo; /*Right Top origo*/
lv_point_t rb_origo; /*Left Bottom origo*/
lt_origo.x = coords->x1 + radius + LV_ANTIALIAS;
lt_origo.y = coords->y1 + radius + LV_ANTIALIAS;
lt_origo.x = coords->x1 + radius + aa;
lt_origo.y = coords->y1 + radius + aa;
lb_origo.x = coords->x1 + radius + LV_ANTIALIAS;
lb_origo.y = coords->y2 - radius - LV_ANTIALIAS;
lb_origo.x = coords->x1 + radius + aa;
lb_origo.y = coords->y2 - radius - aa;
rt_origo.x = coords->x2 - radius - LV_ANTIALIAS;
rt_origo.y = coords->y1 + radius + LV_ANTIALIAS;
rt_origo.x = coords->x2 - radius - aa;
rt_origo.y = coords->y1 + radius + aa;
rb_origo.x = coords->x2 - radius - LV_ANTIALIAS;
rb_origo.y = coords->y2 - radius - LV_ANTIALIAS;
rb_origo.x = coords->x2 - radius - aa;
rb_origo.y = coords->y2 - radius - aa;
lv_area_t edge_top_area;
lv_area_t mid_top_area;
@@ -229,57 +233,59 @@ static void lv_draw_rect_main_corner(const lv_area_t * coords, const lv_area_t *
rt_origo.x + LV_CIRC_OCT7_X(cir),
rt_origo.y + LV_CIRC_OCT7_Y(cir));
#if LV_ANTIALIAS
/*Store some internal states for anti-aliasing*/
lv_coord_t out_y_seg_start = 0;
lv_coord_t out_y_seg_end = 0;
lv_coord_t out_x_last = radius;
/*Store some internal states for anti-aliasing*/
lv_coord_t out_y_seg_start = 0;
lv_coord_t out_y_seg_end = 0;
lv_coord_t out_x_last = radius;
lv_color_t aa_color_hor_top;
lv_color_t aa_color_hor_bottom;
lv_color_t aa_color_ver;
lv_color_t aa_color_hor_top;
lv_color_t aa_color_hor_bottom;
lv_color_t aa_color_ver;
#endif
while(lv_circ_cont(&cir)) {
#if LV_ANTIALIAS != 0
/*New step in y on the outter circle*/
if(out_x_last != cir.x) {
out_y_seg_end = cir.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
#if LV_ANTIALIAS
if(aa) {
/*New step in y on the outter circle*/
if(out_x_last != cir.x) {
out_y_seg_end = cir.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
aa_p.x = out_x_last;
aa_p.y = out_y_seg_start;
aa_p.x = out_x_last;
aa_p.y = out_y_seg_start;
mix = (uint32_t)((uint32_t)(radius - out_x_last) * 255) / height;
aa_color_hor_top = lv_color_mix(gcolor, mcolor, mix);
aa_color_hor_bottom = lv_color_mix(mcolor, gcolor, mix);
mix = (uint32_t)((uint32_t)(radius - out_x_last) * 255) / height;
aa_color_hor_top = lv_color_mix(gcolor, mcolor, mix);
aa_color_hor_bottom = lv_color_mix(mcolor, gcolor, mix);
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa;
if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping on the first segment*/
aa_opa = antialias_get_opa_circ(seg_size, i, opa);
} else {
aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa;
if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping on the first segment*/
aa_opa = antialias_get_opa_circ(seg_size, i, opa);
} else {
aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
}
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, aa_color_hor_top, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, aa_color_hor_top, aa_opa);
mix = (uint32_t)((uint32_t)(radius - out_y_seg_start + i) * 255) / height;
aa_color_ver = lv_color_mix(mcolor, gcolor, mix);
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
aa_color_ver = lv_color_mix(gcolor, mcolor, mix);
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
}
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, aa_color_hor_top, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, aa_color_hor_top, aa_opa);
mix = (uint32_t)((uint32_t)(radius - out_y_seg_start + i) * 255) / height;
aa_color_ver = lv_color_mix(mcolor, gcolor, mix);
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
aa_color_ver = lv_color_mix(gcolor, mcolor, mix);
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
out_x_last = cir.x;
out_y_seg_start = out_y_seg_end;
}
out_x_last = cir.x;
out_y_seg_start = out_y_seg_end;
}
#endif
uint8_t edge_top_refr = 0;
@@ -395,66 +401,65 @@ static void lv_draw_rect_main_corner(const lv_area_t * coords, const lv_area_t *
#if LV_ANTIALIAS
/*The first and the last line is not drawn*/
edge_top_area.x1 = coords->x1 + radius + 2;
edge_top_area.x2 = coords->x2 - radius - 2;
edge_top_area.y1 = coords->y1;
edge_top_area.y2 = coords->y1;
lv_draw_fill(&edge_top_area, mask, style->body.main_color, opa);
if(aa) {
/*The first and the last line is not drawn*/
edge_top_area.x1 = coords->x1 + radius + 2;
edge_top_area.x2 = coords->x2 - radius - 2;
edge_top_area.y1 = coords->y1;
edge_top_area.y2 = coords->y1;
lv_draw_fill(&edge_top_area, mask, style->body.main_color, opa);
edge_top_area.y1 = coords->y2;
edge_top_area.y2 = coords->y2;
lv_draw_fill(&edge_top_area, mask, style->body.grad_color, opa);
edge_top_area.y1 = coords->y2;
edge_top_area.y2 = coords->y2;
lv_draw_fill(&edge_top_area, mask, style->body.grad_color, opa);
/*Last parts of the anti-alias*/
out_y_seg_end = cir.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
/*Last parts of the anti-alias*/
out_y_seg_end = cir.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
aa_p.x = out_x_last;
aa_p.y = out_y_seg_start;
mix = (uint32_t)((uint32_t)(radius - out_x_last) * 255) / height;
aa_color_hor_bottom = lv_color_mix(gcolor, mcolor, mix);
aa_color_hor_top = lv_color_mix(mcolor, gcolor, mix);
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, aa_color_hor_top, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, aa_color_hor_top, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, aa_color_hor_bottom, aa_opa);
mix = (uint32_t)((uint32_t)(radius - out_y_seg_start + i) * 255) / height;
aa_color_ver = lv_color_mix(mcolor, gcolor, mix);
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
aa_color_ver = lv_color_mix(gcolor, mcolor, mix);
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
}
/*In some cases the last pixel is not drawn*/
if(LV_MATH_ABS(aa_p.x - aa_p.y) == seg_size) {
aa_p.x = out_x_last;
aa_p.y = out_x_last;
aa_p.y = out_y_seg_start;
mix = (uint32_t)((uint32_t)(out_x_last) * 255) / height;
aa_color_hor_top = lv_color_mix(gcolor, mcolor, mix);
aa_color_hor_bottom = lv_color_mix(mcolor, gcolor, mix);
mix = (uint32_t)((uint32_t)(radius - out_x_last) * 255) / height;
aa_color_hor_bottom = lv_color_mix(gcolor, mcolor, mix);
aa_color_hor_top = lv_color_mix(mcolor, gcolor, mix);
lv_opa_t aa_opa = opa >> 1;
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p), rb_origo.y + LV_CIRC_OCT2_Y(aa_p), mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p), lb_origo.y + LV_CIRC_OCT4_Y(aa_p), mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p), lt_origo.y + LV_CIRC_OCT6_Y(aa_p), mask, aa_color_hor_top, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p), rt_origo.y + LV_CIRC_OCT8_Y(aa_p), mask, aa_color_hor_top, aa_opa);
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, aa_color_hor_top, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, aa_color_hor_top, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, aa_color_hor_bottom, aa_opa);
mix = (uint32_t)((uint32_t)(radius - out_y_seg_start + i) * 255) / height;
aa_color_ver = lv_color_mix(mcolor, gcolor, mix);
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, aa_color_ver, aa_opa);
aa_color_ver = lv_color_mix(gcolor, mcolor, mix);
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, aa_color_ver, aa_opa);
}
/*In some cases the last pixel is not drawn*/
if(LV_MATH_ABS(aa_p.x - aa_p.y) == seg_size) {
aa_p.x = out_x_last;
aa_p.y = out_x_last;
mix = (uint32_t)((uint32_t)(out_x_last) * 255) / height;
aa_color_hor_top = lv_color_mix(gcolor, mcolor, mix);
aa_color_hor_bottom = lv_color_mix(mcolor, gcolor, mix);
lv_opa_t aa_opa = opa >> 1;
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p), rb_origo.y + LV_CIRC_OCT2_Y(aa_p), mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p), lb_origo.y + LV_CIRC_OCT4_Y(aa_p), mask, aa_color_hor_bottom, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p), lt_origo.y + LV_CIRC_OCT6_Y(aa_p), mask, aa_color_hor_top, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p), rt_origo.y + LV_CIRC_OCT8_Y(aa_p), mask, aa_color_hor_top, aa_opa);
}
}
#endif
}
/**
@@ -467,6 +472,7 @@ static void lv_draw_rect_main_corner(const lv_area_t * coords, const lv_area_t *
static void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
{
uint16_t radius = style->body.radius;
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
lv_coord_t width = lv_area_get_width(coords);
lv_coord_t height = lv_area_get_height(coords);
@@ -484,10 +490,10 @@ static void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area
radius = lv_draw_cont_radius_corr(radius, width, height);
if(radius < bwidth) {
length_corr = bwidth - radius - LV_ANTIALIAS;
length_corr = bwidth - radius - aa;
corner_size = bwidth;
} else {
corner_size = radius + LV_ANTIALIAS;
corner_size = radius + aa;
}
/*If radius == 0 is a special case*/
@@ -576,17 +582,17 @@ static void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area
/*Left top correction*/
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
work_area.x1 = coords->x1;
work_area.x2 = coords->x1 + radius + LV_ANTIALIAS;
work_area.y1 = coords->y1 + radius + 1 + LV_ANTIALIAS;
work_area.x2 = coords->x1 + radius + aa;
work_area.y1 = coords->y1 + radius + 1 + aa;
work_area.y2 = coords->y1 + bwidth;
lv_draw_fill(&work_area, mask, color, opa);
}
/*Right top correction*/
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
work_area.x1 = coords->x2 - radius - LV_ANTIALIAS;
work_area.x1 = coords->x2 - radius - aa;
work_area.x2 = coords->x2;
work_area.y1 = coords->y1 + radius + 1 + LV_ANTIALIAS;
work_area.y1 = coords->y1 + radius + 1 + aa;
work_area.y2 = coords->y1 + bwidth;
lv_draw_fill(&work_area, mask, color, opa);
}
@@ -594,18 +600,18 @@ static void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area
/*Left bottom correction*/
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
work_area.x1 = coords->x1;
work_area.x2 = coords->x1 + radius + LV_ANTIALIAS;
work_area.x2 = coords->x1 + radius + aa;
work_area.y1 = coords->y2 - bwidth;
work_area.y2 = coords->y2 - radius - 1 - LV_ANTIALIAS;
work_area.y2 = coords->y2 - radius - 1 - aa;
lv_draw_fill(&work_area, mask, color, opa);
}
/*Right bottom correction*/
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
work_area.x1 = coords->x2 - radius - LV_ANTIALIAS;
work_area.x1 = coords->x2 - radius - aa;
work_area.x2 = coords->x2;
work_area.y1 = coords->y2 - bwidth;
work_area.y2 = coords->y2 - radius - 1 - LV_ANTIALIAS;
work_area.y2 = coords->y2 - radius - 1 - aa;
lv_draw_fill(&work_area, mask, color, opa);
}
}
@@ -615,35 +621,35 @@ static void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area
/*Left top corner*/
if(part & (LV_BORDER_TOP | LV_BORDER_LEFT)) {
work_area.x1 = coords->x1;
work_area.x2 = coords->x1 + LV_ANTIALIAS;
work_area.x2 = coords->x1 + aa;
work_area.y1 = coords->y1;
work_area.y2 = coords->y1 + LV_ANTIALIAS;
work_area.y2 = coords->y1 + aa;
lv_draw_fill(&work_area, mask, color, opa);
}
/*Right top corner*/
if(part & (LV_BORDER_TOP | LV_BORDER_RIGHT)) {
work_area.x1 = coords->x2 - LV_ANTIALIAS;
work_area.x1 = coords->x2 - aa;
work_area.x2 = coords->x2;
work_area.y1 = coords->y1;
work_area.y2 = coords->y1 + LV_ANTIALIAS;
work_area.y2 = coords->y1 + aa;
lv_draw_fill(&work_area, mask, color, opa);
}
/*Left bottom corner*/
if(part & (LV_BORDER_BOTTOM | LV_BORDER_LEFT)) {
work_area.x1 = coords->x1;
work_area.x2 = coords->x1 + LV_ANTIALIAS;
work_area.y1 = coords->y2 - LV_ANTIALIAS;
work_area.x2 = coords->x1 + aa;
work_area.y1 = coords->y2 - aa;
work_area.y2 = coords->y2;
lv_draw_fill(&work_area, mask, color, opa);
}
/*Right bottom corner*/
if(part & (LV_BORDER_BOTTOM | LV_BORDER_RIGHT)) {
work_area.x1 = coords->x2 - LV_ANTIALIAS;
work_area.x1 = coords->x2 - aa;
work_area.x2 = coords->x2;
work_area.y1 = coords->y2 - LV_ANTIALIAS;
work_area.y1 = coords->y2 - aa;
work_area.y2 = coords->y2;
lv_draw_fill(&work_area, mask, color, opa);
}
@@ -661,6 +667,7 @@ static void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area
static void lv_draw_rect_border_corner(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
{
uint16_t radius = style->body.radius ;
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
uint16_t bwidth = style->body.border.width;
lv_color_t color = style->body.border.color;
lv_border_part_t part = style->body.border.part;
@@ -669,7 +676,7 @@ static void lv_draw_rect_border_corner(const lv_area_t * coords, const lv_area_t
bwidth--;
#if LV_ANTIALIAS
bwidth--; /*Because of anti-aliasing the border seems one pixel ticker*/
if(aa) bwidth--; /*Because of anti-aliasing the border seems one pixel ticker*/
#endif
lv_coord_t width = lv_area_get_width(coords);
@@ -682,17 +689,17 @@ static void lv_draw_rect_border_corner(const lv_area_t * coords, const lv_area_t
lv_point_t rt_origo; /*Right Top origo*/
lv_point_t rb_origo; /*Left Bottom origo*/
lt_origo.x = coords->x1 + radius + LV_ANTIALIAS;
lt_origo.y = coords->y1 + radius + LV_ANTIALIAS;
lt_origo.x = coords->x1 + radius + aa;
lt_origo.y = coords->y1 + radius + aa;
lb_origo.x = coords->x1 + radius + LV_ANTIALIAS;
lb_origo.y = coords->y2 - radius - LV_ANTIALIAS;
lb_origo.x = coords->x1 + radius + aa;
lb_origo.y = coords->y2 - radius - aa;
rt_origo.x = coords->x2 - radius - LV_ANTIALIAS;
rt_origo.y = coords->y1 + radius + LV_ANTIALIAS;
rt_origo.x = coords->x2 - radius - aa;
rt_origo.y = coords->y1 + radius + aa;
rb_origo.x = coords->x2 - radius - LV_ANTIALIAS;
rb_origo.y = coords->y2 - radius - LV_ANTIALIAS;
rb_origo.x = coords->x2 - radius - aa;
rb_origo.y = coords->y2 - radius - aa;
lv_point_t cir_out;
lv_coord_t tmp_out;
@@ -735,113 +742,114 @@ static void lv_draw_rect_border_corner(const lv_area_t * coords, const lv_area_t
act_w2 = act_w1 - 1;
}
#if LV_ANTIALIAS != 0
/*New step in y on the outter circle*/
if(out_x_last != cir_out.x) {
out_y_seg_end = cir_out.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
#if LV_ANTIALIAS
if(aa) {
/*New step in y on the outter circle*/
if(out_x_last != cir_out.x) {
out_y_seg_end = cir_out.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
aa_p.x = out_x_last;
aa_p.y = out_y_seg_start;
aa_p.x = out_x_last;
aa_p.y = out_y_seg_start;
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa;
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa;
if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping on the first segment*/
aa_opa = antialias_get_opa_circ(seg_size, i, opa);
} else {
aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
}
if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping on the first segment*/
aa_opa = antialias_get_opa_circ(seg_size, i, opa);
} else {
aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
}
out_x_last = cir_out.x;
out_y_seg_start = out_y_seg_end;
}
/*New step in y on the inner circle*/
if(in_x_last != cir_in.x) {
in_y_seg_end = cir_out.y;
lv_coord_t seg_size = in_y_seg_end - in_y_seg_start;
lv_point_t aa_p;
aa_p.x = in_x_last;
aa_p.y = in_y_seg_start;
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa;
if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping on the first segment*/
aa_opa = opa - antialias_get_opa_circ(seg_size, i, opa);
} else {
aa_opa = lv_draw_aa_get_opa(seg_size, i, opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) - 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) + 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
/*Be sure the pixels on the middle are not drawn twice*/
if(LV_CIRC_OCT1_X(aa_p) - 1 != LV_CIRC_OCT2_X(aa_p) + i) {
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) + 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) - 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
}
out_x_last = cir_out.x;
out_y_seg_start = out_y_seg_end;
}
in_x_last = cir_in.x;
in_y_seg_start = in_y_seg_end;
/*New step in y on the inner circle*/
if(in_x_last != cir_in.x) {
in_y_seg_end = cir_out.y;
lv_coord_t seg_size = in_y_seg_end - in_y_seg_start;
lv_point_t aa_p;
aa_p.x = in_x_last;
aa_p.y = in_y_seg_start;
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa;
if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping on the first segment*/
aa_opa = opa - antialias_get_opa_circ(seg_size, i, opa);
} else {
aa_opa = lv_draw_aa_get_opa(seg_size, i, opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) - 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) + 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
/*Be sure the pixels on the middle are not drawn twice*/
if(LV_CIRC_OCT1_X(aa_p) - 1 != LV_CIRC_OCT2_X(aa_p) + i) {
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) + 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) - 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
}
}
in_x_last = cir_in.x;
in_y_seg_start = in_y_seg_end;
}
}
#endif
@@ -920,107 +928,107 @@ static void lv_draw_rect_border_corner(const lv_area_t * coords, const lv_area_t
}
#if LV_ANTIALIAS != 0
#if LV_ANTIALIAS
if(aa) {
/*Last parts of the outer anti-alias*/
out_y_seg_end = cir_out.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
/*Last parts of the outer anti-alias*/
out_y_seg_end = cir_out.y;
lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;
lv_point_t aa_p;
aa_p.x = out_x_last;
aa_p.y = out_y_seg_start;
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
}
/*In some cases the last pixel in the outer middle is not drawn*/
if(LV_MATH_ABS(aa_p.x - aa_p.y) == seg_size) {
aa_p.x = out_x_last;
aa_p.y = out_x_last;
aa_p.y = out_y_seg_start;
lv_opa_t aa_opa = opa >> 1;
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p), rb_origo.y + LV_CIRC_OCT2_Y(aa_p), mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p), lb_origo.y + LV_CIRC_OCT4_Y(aa_p), mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p), lt_origo.y + LV_CIRC_OCT6_Y(aa_p), mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p), rt_origo.y + LV_CIRC_OCT8_Y(aa_p), mask, style->body.border.color, aa_opa);
}
}
/*Last parts of the inner anti-alias*/
in_y_seg_end = cir_in.y;
aa_p.x = in_x_last;
aa_p.y = in_y_seg_start;
seg_size = in_y_seg_end - in_y_seg_start;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa = lv_draw_aa_get_opa(seg_size, i, opa);
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) - 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) + 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if(LV_CIRC_OCT1_X(aa_p) - 1 != LV_CIRC_OCT2_X(aa_p) + i) {
lv_coord_t i;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) + 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) - 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
}
/*In some cases the last pixel in the outer middle is not drawn*/
if(LV_MATH_ABS(aa_p.x - aa_p.y) == seg_size) {
aa_p.x = out_x_last;
aa_p.y = out_x_last;
lv_opa_t aa_opa = opa >> 1;
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p), rb_origo.y + LV_CIRC_OCT2_Y(aa_p), mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p), lb_origo.y + LV_CIRC_OCT4_Y(aa_p), mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p), lt_origo.y + LV_CIRC_OCT6_Y(aa_p), mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p), rt_origo.y + LV_CIRC_OCT8_Y(aa_p), mask, style->body.border.color, aa_opa);
}
}
/*Last parts of the inner anti-alias*/
in_y_seg_end = cir_in.y;
aa_p.x = in_x_last;
aa_p.y = in_y_seg_start;
seg_size = in_y_seg_end - in_y_seg_start;
for(i = 0; i < seg_size; i++) {
lv_opa_t aa_opa = lv_draw_aa_get_opa(seg_size, i, opa);
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) - 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) + 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if(LV_CIRC_OCT1_X(aa_p) - 1 != LV_CIRC_OCT2_X(aa_p) + i) {
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) - 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) + 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {
lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) + 1, mask, style->body.border.color, aa_opa);
}
if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {
lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) - 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, style->body.border.color, aa_opa);
}
}
}
}
#endif
}
@@ -1074,6 +1082,7 @@ static void lv_draw_shadow_full(const lv_area_t * coords, const lv_area_t * mask
* the other corner. `col` also should start from `- swidth`
*/
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
lv_coord_t radius = style->body.radius;
lv_coord_t swidth = style->body.shadow.width;
@@ -1083,7 +1092,7 @@ static void lv_draw_shadow_full(const lv_area_t * coords, const lv_area_t * mask
radius = lv_draw_cont_radius_corr(radius, width, height);
radius += LV_ANTIALIAS;
radius += aa;
#if LV_COMPILER_VLA_SUPPORTED
lv_coord_t curve_x[radius + swidth + 1]; /*Stores the 'x' coordinates of a quarter circle.*/
@@ -1140,17 +1149,17 @@ static void lv_draw_shadow_full(const lv_area_t * coords, const lv_area_t * mask
lv_point_t ofs_rt;
lv_point_t ofs_lb;
lv_point_t ofs_lt;
ofs_rb.x = coords->x2 - radius - LV_ANTIALIAS;
ofs_rb.y = coords->y2 - radius - LV_ANTIALIAS;
ofs_rb.x = coords->x2 - radius - aa;
ofs_rb.y = coords->y2 - radius - aa;
ofs_rt.x = coords->x2 - radius - LV_ANTIALIAS;
ofs_rt.y = coords->y1 + radius + LV_ANTIALIAS;
ofs_rt.x = coords->x2 - radius - aa;
ofs_rt.y = coords->y1 + radius + aa;
ofs_lb.x = coords->x1 + radius + LV_ANTIALIAS;
ofs_lb.y = coords->y2 - radius - LV_ANTIALIAS;
ofs_lb.x = coords->x1 + radius + aa;
ofs_lb.y = coords->y2 - radius - aa;
ofs_lt.x = coords->x1 + radius + LV_ANTIALIAS;
ofs_lt.y = coords->y1 + radius + LV_ANTIALIAS;
ofs_lt.x = coords->x1 + radius + aa;
ofs_lt.y = coords->y1 + radius + aa;
bool line_ready;
for(line = 0; line <= radius + swidth; line++) { /*Check all rows and make the 1D blur to 2D*/
line_ready = false;
@@ -1235,14 +1244,15 @@ static void lv_draw_shadow_full(const lv_area_t * coords, const lv_area_t * mask
static void lv_draw_shadow_bottom(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
{
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
lv_coord_t radius = style->body.radius;
lv_coord_t swidth = style->body.shadow.width;
lv_coord_t width = lv_area_get_width(coords);
lv_coord_t height = lv_area_get_height(coords);
radius = lv_draw_cont_radius_corr(radius, width, height);
radius += LV_ANTIALIAS * SHADOW_BOTTOM_AA_EXTRA_RADIUS;
swidth += LV_ANTIALIAS;
radius += aa * SHADOW_BOTTOM_AA_EXTRA_RADIUS;
swidth += aa;
#if LV_COMPILER_VLA_SUPPORTED
lv_coord_t curve_x[radius + 1]; /*Stores the 'x' coordinates of a quarter circle.*/
#else
@@ -1284,10 +1294,10 @@ static void lv_draw_shadow_bottom(const lv_area_t * coords, const lv_area_t * ma
lv_point_t ofs_r;
ofs_l.x = coords->x1 + radius;
ofs_l.y = coords->y2 - radius + 1 - LV_ANTIALIAS;
ofs_l.y = coords->y2 - radius + 1 - aa;
ofs_r.x = coords->x2 - radius;
ofs_r.y = coords->y2 - radius + 1 - LV_ANTIALIAS;
ofs_r.y = coords->y2 - radius + 1 - aa;
for(col = 0; col <= radius; col++) {
point_l.x = ofs_l.x - col ;
@@ -1333,36 +1343,37 @@ static void lv_draw_shadow_bottom(const lv_area_t * coords, const lv_area_t * ma
static void lv_draw_shadow_full_straight(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, const lv_opa_t * map)
{
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
lv_coord_t radius = style->body.radius;
lv_coord_t swidth = style->body.shadow.width;// + LV_ANTIALIAS;
lv_coord_t width = lv_area_get_width(coords);
lv_coord_t height = lv_area_get_height(coords);
radius = lv_draw_cont_radius_corr(radius, width, height);
radius += LV_ANTIALIAS;
radius += aa;
lv_area_t right_area;
right_area.x1 = coords->x2 + 1 - LV_ANTIALIAS;
right_area.y1 = coords->y1 + radius + LV_ANTIALIAS;
right_area.x1 = coords->x2 + 1 - aa;
right_area.y1 = coords->y1 + radius + aa;
right_area.x2 = right_area.x1;
right_area.y2 = coords->y2 - radius - LV_ANTIALIAS;
right_area.y2 = coords->y2 - radius - aa;
lv_area_t left_area;
left_area.x1 = coords->x1 - 1 + LV_ANTIALIAS;
left_area.y1 = coords->y1 + radius + LV_ANTIALIAS;
left_area.x1 = coords->x1 - 1 + aa;
left_area.y1 = coords->y1 + radius + aa;
left_area.x2 = left_area.x1;
left_area.y2 = coords->y2 - radius - LV_ANTIALIAS;
left_area.y2 = coords->y2 - radius - aa;
lv_area_t top_area;
top_area.x1 = coords->x1 + radius + LV_ANTIALIAS;
top_area.y1 = coords->y1 - 1 + LV_ANTIALIAS;
top_area.x2 = coords->x2 - radius - LV_ANTIALIAS;
top_area.x1 = coords->x1 + radius + aa;
top_area.y1 = coords->y1 - 1 + aa;
top_area.x2 = coords->x2 - radius - aa;
top_area.y2 = top_area.y1;
lv_area_t bottom_area;
bottom_area.x1 = coords->x1 + radius + LV_ANTIALIAS;
bottom_area.y1 = coords->y2 + 1 - LV_ANTIALIAS;
bottom_area.x2 = coords->x2 - radius - LV_ANTIALIAS;
bottom_area.x1 = coords->x1 + radius + aa;
bottom_area.y1 = coords->y2 + 1 - aa;
bottom_area.x2 = coords->x2 - radius - aa;
bottom_area.y2 = bottom_area.y1;
lv_opa_t opa_act;
@@ -1393,6 +1404,8 @@ static void lv_draw_shadow_full_straight(const lv_area_t * coords, const lv_area
static uint16_t lv_draw_cont_radius_corr(uint16_t r, lv_coord_t w, lv_coord_t h)
{
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
if(r >= (w >> 1)) {
r = (w >> 1);
if(r != 0) r--;
@@ -1402,7 +1415,7 @@ static uint16_t lv_draw_cont_radius_corr(uint16_t r, lv_coord_t w, lv_coord_t h)
if(r != 0) r--;
}
if(r > 0) r -= LV_ANTIALIAS;
if(r > 0) r -= aa;
return r;
}

View File

@@ -14,13 +14,13 @@
#include "lv_hal.h"
#include "../lv_misc/lv_mem.h"
#include "../lv_core/lv_obj.h"
#include "../lv_core/lv_refr.h"
#include "../lv_misc/lv_gc.h"
#if defined(LV_GC_INCLUDE)
# include LV_GC_INCLUDE
#endif /* LV_ENABLE_GC */
/*********************
* DEFINES
*********************/
@@ -61,6 +61,10 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
driver->ver_res = LV_VER_RES_MAX;
driver->buffer = NULL;
#if LV_ANTIALIAS
driver->antialiasing = true;
#endif
#if LV_USE_GPU
driver->mem_blend = NULL;
driver->mem_fill = NULL;
@@ -132,6 +136,12 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
disp_def = disp_def_tmp; /*Revert the default display*/
/*Create a refresh task*/
disp->refr_task = lv_task_create(lv_disp_refr_task, LV_REFR_PERIOD, LV_TASK_PRIO_MID, disp);
lv_mem_assert(disp->refr_task);
if(disp->refr_task == NULL) return NULL;
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
return disp;
}
@@ -205,6 +215,23 @@ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp)
else return disp->driver.ver_res;
}
/**
* Get if anti-aliasing is enabled for a display or not
* @param disp pointer to a display (NULL to use the default display)
* @return true: anti-aliasing is enabled; false: disabled
*/
bool lv_disp_get_antialiasing(lv_disp_t * disp)
{
#if LV_ANTIALIAS == 0
return false;
#else
if(disp == NULL) disp = lv_disp_get_default();
if(disp == NULL) return false;
return disp->driver.antialiasing ? true : false;
#endif
}
/**
* Call in the display driver's `flush_cb` function when the flushing is finished
* @param disp_drv pointer to display driver in `flush_cb` where this function is called

View File

@@ -21,6 +21,7 @@ extern "C" {
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_ll.h"
#include "../lv_misc/lv_task.h"
/*********************
* DEFINES
@@ -67,6 +68,10 @@ typedef struct _disp_drv_t {
* LittlevGL will use this buffer(s) to draw the screens contents */
lv_disp_buf_t * buffer;
#if LV_ANTIALIAS
uint32_t antialiasing :1;
#endif
/* MANDATORY: Write the internal buffer (VDB) to the display. 'lv_flush_ready()' has to be called when finished */
void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
@@ -110,6 +115,9 @@ typedef struct _disp_t {
/*Driver to the display*/
lv_disp_drv_t driver;
/*A task which periodically checks the dirty areas and refreshes them*/
lv_task_t * refr_task;
/*Screens of the display*/
lv_ll_t scr_ll;
struct _lv_obj_t * act_scr;
@@ -192,6 +200,13 @@ lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp);
*/
lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);
/**
* Get if anti-aliasing is enabled for a display or not
* @param disp pointer to a display (NULL to use the default display)
* @return true: anti-aliasing is enabled; false: disabled
*/
bool lv_disp_get_antialiasing(lv_disp_t * disp);
/**
* Call in the display driver's `flush_cb` function when the flushing is finished
* @param disp_drv pointer to display driver in `flush_cb` where this function is called

View File

@@ -995,7 +995,7 @@ bool lv_ta_text_is_selected(const lv_obj_t *ta) {
* @param ta pointer to a text area object
* @return true: selection mode is enabled, false: disabled
*/
bool lv_ta_get_sel_mode(lv_obj_t *ta, bool en) {
bool lv_ta_get_sel_mode(lv_obj_t *ta) {
lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
return ext->sel_mode;

View File

@@ -395,7 +395,7 @@ bool lv_ta_text_is_selected(const lv_obj_t *ta);
* @param ta pointer to a text area object
* @return true: selection mode is enabled, false: disabled
*/
bool lv_ta_get_sel_mode(lv_obj_t *ta, bool en);
bool lv_ta_get_sel_mode(lv_obj_t *ta);
/*=====================
* Other functions