BigW Consortium Gitlab

Commit 2237ebd4 by Gabor Kiss-Vamosi

work in progress with new anti aliasing

parent 133bfe16
......@@ -28,23 +28,23 @@ extern "C" {
/*Error check of lv_conf.h*/
#if LV_HOR_RES == 0 || LV_VER_RES == 0
#error "LV: LV_HOR_RES and LV_VER_RES must be greater then 0"
#error "LittlevGL: LV_HOR_RES and LV_VER_RES must be greater then 0"
#endif
#if LV_ANTIALIAS != 0 && LV_ANTIALIAS != 1
#error "LV: LV_ATIALIAS can be only 0 or 1"
#if LV_ANTIALIAS > 1
#error "LittlevGL: LV_ANTIALIAS can be only 0 or 1"
#endif
#if LV_VDB_SIZE == 0 && LV_ANTIALIAS != 0
#error "LV: If LV_VDB_SIZE == 0 the antialaissing must be disabled"
#error "LittlevGL: If LV_VDB_SIZE == 0 the anti-aliasing must be disabled"
#endif
#if LV_VDB_SIZE != 0 && LV_VDB_SIZE < LV_HOR_RES && LV_ANTIALIAS == 0
#error "LV: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= LV_HOR_RES)"
#if LV_VDB_SIZE > 0 && LV_VDB_SIZE < LV_HOR_RES
#error "LittlevGL: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= LV_HOR_RES)"
#endif
#if LV_VDB_SIZE != 0 && LV_VDB_SIZE < 2 *LV_HOR_RES && LV_ANTIALIAS != 0
#error "LV: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= (2 * LV_HOR_RES))"
#error "LittlevGL: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= (2 * LV_HOR_RES))"
#endif
#define LV_ANIM_IN 0x00 /*Animation to show an object. 'OR' it with lv_anim_builtin_t*/
......
......@@ -98,14 +98,6 @@ void lv_inv_area(const lv_area_t * area_p)
/*The area is truncated to the screen*/
if(suc != false)
{
#if LV_ANTIALIAS == 1
/*Rounding*/
com_area.x1 = com_area.x1 & (~0x1);
com_area.y1 = com_area.y1 & (~0x1);
com_area.x2 = com_area.x2 | 0x1;
com_area.y2 = com_area.y2 | 0x1;
#endif
/*Save only if this area is not in one of the saved areas*/
uint16_t i;
for(i = 0; i < inv_buf_p; i++) {
......@@ -262,10 +254,8 @@ static void lv_refr_area_with_vdb(const lv_area_t * area_p)
lv_coord_t h = lv_area_get_height(area_p);
lv_coord_t y2 = area_p->y2 >= LV_VER_RES ? y2 = LV_VER_RES - 1 : area_p->y2;
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (w << LV_AA);
if(max_row > (h << LV_AA)) max_row = (h << LV_AA);
max_row = max_row >> LV_AA ;
uint32_t max_row = (uint32_t) LV_VDB_SIZE / w;
if(max_row > h) max_row = h;
/*Always use the full row*/
uint32_t row;
......@@ -312,13 +302,6 @@ static void lv_refr_area_part_vdb(const lv_area_t * area_p)
lv_area_t start_mask;
lv_area_union(&start_mask, area_p, &vdb_p->area);
#if LV_ANTIALIAS
vdb_p->area.x1 = vdb_p->area.x1 << LV_AA;
vdb_p->area.x2 = (vdb_p->area.x2 << LV_AA) + 1;
vdb_p->area.y1 = (vdb_p->area.y1 << LV_AA);
vdb_p->area.y2 = (vdb_p->area.y2 << LV_AA) + 1;
#endif
/*Get the most top object which is not covered by others*/
top_p = lv_refr_get_top_obj(&start_mask, lv_scr_act());
......
......@@ -23,7 +23,6 @@ extern "C" {
* DEFINES
*********************/
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /*A very big radius to always draw as circle*/
#define LV_AA LV_ANTIALIAS /*Just a shorter form of LV_ANTIALIAS*/
/**********************
* TYPEDEFS
......
......@@ -119,59 +119,9 @@ void lv_vdb_flush(void)
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH;
#endif
#if LV_ANTIALIAS == 0
/*Flush the rendered content to the display*/
lv_disp_flush(vdb_act->area.x1, vdb_act->area.y1, vdb_act->area.x2, vdb_act->area.y2, vdb_act->buf);
#else
/* Get the average of 2x2 pixels and put the result back to the VDB
* The reading goes much faster then the write back
* so useful data won't be overwritten
* Example:
* -----------------------------
* in1_buf |2,2|6,8| 3,7
* in2_buf |4,4|7,7| 1,2
* --------- ==>
* in1_buf |1,1|1,3|
* in2_buf |1,1|1,3|
* */
lv_coord_t x;
lv_coord_t y;
lv_coord_t w = lv_area_get_width(&vdb_act->area);
lv_color_t * in1_buf = vdb_act->buf; /*Pointer to the first row*/
lv_color_t * in2_buf = vdb_act->buf + w; /*Pointer to the second row*/
lv_color_t * out_buf = vdb_act->buf; /*Store the result here*/
for(y = vdb_act->area.y1; y < vdb_act->area.y2; y += 2) {
for(x = vdb_act->area.x1; x < vdb_act->area.x2; x += 2) {
/*If the pixels are the same do not calculate the average */
if(in1_buf->full == (in1_buf + 1)->full &&
in1_buf->full == in2_buf->full &&
in1_buf->full == (in2_buf + 1)->full) {
out_buf->full = in1_buf->full;
} else {
/*Get the average of 2x2 red*/
out_buf->red = (in1_buf->red + (in1_buf + 1)->red +
in2_buf->red + (in2_buf+ 1)->red) >> 2;
/*Get the average of 2x2 green*/
out_buf->green = (in1_buf->green + (in1_buf + 1)->green +
in2_buf->green + (in2_buf + 1)->green) >> 2;
/*Get the average of 2x2 blue*/
out_buf->blue = (in1_buf->blue + (in1_buf + 1)->blue +
in2_buf->blue + (in2_buf + 1)->blue) >> 2;
}
in1_buf += 2; /*Skip the next pixel because it is already used above*/
in2_buf += 2;
out_buf ++;
}
/*2 row is ready so go the next 2*/
in1_buf += w; /*Skip the next row because it is processed from in2_buf*/
in2_buf += w;
}
/* Now the full the VDB is filtered and the result is stored in the first quarter of it
* Write out the filtered map to the display*/
lv_disp_flush(vdb_act->area.x1 >> 1, vdb_act->area.y1 >> 1, vdb_act->area.x2 >> 1, vdb_act->area.y2 >> 1, vdb_act->buf);
#endif
}
/**
......
......@@ -109,7 +109,6 @@ void lv_rletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
const uint8_t * bitmap_p = lv_font_get_bitmap(font_p, letter);
uint8_t col, col_sub, row;
#if LV_FONT_ANTIALIAS == 0
for(row = 0; row < font_p->h_px; row ++) {
for(col = 0, col_sub = 7; col < w; col ++, col_sub--) {
if(*bitmap_p & (1 << col_sub)) {
......@@ -124,50 +123,7 @@ void lv_rletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
/*Go to the next row*/
if(col_sub != 7) bitmap_p ++; /*Go to the next byte if it not done in the last step*/
}
#else
uint8_t width_byte = w >> 3; /*Width in bytes (e.g. w = 11 -> 2 bytes wide)*/
if(w & 0x7) width_byte++;
const uint8_t * map1_p = bitmap_p;
const uint8_t * map2_p = bitmap_p + width_byte;
uint8_t px_cnt;
uint8_t col_byte_cnt;
for(row = 0; row < (font_p->h_px >> 1); row ++) {
col_byte_cnt = 0;
col_sub = 7;
for(col = 0; col < (w >> 1); col ++) {
px_cnt = 0;
if((*map1_p & (1 << col_sub)) != 0) px_cnt++;
if((*map2_p & (1 << col_sub)) != 0) px_cnt++;
if(col_sub != 0) col_sub --;
else {
col_sub = 7;
col_byte_cnt ++;
map1_p ++;
map2_p ++;
}
if((*map1_p & (1 << col_sub)) != 0) px_cnt++;
if((*map2_p & (1 << col_sub)) != 0) px_cnt++;
if(col_sub != 0) col_sub --;
else {
col_sub = 7;
col_byte_cnt ++;
map1_p ++;
map2_p ++;
}
if(px_cnt != 0) {
lv_rpx(pos_p->x + col, pos_p->y + row, mask_p, lv_color_mix(color, LV_COLOR_SILVER, 63 * px_cnt), LV_OPA_COVER);
}
}
map1_p += width_byte;
map2_p += width_byte;
map1_p += width_byte - col_byte_cnt;
map2_p += width_byte - col_byte_cnt;
}
#endif
}
/**
......
......@@ -128,7 +128,7 @@ void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
#if USE_LV_GPU
static lv_color_t color_array_tmp[LV_HOR_RES << LV_ANTIALIAS]; /*Used by 'sw_color_fill'*/
static lv_color_t color_array_tmp[LV_HOR_RES]; /*Used by 'lv_disp_mem_blend'*/
static lv_coord_t last_width = -1;
lv_coord_t w = lv_area_get_width(&vdb_rel_a);
......
......@@ -19,7 +19,8 @@ extern "C" {
/*********************
* DEFINES
*********************/
#define TRIGO_SIN_MAX 32767
#define LV_TRIGO_SIN_MAX 32767
#define LV_TRIGO_SHIFT 15 /* >> LV_TRIGO_SHIFT to normalize*/
/**********************
* TYPEDEFS
......
......@@ -337,10 +337,10 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask)
/*Calculate the position a scale label*/
int16_t angle = (i * scale_angle) / (label_num - 1) + angle_ofs;
lv_coord_t y = (int32_t)((int32_t)lv_trigo_sin(angle) * r) / TRIGO_SIN_MAX;
lv_coord_t y = (int32_t)((int32_t)lv_trigo_sin(angle) * r) / LV_TRIGO_SIN_MAX;
y += y_ofs;
lv_coord_t x = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r) / TRIGO_SIN_MAX;
lv_coord_t x = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r) / LV_TRIGO_SIN_MAX;
x += x_ofs;
int16_t scale_act = (int32_t)((int32_t)(max - min) * i) / (label_num - 1);
......@@ -390,8 +390,8 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)
for(i = 0; i < ext->needle_count; i++) {
/*Calculate the end point of a needle*/
int16_t needle_angle = (ext->values[i] - min) * angle / (max - min) + angle_ofs;
p_end.y = (lv_trigo_sin(needle_angle) * r) / TRIGO_SIN_MAX + y_ofs;
p_end.x = (lv_trigo_sin(needle_angle + 90) * r) / TRIGO_SIN_MAX + x_ofs;
p_end.y = (lv_trigo_sin(needle_angle) * r) / LV_TRIGO_SIN_MAX + y_ofs;
p_end.x = (lv_trigo_sin(needle_angle + 90) * r) / LV_TRIGO_SIN_MAX + x_ofs;
/*Draw the needle with the corresponding color*/
if(ext->needle_colors == NULL) style_needle.line.color = LV_GAUGE_DEF_NEEDLE_COLOR;
......
......@@ -74,7 +74,6 @@ lv_obj_t * lv_img_create(lv_obj_t * par, lv_obj_t * copy)
ext->w = lv_obj_get_width(new_img);
ext->h = lv_obj_get_height(new_img);
ext->transp = 0;
ext->upscale = 0;
ext->auto_size = 1;
/*Init the new object*/
......@@ -92,7 +91,6 @@ lv_obj_t * lv_img_create(lv_obj_t * par, lv_obj_t * copy)
} else {
lv_img_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->auto_size = copy_ext->auto_size;
ext->upscale = copy_ext->upscale;
lv_img_set_file(new_img, copy_ext->fn);
/*Refresh the style with new signal function*/
......@@ -175,12 +173,6 @@ void lv_img_set_file(lv_obj_t * img, const char * fn)
ext->w = header.w;
ext->h = header.h;
ext->transp = header.transp;
#if LV_ANTIALIAS
if(ext->upscale == false) {
ext->w = ext->w >> LV_AA;
ext->h = ext->h >> LV_AA;
}
#endif
}
/*Handle symbol texts*/
else {
......@@ -225,25 +217,6 @@ void lv_img_set_auto_size(lv_obj_t * img, bool autosize_en)
ext->auto_size = (autosize_en == false ? 0 : 1);
}
/**
* Enable the upscaling if LV_ANTIALIAS is enabled.
* If enabled the object size will be same as the picture size.
* @param img pointer to an image
* @param upscale_en true: upscale enable, false: upscale disable
*/
void lv_img_set_upscale(lv_obj_t * img, bool upscale_en)
{
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
/*Upscale works only if antialiassing is enabled*/
#if LV_ANTIALIAS == 0
upscale_en = false;
#endif
ext->upscale = (upscale_en == false ? 0 : 1);
/*Refresh the image with the new size*/
lv_img_set_file(img, ext->fn);
}
/*=====================
* Getter functions
......@@ -275,18 +248,6 @@ bool lv_img_get_auto_size(lv_obj_t * img)
return ext->auto_size == 0 ? false : true;
}
/**
* Get the upscale enable attribute
* @param img pointer to an image
* @return true: upscale is enabled, false: upscale is disabled
*/
bool lv_img_get_upscale(lv_obj_t * img)
{
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
return ext->upscale == 0 ? false : true;
}
/**********************
* STATIC FUNCTIONS
**********************/
......
......@@ -41,7 +41,6 @@ typedef struct
lv_coord_t w; /*Width of the image (doubled when upscaled) (Handled by the library)*/
lv_coord_t h; /*Height of the image (doubled when upscaled) (Handled by the library)*/
uint8_t auto_size :1; /*1: automatically set the object size to the image size*/
uint8_t upscale :1; /*1: upscale to double size with antialaissing*/
uint8_t transp :1; /*Transp. bit in the image header (Handled by the library)*/
uint8_t alpha_byte :1; /*Extra byte for every pixel to define opacity*/
}lv_img_ext_t;
......@@ -86,14 +85,6 @@ void lv_img_set_file(lv_obj_t * img, const char * fn);
void lv_img_set_auto_size(lv_obj_t * img, bool autosize_en);
/**
* Enable the upscaling if LV_ANTIALIAS is enabled.
* If enabled the object size will be same as the picture size.
* @param img pointer to an image
* @param en true: upscale enable, false: upscale disable
*/
void lv_img_set_upscale(lv_obj_t * img, bool en);
/**
* Set the style of an image
* @param img pointer to an image object
* @param style pointer to a style
......@@ -123,13 +114,6 @@ const char * lv_img_get_file_name(lv_obj_t * img);
bool lv_img_get_auto_size(lv_obj_t * img);
/**
* Get the upscale enable attribute
* @param img pointer to an image
* @return true: upscale is enabled, false: upscale is disabled
*/
bool lv_img_get_upscale(lv_obj_t * img);
/**
* Get the style of an image object
* @param img pointer to an image object
* @return pointer to the image's style
......
......@@ -112,9 +112,11 @@ void lv_line_set_points(lv_obj_t * line, const lv_point_t * point_a, uint16_t po
ymax = LV_MATH_MAX(point_a[i].y, ymax);
}
lv_style_t * lines = lv_obj_get_style(line);
lv_obj_set_size(line, xmax + lines->line.width, ymax + lines->line.width);
lv_style_t * style = lv_line_get_style(line);
lv_obj_set_size(line, xmax + style->line.width, ymax + style->line.width);
}
lv_obj_invalidate(line);
}
/**
......
......@@ -18,6 +18,8 @@
/*********************
* DEFINES
*********************/
#define LV_LMETER_LINE_UPSCALE 5 /*2^x upscale of line to make rounding*/
#define LV_LMETER_LINE_UPSCALE_MASK ((1 << LV_LMETER_LINE_UPSCALE) - 1)
/**********************
* TYPEDEFS
......@@ -28,6 +30,7 @@
**********************/
static bool lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * mask, lv_design_mode_t mode);
static lv_res_t lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * param);
static lv_coord_t lv_lmeter_coord_round(int32_t x);
/**********************
* STATIC VARIABLES
......@@ -237,7 +240,6 @@ static bool lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * mask, lv_desig
else if(mode == LV_DESIGN_DRAW_MAIN) {
lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);
lv_style_t * style = lv_obj_get_style(lmeter);
lv_style_t style_tmp;
memcpy(&style_tmp, style, sizeof(lv_style_t));
......@@ -251,6 +253,8 @@ static bool lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * mask, lv_desig
lv_coord_t r_out = lv_obj_get_width(lmeter) / 2;
lv_coord_t r_in = r_out - style->body.padding.hor;
if(r_in < 1) r_in = 1;
lv_coord_t x_ofs = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1;
lv_coord_t y_ofs = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1;
int16_t angle_ofs = 90 + (360 - ext->scale_angle) / 2;
......@@ -259,14 +263,24 @@ static bool lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * mask, lv_desig
style_tmp.line.color = style->body.main_color;
/*Calculate every coordinate in x32 size to make rounding later*/
r_out = r_out << LV_LMETER_LINE_UPSCALE;
r_in = r_in << LV_LMETER_LINE_UPSCALE;
for(i = 0; i < ext->line_cnt; i++) {
/*Calculate the position a scale label*/
int16_t angle = (i * ext->scale_angle) / (ext->line_cnt - 1) + angle_ofs;
lv_coord_t y_out = (int32_t)((int32_t)lv_trigo_sin(angle) * r_out) / TRIGO_SIN_MAX;
lv_coord_t x_out = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_out) / TRIGO_SIN_MAX;
lv_coord_t y_in = (int32_t)((int32_t)lv_trigo_sin(angle) * r_in) / TRIGO_SIN_MAX;
lv_coord_t x_in = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_in) / TRIGO_SIN_MAX;
lv_coord_t y_out = (int32_t)((int32_t)lv_trigo_sin(angle) * r_out) >> LV_TRIGO_SHIFT;
lv_coord_t x_out = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_out) >> LV_TRIGO_SHIFT;
lv_coord_t y_in = (int32_t)((int32_t)lv_trigo_sin(angle) * r_in) >> LV_TRIGO_SHIFT;
lv_coord_t x_in = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_in) >> LV_TRIGO_SHIFT;
/*Rounding*/
x_out = lv_lmeter_coord_round(x_out);
x_in = lv_lmeter_coord_round(x_in);
y_out = lv_lmeter_coord_round(y_out);
y_in = lv_lmeter_coord_round(y_in);
lv_point_t p1;
lv_point_t p2;
......@@ -316,5 +330,30 @@ static lv_res_t lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * par
return res;
}
/**
* Round a coordinate which is upscaled (>=x.5 -> x + 1; <x.5 -> x)
* @param x a coordinate which is greater then it should be
* @return the downscaled and rounded coordinate (+-1)
*/
static lv_coord_t lv_lmeter_coord_round(int32_t x)
{
#if LV_LMETER_LINE_UPSCALE > 0
bool was_negative;
if(x < 0) {
was_negative = true;
x = -x;
} else {
was_negative = false;
}
x = (x >> LV_LMETER_LINE_UPSCALE) + ((x & LV_LMETER_LINE_UPSCALE_MASK) >> (LV_LMETER_LINE_UPSCALE - 1));
if(was_negative) x = -x;
return x;
#else
return x;
#endif
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment