merge dev-6.1

This commit is contained in:
Gabor Kiss-Vamosi
2019-10-24 15:25:52 +02:00
22 changed files with 373 additions and 98 deletions

View File

@@ -199,8 +199,10 @@ typedef void * lv_img_decoder_user_data_t;
/* Export integer constant to binding.
* This macro is used with constants in the form of LV_<CONST> that
* should also appear on lvgl binding API such as Micropython
*
* The default value just prevents a GCC warning.
*/
#define LV_EXPORT_CONST_INT(int_value)
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
/*===================
* HAL settings
@@ -372,6 +374,12 @@ typedef void * lv_font_user_data_t;
# define lv_vsnprintf vsnprintf
#endif /*LV_SPRINTF_CUSTOM*/
/* Set the pixel order of the display.
* Important only if "subpx fonts" are used.
* With "normal" font it doesn't matter.
*/
#define LV_SUBPX_BGR 0
/*===================
* LV_OBJ SETTINGS
*==================*/

6
scripts/lv_conf_checker.py Normal file → Executable file
View File

@@ -1,3 +1,5 @@
#!/usr/bin/env python3.6
'''
Generates a checker file for lv_conf.h from lv_conf_templ.h define all the not defined values
'''
@@ -34,9 +36,11 @@ for i in fin.read().splitlines():
if '/*--END OF LV_CONF_H--*/' in i: break
r = re.search(r'^ *# *define ([^\s]+).*$', i)
if r:
line = re.sub('\(.*?\)', '', r[1], 1) #remove parentheses from macros
fout.write(
f'#ifndef {r[1]}\n'
f'#ifndef {line}\n'
f'{i}\n'
'#endif\n'
)

View File

@@ -521,6 +521,14 @@
#endif
#endif /*LV_SPRINTF_CUSTOM*/
/* Set the pixel order of the display.
* Important only if "subpx fonts" are used.
* With "normal" font it doesn't matter.
*/
#ifndef LV_SUBPX_BGR
#define LV_SUBPX_BGR 0
#endif
/*===================
* LV_OBJ SETTINGS
*==================*/

View File

@@ -22,6 +22,7 @@
#include <stdint.h>
#include <string.h>
#include "../lv_misc/lv_gc.h"
#include "../lv_misc/lv_math.h"
#if defined(LV_GC_INCLUDE)
#include LV_GC_INCLUDE
@@ -1142,21 +1143,6 @@ void lv_obj_set_auto_realign(lv_obj_t * obj, bool en)
#endif
}
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
/**
* Set the size of an extended clickable area
* @param obj pointer to an object
* @param w extended width to both sides
* @param h extended height to both sides
*/
void lv_obj_set_ext_click_area(lv_obj_t * obj, uint8_t w, uint8_t h)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
obj->ext_click_pad_hor = w;
obj->ext_click_pad_ver = h;
}
#endif
/**
* Set the size of an extended clickable area
@@ -1963,7 +1949,7 @@ lv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj)
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY
return obj->ext_click_pad_ver
return obj->ext_click_pad_ver;
#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
return obj->ext_click_pad.y2;
#else

View File

@@ -57,6 +57,11 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
lv_coord_t thickness = style->line.width;
if(thickness > radius) thickness = radius;
#if LV_ANTIALIAS
thickness--;
radius--;
#endif
lv_coord_t r_out = radius;
lv_coord_t r_in = r_out - thickness;
int16_t deg_base;
@@ -73,17 +78,26 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
else
deg_test = deg_test_inv;
int middle_r_out = r_out;
#if !LV_ANTIALIAS
thickness--;
middle_r_out = r_out - 1;
#endif
if(deg_test(270, start_angle, end_angle))
hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); /*Left Middle*/
hor_line(center_x - middle_r_out, center_y, mask, thickness, color, opa); /*Left Middle*/
if(deg_test(90, start_angle, end_angle))
hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); /*Right Middle*/
hor_line(center_x + r_in, center_y, mask, thickness, color, opa); /*Right Middle*/
if(deg_test(180, start_angle, end_angle))
ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); /*Top Middle*/
ver_line(center_x, center_y - middle_r_out, mask, thickness, color, opa); /*Top Middle*/
if(deg_test(0, start_angle, end_angle))
ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); /*Bottom middle*/
ver_line(center_x, center_y + r_in, mask, thickness, color, opa); /*Bottom middle*/
uint32_t r_out_sqr = r_out * r_out;
uint32_t r_in_sqr = r_in * r_in;
#if LV_ANTIALIAS
uint32_t r_out_aa_sqr = (r_out + 1) * (r_out + 1);
uint32_t r_in_aa_sqr = (r_in - 1) * (r_in - 1);
#endif
int16_t xi;
int16_t yi;
for(yi = -r_out; yi < 0; yi++) {
@@ -95,13 +109,56 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
x_end[1] = LV_COORD_MIN;
x_end[2] = LV_COORD_MIN;
x_end[3] = LV_COORD_MIN;
int xe = 0;
for(xi = -r_out; xi < 0; xi++) {
uint32_t r_act_sqr = xi * xi + yi * yi;
#if LV_ANTIALIAS
if(r_act_sqr > r_out_aa_sqr) {
continue;
}
#else
if(r_act_sqr > r_out_sqr) continue;
#endif
deg_base = fast_atan2(xi, yi) - 180;
#if LV_ANTIALIAS
int opa = -1;
if(r_act_sqr > r_out_sqr) {
opa = LV_OPA_100 * (r_out + 1) - lv_sqrt(LV_OPA_100 * LV_OPA_100 * r_act_sqr);
if(opa < LV_OPA_0)
opa = LV_OPA_0;
else if(opa > LV_OPA_100)
opa = LV_OPA_100;
} else if(r_act_sqr < r_in_sqr) {
if(xe == 0) xe = xi;
opa = lv_sqrt(LV_OPA_100 * LV_OPA_100 * r_act_sqr) - LV_OPA_100 * (r_in - 1);
if(opa < LV_OPA_0)
opa = LV_OPA_0;
else if(opa > LV_OPA_100)
opa = LV_OPA_100;
if(r_act_sqr < r_in_aa_sqr)
break; /*No need to continue the iteration in x once we found the inner edge of the
arc*/
}
if(opa != -1) {
if(deg_test(180 + deg_base, start_angle, end_angle)) {
lv_draw_px(center_x + xi, center_y + yi, mask, color, opa);
}
if(deg_test(360 - deg_base, start_angle, end_angle)) {
lv_draw_px(center_x + xi, center_y - yi, mask, color, opa);
}
if(deg_test(180 - deg_base, start_angle, end_angle)) {
lv_draw_px(center_x - xi, center_y + yi, mask, color, opa);
}
if(deg_test(deg_base, start_angle, end_angle)) {
lv_draw_px(center_x - xi, center_y - yi, mask, color, opa);
}
continue;
}
#endif
deg = 180 + deg_base;
if(deg_test(deg, start_angle, end_angle)) {
if(x_start[0] == LV_COORD_MIN) x_start[0] = xi;
@@ -130,35 +187,32 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
x_end[3] = xi - 1;
}
if(r_act_sqr < r_in_sqr)
if(r_act_sqr < r_in_sqr) {
xe = xi;
break; /*No need to continue the iteration in x once we found the inner edge of the
arc*/
}
}
if(x_start[0] != LV_COORD_MIN) {
if(x_end[0] == LV_COORD_MIN) x_end[0] = xi - 1;
if(x_end[0] == LV_COORD_MIN) x_end[0] = xe - 1;
hor_line(center_x + x_start[0], center_y + yi, mask, x_end[0] - x_start[0], color, opa);
}
if(x_start[1] != LV_COORD_MIN) {
if(x_end[1] == LV_COORD_MIN) x_end[1] = xi - 1;
if(x_end[1] == LV_COORD_MIN) x_end[1] = xe - 1;
hor_line(center_x + x_start[1], center_y - yi, mask, x_end[1] - x_start[1], color, opa);
}
if(x_start[2] != LV_COORD_MIN) {
if(x_end[2] == LV_COORD_MIN) x_end[2] = xi - 1;
if(x_end[2] == LV_COORD_MIN) x_end[2] = xe - 1;
hor_line(center_x - x_end[2], center_y + yi, mask, LV_MATH_ABS(x_end[2] - x_start[2]), color, opa);
}
if(x_start[3] != LV_COORD_MIN) {
if(x_end[3] == LV_COORD_MIN) x_end[3] = xi - 1;
if(x_end[3] == LV_COORD_MIN) x_end[3] = xe - 1;
hor_line(center_x - x_end[3], center_y - yi, mask, LV_MATH_ABS(x_end[3] - x_start[3]), color, opa);
}
#if LV_ANTIALIAS
/*TODO*/
#endif
}
}

