diff --git a/lv_conf_template.h b/lv_conf_template.h index 8450b6ea8..8b7913692 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -30,8 +30,7 @@ /* Enable anti-aliasing (lines, and radiuses will be smoothed) */ #define LV_ANTIALIAS 1 /*1: Enable anti-aliasing*/ - -/*Screen refresh period in milliseconds. LittlevGL will redraw the screen with this period*/ +/*Default screen refresh period in milliseconds. LittlevGL will redraw the screen with this period*/ #define LV_REFR_PERIOD 30 /*[ms]*/ /* Dot Per Inch: used to initialize default sizes. E.g. a button with width = LV_DPI / 2 -> half inch wide diff --git a/src/lv_core/lv_disp.c b/src/lv_core/lv_disp.c index dc4578d17..b32323f9a 100644 --- a/src/lv_core/lv_disp.c +++ b/src/lv_core/lv_disp.c @@ -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 **********************/ diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index b291213ed..4ca104c20 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -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 diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 7918e10dc..febd01a16 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -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 diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index 307ae8484..b55fbe64b 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -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 diff --git a/src/lv_core/lv_refr.h b/src/lv_core/lv_refr.h index 789d47889..bdf406c69 100644 --- a/src/lv_core/lv_refr.h +++ b/src/lv_core/lv_refr.h @@ -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 **********************/ diff --git a/src/lv_draw/lv_draw.c b/src/lv_draw/lv_draw.c index af7c8a384..b3ee3d775 100644 --- a/src/lv_draw/lv_draw.c +++ b/src/lv_draw/lv_draw.c @@ -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 diff --git a/src/lv_draw/lv_draw.h b/src/lv_draw/lv_draw.h index a3d41b745..5a1350873 100644 --- a/src/lv_draw/lv_draw.h +++ b/src/lv_draw/lv_draw.h @@ -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 diff --git a/src/lv_draw/lv_draw_line.c b/src/lv_draw/lv_draw_line.c index c456095c5..8fa7b894c 100644 --- a/src/lv_draw/lv_draw_line.c +++ b/src/lv_draw/lv_draw_line.c @@ -9,6 +9,7 @@ #include #include #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 } } diff --git a/src/lv_draw/lv_draw_rect.c b/src/lv_draw/lv_draw_rect.c index ecd29b32d..4de64642c 100644 --- a/src/lv_draw/lv_draw_rect.c +++ b/src/lv_draw/lv_draw_rect.c @@ -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; } diff --git a/src/lv_hal/lv_hal_disp.c b/src/lv_hal/lv_hal_disp.c index 39e6853ae..9993ae11b 100644 --- a/src/lv_hal/lv_hal_disp.c +++ b/src/lv_hal/lv_hal_disp.c @@ -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 diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index 89b5a22f8..47818f513 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -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 diff --git a/src/lv_objx/lv_ta.c b/src/lv_objx/lv_ta.c index 97f20771e..6ec07a1b8 100644 --- a/src/lv_objx/lv_ta.c +++ b/src/lv_objx/lv_ta.c @@ -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; diff --git a/src/lv_objx/lv_ta.h b/src/lv_objx/lv_ta.h index fa606e816..53c8716b9 100644 --- a/src/lv_objx/lv_ta.h +++ b/src/lv_objx/lv_ta.h @@ -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