View File

@@ -252,6 +252,7 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0');
if(g_ret == false) return;
lv_coord_t pos_x = pos_p->x + g.ofs_x;
lv_coord_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;
@@ -300,17 +301,32 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
if(g.box_w & 0x7) width_byte_scr++;
uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/
bool subpx = font_p->subpx == LV_FONT_SUBPX_NONE ? false : true;
/* Calculate the col/row start/end on the map*/
lv_coord_t col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
lv_coord_t col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
lv_coord_t row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
lv_coord_t row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
lv_coord_t col_start;
lv_coord_t col_end;
lv_coord_t row_start;
lv_coord_t row_end;
if(subpx == false) {
col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
} else {
col_start = pos_x >= mask_p->x1 ? 0 : (mask_p->x1 - pos_x) * 3;
col_end = pos_x + g.box_w / 3 <= mask_p->x2 ? g.box_w : (mask_p->x2 - pos_x + 1) * 3;
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
}
/*Set a pointer on VDB to the first pixel of the letter*/
vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width) + pos_x - vdb->area.x1;
/*If the letter is partially out of mask the move there on VDB*/
vdb_buf_tmp += (row_start * vdb_width) + col_start;
if(subpx) vdb_buf_tmp += (row_start * vdb_width) + col_start / 3;
else vdb_buf_tmp += (row_start * vdb_width) + col_start;
/*Move on the map too*/
uint32_t bit_ofs = (row_start * width_bit) + (col_start * g.bpp);
@@ -326,37 +342,108 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
scr_transp = disp->driver.screen_transp;
#endif
uint8_t font_rgb[3];
#if LV_COLOR_16_SWAP == 0
uint8_t txt_rgb[3] = {color.ch.red, color.ch.green, color.ch.blue};
#else
uint8_t txt_rgb[3] = {color.ch.red, (color.ch.green_h << 3) + color.ch.green_l, color.ch.blue};
#endif
for(row = row_start; row < row_end; row++) {
bitmask = bitmask_init >> col_bit;
uint8_t sub_px_cnt = 0;
for(col = col_start; col < col_end; col++) {
letter_px = (*map_p & bitmask) >> (8 - col_bit - g.bpp);
if(letter_px != 0) {
if(opa == LV_OPA_COVER) {
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
} else {
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
}
if(disp->driver.set_px_cb) {
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
} else if(vdb_buf_tmp->full != color.full) {
if(px_opa > LV_OPA_MAX)
*vdb_buf_tmp = color;
else if(px_opa > LV_OPA_MIN) {
if(scr_transp == false) {
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
} else {
/*subpx == 0*/
if(subpx == false) {
if(letter_px != 0) {
if(opa == LV_OPA_COVER) {
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
} else {
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
}
if(disp->driver.set_px_cb) {
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
} else if(vdb_buf_tmp->full != color.full) {
if(px_opa > LV_OPA_MAX) {
*vdb_buf_tmp = color;
} else if(px_opa > LV_OPA_MIN) {
if(scr_transp == false) {
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
} else {
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
#endif
}
}
}
}
vdb_buf_tmp++;
}
/*Handle subpx drawing*/
else {
if(letter_px != 0) {
if(opa == LV_OPA_COVER) {
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
} else {
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
}
font_rgb[sub_px_cnt] = px_opa;
} else {
font_rgb[sub_px_cnt] = 0;
}
sub_px_cnt ++;
if(sub_px_cnt == 3) {
lv_color_t res_color;
if(font_rgb[0] == 0 && font_rgb[1] == 0 && font_rgb[2] == 0) {
res_color = *vdb_buf_tmp;
} else {
#if LV_COLOR_16_SWAP == 0
uint8_t bg_rgb[3] = {vdb_buf_tmp->ch.red, vdb_buf_tmp->ch.green, vdb_buf_tmp->ch.blue};
#else
uint8_t bg_rgb[3] = {vdb_buf_tmp->ch.red,
(vdb_buf_tmp->ch.green_h << 3) + vdb_buf_tmp->ch.green_l,
vdb_buf_tmp->ch.blue};
#endif
#if LV_SUBPX_BGR
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[2] * (255 - font_rgb[0]))) >> 8;
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[0] * (255 - font_rgb[2]))) >> 8;
#else
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
#endif
#if LV_COLOR_16_SWAP == 0
res_color.ch.green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
#else
uint8_t green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
res_color.ch.green_h = green >> 3;
res_color.ch.green_l = green & 0x7;
#endif
}
if(scr_transp == false) {
vdb_buf_tmp->full = res_color.full;
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
} else {
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
#endif
}
sub_px_cnt = 0;
vdb_buf_tmp++;
}
}
vdb_buf_tmp++;
if(col_bit < 8 - g.bpp) {
col_bit += g.bpp;
@@ -367,11 +454,15 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
map_p++;
}
}
col_bit += ((g.box_w - col_end) + col_start) * g.bpp;
map_p += (col_bit >> 3);
col_bit = col_bit & 0x7;
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
/*Next row in VDB*/
if(subpx) vdb_buf_tmp += vdb_width - (col_end - col_start) / 3;
else vdb_buf_tmp += vdb_width - (col_end - col_start);
}
}

View File

@@ -53,7 +53,18 @@ typedef struct
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
}lv_font_glyph_dsc_t;
/*Describe the properties of a font*/
/** The bitmaps might be upscaled by 3 to achieve subpixel rendering. */
enum {
LV_FONT_SUBPX_NONE,
LV_FONT_SUBPX_HOR,
LV_FONT_SUBPX_VER,
LV_FONT_SUBPX_BOTH,
};
typedef uint8_t lv_font_subpx_t;
/** Describe the properties of a font*/
typedef struct _lv_font_struct
{
/** Get a glyph's descriptor from a font*/
@@ -65,10 +76,13 @@ typedef struct _lv_font_struct
/*Pointer to the font in a font pack (must have the same line height)*/
uint8_t line_height; /**< The real line height where any text fits*/
uint8_t base_line; /**< Base line measured from the top of the line_height*/
uint8_t subpx :2; /**< An element of `lv_font_subpx_t`*/
void * dsc; /**< Store implementation specific data here*/
#if LV_USE_USER_DATA
lv_font_user_data_t user_data; /**< Custom user data for font. */
#endif
} lv_font_t;
/**********************

View File

@@ -91,6 +91,8 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic
static uint8_t * buf = NULL;
uint32_t gsize = gdsc->box_w * gdsc->box_h;
if(gsize == 0) return NULL;
uint32_t buf_size = gsize;
switch(fdsc->bpp) {
case 1: buf_size = gsize >> 3; break;
@@ -138,7 +140,9 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t *
/*Put together a glyph dsc*/
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
uint32_t adv_w = gdsc->adv_w + ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
int32_t kv = ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
uint32_t adv_w = gdsc->adv_w + kv;
adv_w = (adv_w + (1 << 3)) >> 4;
dsc_out->adv_w = adv_w;

View File

@@ -191,6 +191,7 @@ typedef struct {
* from `lv_font_fmt_txt_bitmap_format_t`
*/
uint16_t bitmap_format :2;
uint16_t subpx :1;
/*Cache the last letter and is glyph id*/
uint32_t last_letter;

View File

@@ -268,14 +268,14 @@ bool lv_disp_get_antialiasing(lv_disp_t * disp)
*/
LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv)
{
disp_drv->buffer->flushing = 0;
/*If the screen is transparent initialize it when the flushing is ready*/
#if LV_COLOR_SCREEN_TRANSP
if(disp_drv->screen_transp) {
memset(disp_drv->buffer->buf_act, 0x00, disp_drv->buffer->size * sizeof(lv_color32_t));
}
#endif
disp_drv->buffer->flushing = 0;
}
/**

View File

@@ -303,21 +303,44 @@ static inline uint32_t lv_color_to32(lv_color_t color)
ret.ch.alpha = 0xFF;
return ret.full;
#elif LV_COLOR_DEPTH == 16
/**
* The floating point math for conversion is:
* valueto = valuefrom * ( (2^bitsto - 1) / (float)(2^bitsfrom - 1) )
* The faster integer math for conversion is:
* valueto = ( valuefrom * multiplier + adder ) >> divisor
* multiplier = FLOOR( ( (2^bitsto - 1) << divisor ) / (float)(2^bitsfrom - 1) )
*
* Find the first divisor where ( adder >> divisor ) <= 0
*
* 5-bit to 8-bit: ( 31 * multiplier + adder ) >> divisor = 255
* divisor multiplier adder min (0) max (31)
* 0 8 7 7 255
* 1 16 14 7 255
* 2 32 28 7 255
* 3 65 25 3 255
* 4 131 19 1 255
* 5 263 7 0 255
*
* 6-bit to 8-bit: 255 = ( 63 * multiplier + adder ) >> divisor
* divisor multiplier adder min (0) max (63)
* 0 4 3 3 255
* 1 8 6 3 255
* 2 16 12 3 255
* 3 32 24 3 255
* 4 64 48 3 255
* 5 129 33 1 255
* 6 259 3 0 255
*/
lv_color32_t ret;
ret.ch.red = ( color.ch.red * 263 + 7 ) >> 5;
#if LV_COLOR_16_SWAP == 0
lv_color32_t ret;
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.ch.green = color.ch.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.ch.alpha = 0xFF;
return ret.full;
ret.ch.green = ( color.ch.green * 259 + 3 ) >> 6;
#else
lv_color32_t ret;
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.ch.green = ((color.ch.green_h << 3) + color.ch.green_l) * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.ch.green = (((color.ch.green_h << 3) + color.ch.green_l) * 259 + 3 ) >> 6;
#endif
ret.ch.blue = ( color.ch.blue * 263 + 7 ) >> 5;
ret.ch.alpha = 0xFF;
return ret.full;
#endif
#elif LV_COLOR_DEPTH == 32
return color.full;
#endif

View File

@@ -26,14 +26,19 @@ extern "C" {
/*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/
enum {
LV_LOG_LEVEL_TRACE = 0, /**< A lot of logs to give detailed information*/
LV_LOG_LEVEL_INFO = 1, /**< Log important events*/
LV_LOG_LEVEL_WARN = 2, /**< Log if something unwanted happened but didn't caused problem*/
LV_LOG_LEVEL_ERROR = 3, /**< Only critical issue, when the system may fail*/
LV_LOG_LEVEL_NONE = 4, /**< Do not log anything*/
_LV_LOG_LEVEL_NUM = 5 /**< Number of log levels */
};
#define LV_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information*/
#define LV_LOG_LEVEL_INFO 1 /**< Log important events*/
#define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem*/
#define LV_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail*/
#define LV_LOG_LEVEL_NONE 4 /**< Do not log anything*/
#define _LV_LOG_LEVEL_NUM 5 /**< Number of log levels */
LV_EXPORT_CONST_INT(LV_LOG_LEVEL_TRACE);
LV_EXPORT_CONST_INT(LV_LOG_LEVEL_INFO);
LV_EXPORT_CONST_INT(LV_LOG_LEVEL_WARN);
LV_EXPORT_CONST_INT(LV_LOG_LEVEL_ERROR);
LV_EXPORT_CONST_INT(LV_LOG_LEVEL_NONE);
typedef int8_t lv_log_level_t;
#if LV_USE_LOG

View File

@@ -94,6 +94,29 @@ int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3)
return v1 + v2 + v3 + v4;
}
/**
* Calculate the integer square root of a number.
* @param num
* @return square root of 'num'
*/
uint32_t lv_sqrt(uint32_t num)
{
// http://www.codecodex.com/wiki/Calculate_an_integer_square_root#C
uint32_t root = 0;
uint32_t place = 0x40000000;
while(place > num) place >>= 2;
while(place) {
if(num >= root + place) {
num -= root + place;
root += (place << 1);
}
root >>= 1;
place >>= 2;
}
return root;
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@@ -54,6 +54,13 @@ int16_t lv_trigo_sin(int16_t angle);
*/
int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3);
/**
* Calculate the integer square root of a number.
* @param num
* @return square root of 'num'
*/
uint32_t lv_sqrt(uint32_t num);
/**********************
* MACROS
**********************/

View File

@@ -363,7 +363,7 @@ uint16_t lv_btn_get_ink_out_time(const lv_obj_t * btn)
#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
return ext->ink_in_time;
return ext->ink_out_time;
#else
(void)btn; /*Unused*/
return 0;

View File

@@ -880,6 +880,12 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
#if LV_USE_GROUP
lv_indev_t * indev = lv_indev_get_act();
lv_indev_type_t indev_type = lv_indev_get_type(indev);
/*If not focused by an input device assume the last input device*/
if(indev_type == LV_INDEV_TYPE_NONE) {
indev_type = lv_indev_get_type(lv_indev_get_next(NULL));
}
if(indev_type == LV_INDEV_TYPE_POINTER) {
/*Select the clicked button*/
lv_point_t p1;

View File

@@ -695,11 +695,37 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t * points, uint32_t
lv_disp_t * refr_ori = lv_refr_get_disp_refreshing();
lv_refr_set_disp_refreshing(&disp);
lv_style_t circle_style_tmp; /*If rounded...*/
if(style->line.rounded) {
lv_style_copy(&circle_style_tmp, style);
circle_style_tmp.body.radius = LV_RADIUS_CIRCLE;
circle_style_tmp.body.main_color = style->line.color;
circle_style_tmp.body.grad_color = style->line.color;
circle_style_tmp.body.opa = style->line.opa;
}
lv_area_t circle_area;
uint32_t i;
for(i = 0; i < point_cnt - 1; i++) {
lv_draw_line(&points[i], &points[i + 1], &mask, style, LV_OPA_COVER);
/*Draw circle on the joints if enabled*/
if(style->line.rounded) {
circle_area.x1 = points[i].x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
circle_area.y1 = points[i].y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
circle_area.x2 = points[i].x + ((style->line.width - 1) >> 1);
circle_area.y2 = points[i].y + ((style->line.width - 1) >> 1);
lv_draw_rect(&circle_area, &mask, &circle_style_tmp, LV_OPA_COVER);
}
}
/*Draw circle on the last point too if enabled*/
if(style->line.rounded) {
circle_area.x1 = points[i].x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
circle_area.y1 = points[i].y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);
circle_area.x2 = points[i].x + ((style->line.width - 1) >> 1);
circle_area.y2 = points[i].y + ((style->line.width - 1) >> 1);
lv_draw_rect(&circle_area, &mask, &circle_style_tmp, LV_OPA_COVER);
}
lv_refr_set_disp_refreshing(refr_ori);
}

View File

@@ -1001,6 +1001,7 @@ static void lv_ddlist_pos_current_option(lv_obj_t * ddlist)
*/
static void lv_ddlist_refr_width(lv_obj_t * ddlist)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
/*Save the current x coordinate because it should be kept after the refrsh*/
lv_coord_t x;
@@ -1015,6 +1016,12 @@ static void lv_ddlist_refr_width(lv_obj_t * ddlist)
if(lv_obj_get_base_dir(ddlist) == LV_BIDI_DIR_RTL) lv_obj_set_x(ddlist, x - lv_obj_get_width(ddlist));
else lv_obj_set_x(ddlist, x);
switch(lv_label_get_align(ext->label)) {
case LV_LABEL_ALIGN_LEFT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0); break;
case LV_LABEL_ALIGN_CENTER: lv_obj_align(ext->label, NULL, LV_ALIGN_CENTER, 0, 0); break;
case LV_LABEL_ALIGN_RIGHT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0); break;
}
}
#endif

View File

@@ -135,7 +135,6 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy)
void lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, const lv_color_t colors[])
{
LV_ASSERT_OBJ(gauge, LV_OBJX_NAME);
LV_ASSERT_NULL(colors);
lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);

View File

@@ -237,11 +237,13 @@ static bool lv_line_design(lv_obj_t * line, const lv_area_t * mask, lv_design_mo
uint16_t i;
lv_style_t circle_style_tmp; /*If rounded...*/
lv_style_copy(&circle_style_tmp, style);
circle_style_tmp.body.radius = LV_RADIUS_CIRCLE;
circle_style_tmp.body.main_color = style->line.color;
circle_style_tmp.body.grad_color = style->line.color;
circle_style_tmp.body.opa = style->line.opa;
if(style->line.rounded) {
lv_style_copy(&circle_style_tmp, style);
circle_style_tmp.body.radius = LV_RADIUS_CIRCLE;
circle_style_tmp.body.main_color = style->line.color;
circle_style_tmp.body.grad_color = style->line.color;
circle_style_tmp.body.opa = style->line.opa;
}
lv_area_t circle_area;
/*Read all points and draw the lines*/

View File

@@ -406,9 +406,11 @@ static void lv_spinbox_updatevalue(lv_obj_t * spinbox)
memset(buf, 0, sizeof(buf));
char * buf_p = buf;
/*Add the sign*/
(*buf_p) = ext->value >= 0 ? '+' : '-';
buf_p++;
if (ext->range_min < 0) { // hide sign if there are only positive values
/*Add the sign*/
(*buf_p) = ext->value >= 0 ? '+' : '-';
buf_p++;
}
int i;
/*padding left*/

View File

@@ -409,7 +409,11 @@ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t an
case LV_TABVIEW_BTNS_POS_LEFT:
case LV_TABVIEW_BTNS_POS_RIGHT:
indic_size = lv_obj_get_height(ext->indic);
indic_pos = tabs_style->body.padding.top + id * (indic_size + tabs_style->body.padding.inner);
const lv_style_t * style_tabs = lv_tabview_get_style(tabview, LV_TABVIEW_STYLE_BTN_BG);
lv_coord_t max_h = lv_obj_get_height(ext->btns) - style_tabs->body.padding.top - style_tabs->body.padding.bottom;
if(ext->tab_cnt) indic_pos = (max_h * ext->tab_cur) / ext->tab_cnt;
else indic_pos = 0;
break;
}
@@ -751,20 +755,21 @@ static lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * p
if(sign == LV_SIGNAL_FOCUS) {
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
/*If not focused by an input device assume the last input device*/
if(indev_type == LV_INDEV_TYPE_NONE) {
indev_type = lv_indev_get_type(lv_indev_get_next(NULL));
}
/*With ENCODER select the first button only in edit mode*/
if(indev_type == LV_INDEV_TYPE_ENCODER) {
#if LV_USE_GROUP
lv_group_t * g = lv_obj_get_group(tabview);
if(lv_group_get_editing(g)) {
lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btns);
btnm_ext->btn_id_pr = 0;
lv_obj_invalidate(ext->btns);
lv_btnm_set_pressed(ext->btns, ext->tab_cur);
}
#endif
} else {
lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btns);
btnm_ext->btn_id_pr = 0;
lv_obj_invalidate(ext->btns);
lv_btnm_set_pressed(ext->btns, ext->tab_cur);
}
}
} else if(sign == LV_SIGNAL_GET_EDITABLE) {