From a3bfdb240e3ef0f4364a6b7afdf6971d156972c9 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 13 May 2019 05:50:27 +0200 Subject: [PATCH 01/27] define LV_KEY_... as enum --- src/lv_core/lv_group.h | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/lv_core/lv_group.h b/src/lv_core/lv_group.h index 02edca0d2..c58ed48c4 100644 --- a/src/lv_core/lv_group.h +++ b/src/lv_core/lv_group.h @@ -25,19 +25,22 @@ extern "C" { * DEFINES *********************/ /*Predefined keys to control the focused object via lv_group_send(group, c)*/ -/*For compatibility in signal function define the keys regardless to LV_GROUP*/ -#define LV_KEY_UP 17 /*0x11*/ -#define LV_KEY_DOWN 18 /*0x12*/ -#define LV_KEY_RIGHT 19 /*0x13*/ -#define LV_KEY_LEFT 20 /*0x14*/ -#define LV_KEY_ESC 27 /*0x1B*/ -#define LV_KEY_DEL 127 /*0x7F*/ -#define LV_KEY_BACKSPACE 8 /*0x08*/ -#define LV_KEY_ENTER 10 /*0x0A, '\n'*/ -#define LV_KEY_NEXT 9 /*0x09, '\t'*/ -#define LV_KEY_PREV 11 /*0x0B, '*/ -#define LV_KEY_HOME 2 /*0x02, STX*/ -#define LV_KEY_END 3 /*0x03, ETX*/ +/*For compatibility in signal function define the keys regardless to `LV_USE_GROUP`*/ + +typedef enum { + LV_KEY_UP = 17, /*0x11*/ + LV_KEY_DOWN = 18, /*0x12*/ + LV_KEY_RIGHT = 19, /*0x13*/ + LV_KEY_LEFT = 20, /*0x14*/ + LV_KEY_ESC = 27, /*0x1B*/ + LV_KEY_DEL = 127, /*0x7F*/ + LV_KEY_BACKSPACE = 8, /*0x08*/ + LV_KEY_ENTER = 10, /*0x0A, '\n'*/ + LV_KEY_NEXT = 9, /*0x09, '\t'*/ + LV_KEY_PREV=11, /*0x0B, '*/ + LV_KEY_HOME = 2, /*0x02, STX*/ + LV_KEY_END = 3, /*0x03, ETX*/ +} lv_key_t; #if LV_USE_GROUP != 0 /********************** From d58c8663d4c35a3f0a75256fae0abf75c3e04c47 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 14 May 2019 06:34:20 +0200 Subject: [PATCH 02/27] start to reqork the image decoder interface --- lv_conf_template.h | 4 +- src/lv_core/lv_indev.c | 2 +- src/lv_draw/lv_draw_img.c | 505 ------------------------------ src/lv_draw/lv_draw_img.h | 95 +----- src/lv_misc/lv_gc.h | 1 + src/lv_misc/lv_img_decoder.c | 587 +++++++++++++++++++++++++++++++++++ src/lv_misc/lv_img_decoder.h | 165 ++++++++++ 7 files changed, 758 insertions(+), 601 deletions(-) create mode 100644 src/lv_misc/lv_img_decoder.c create mode 100644 src/lv_misc/lv_img_decoder.h diff --git a/lv_conf_template.h b/lv_conf_template.h index 908e18ce6..7eb4065f6 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -145,6 +145,9 @@ typedef void * lv_group_user_data_t; /* 1: Enable alpha indexed images */ #define LV_IMG_CF_ALPHA 1 +/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_img_decoder_user_data_t; + /*1: Add a `user_data` to drivers and objects*/ #define LV_USE_USER_DATA_SINGLE 1 @@ -165,7 +168,6 @@ typedef void * lv_group_user_data_t; * E.g. __attribute__((aligned(4))) */ #define LV_ATTRIBUTE_MEM_ALIGN - /* 1: Variable length array is supported*/ #define LV_COMPILER_VLA_SUPPORTED 1 diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 416937af8..b31bf1ff1 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -876,7 +876,7 @@ static void indev_proc_release(lv_indev_proc_t * proc) if(proc->reset_query != 0) return; - /*Handle click focus*/ + /*Handle click focus*/ #if LV_USE_GROUP /*Edit mode is not used by POINTER devices. So leave edit mode if we are in it*/ lv_group_t * g = lv_obj_get_group(proc->types.pointer.act_obj); diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index c09bf3279..ebc9b0e3e 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -7,7 +7,6 @@ * INCLUDES *********************/ #include "lv_draw_img.h" -#include "../lv_misc/lv_fs.h" /********************* * DEFINES @@ -23,33 +22,9 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style, lv_opa_t opa_scale); -static const uint8_t * lv_img_decoder_open(const void * src, const lv_style_t * style); -static lv_res_t lv_img_decoder_read_line(lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf); -static void lv_img_decoder_close(void); -static lv_res_t lv_img_built_in_decoder_line_alpha(lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf); -static lv_res_t lv_img_built_in_decoder_line_indexed(lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf); - /********************** * STATIC VARIABLES **********************/ -static bool decoder_custom; -static const void * decoder_src; -static lv_img_src_t decoder_src_type; -static lv_img_header_t decoder_header; -static const lv_style_t * decoder_style; -#if LV_USE_FILESYSTEM -static lv_fs_file_t decoder_file; -#endif -#if LV_IMG_CF_INDEXED -static lv_color_t decoder_index_map[256]; -#endif - -static lv_img_decoder_info_f_t lv_img_decoder_info_custom; -static lv_img_decoder_open_f_t lv_img_decoder_open_custom; -static lv_img_decoder_read_line_f_t lv_img_decoder_read_line_custom; -static lv_img_decoder_close_f_t lv_img_decoder_close_custom; /********************** * MACROS @@ -90,63 +65,6 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * } } -/** - * Initialize and `lv_img_dsc_t` variable with the image's info - * @param src variable, filename or symbol - * @param header store the result here - * @return LV_RES_OK: succeeded; LV_RES_INV: failed - */ -lv_res_t lv_img_dsc_get_info(const char * src, lv_img_header_t * header) -{ - header->always_zero = 0; - /*Try to get info with the custom functions first*/ - if(lv_img_decoder_info_custom) { - lv_res_t custom_res; - custom_res = lv_img_decoder_info_custom(src, header); - if(custom_res == LV_RES_OK) return LV_RES_OK; /*Custom info has supported this source*/ - } - - lv_img_src_t src_type = lv_img_src_get_type(src); - if(src_type == LV_IMG_SRC_VARIABLE) { - header->w = ((lv_img_dsc_t *)src)->header.w; - header->h = ((lv_img_dsc_t *)src)->header.h; - header->cf = ((lv_img_dsc_t *)src)->header.cf; - } -#if LV_USE_FILESYSTEM - else if(src_type == LV_IMG_SRC_FILE) { - lv_fs_file_t file; - lv_fs_res_t res; - uint32_t rn; - res = lv_fs_open(&file, src, LV_FS_MODE_RD); - if(res == LV_FS_RES_OK) { - res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn); - lv_fs_close(&file); - } - - /*Create a dummy header on fs error*/ - if(res != LV_FS_RES_OK || rn != sizeof(lv_img_header_t)) { - header->w = LV_DPI; - header->h = LV_DPI; - header->cf = LV_IMG_CF_UNKNOWN; - return LV_RES_INV; - } - } -#endif - else if(src_type == LV_IMG_SRC_SYMBOL) { - /*The size depend on the font but it is unknown here. It should be handled outside of the - * function*/ - header->w = 1; - header->h = 1; - /* Symbols always have transparent parts. Important because of cover check in the design - * function. The actual value doesn't matter because lv_draw_label will draw it*/ - header->cf = LV_IMG_CF_ALPHA_1BIT; - } else { - LV_LOG_WARN("Image get info found unknown src type"); - return LV_RES_INV; - } - return LV_RES_OK; -} - /** * Get the color of an image's pixel * @param dsc an image descriptor @@ -512,24 +430,6 @@ lv_img_src_t lv_img_src_get_type(const void * src) return img_src_type; } -/** - * Set custom decoder functions. See the typdefs of the function typed above for more info about - * them - * @param info_fp info get function - * @param open_fp open function - * @param read_fp read line function - * @param close_fp clode function - */ -void lv_img_decoder_set_custom(lv_img_decoder_info_f_t info_fp, lv_img_decoder_open_f_t open_fp, - lv_img_decoder_read_line_f_t read_fp, - lv_img_decoder_close_f_t close_fp) -{ - lv_img_decoder_info_custom = info_fp; - lv_img_decoder_open_custom = open_fp; - lv_img_decoder_read_line_custom = read_fp; - lv_img_decoder_close_custom = close_fp; -} - /********************** * STATIC FUNCTIONS **********************/ @@ -611,408 +511,3 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas return LV_RES_OK; } - -static const uint8_t * lv_img_decoder_open(const void * src, const lv_style_t * style) -{ - decoder_custom = false; - - /*Try to open with the custom functions first*/ - if(lv_img_decoder_open_custom) { - const uint8_t * custom_res; - custom_res = lv_img_decoder_open_custom(src, style); - if(custom_res != LV_IMG_DECODER_OPEN_FAIL) { - decoder_custom = - true; /*Mark that custom decoder function should be used for this img source.*/ - return custom_res; /*Custom open supported this source*/ - } - } - - decoder_src = src; - decoder_style = style; - decoder_src_type = lv_img_src_get_type(src); - - lv_res_t header_res; - header_res = lv_img_dsc_get_info(src, &decoder_header); - if(header_res == LV_RES_INV) { - decoder_src = NULL; - decoder_src_type = LV_IMG_SRC_UNKNOWN; - LV_LOG_WARN("Built-in image decoder can't get the header info"); - return LV_IMG_DECODER_OPEN_FAIL; - } - - /*Open the file if it's a file*/ - if(decoder_src_type == LV_IMG_SRC_FILE) { -#if LV_USE_FILESYSTEM - lv_fs_res_t res = lv_fs_open(&decoder_file, src, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) { - LV_LOG_WARN("Built-in image decoder can't open the file"); - return LV_IMG_DECODER_OPEN_FAIL; - } -#else - LV_LOG_WARN("Image built-in decoder can read file because LV_USE_FILESYSTEM = 0"); - return LV_IMG_DECODER_OPEN_FAIL; -#endif - } - - /*Process the different color formats*/ - lv_img_cf_t cf = decoder_header.cf; - if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_ALPHA || - cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) { - if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - /*In case of uncompressed formats if the image stored in the ROM/RAM simply give it's - * pointer*/ - return ((lv_img_dsc_t *)decoder_src)->data; - } else { - /*If it's file it need to be read line by line later*/ - return NULL; - } - } else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || - cf == LV_IMG_CF_INDEXED_4BIT || cf == LV_IMG_CF_INDEXED_8BIT) { - -#if LV_IMG_CF_INDEXED -#if LV_USE_FILESYSTEM - lv_color32_t palette_file[256]; -#endif - - lv_color32_t * palette_p = NULL; - uint8_t px_size = lv_img_color_format_get_px_size(cf); - uint32_t palette_size = 1 << px_size; - - if(decoder_src_type == LV_IMG_SRC_FILE) { - /*Read the palette from file*/ -#if LV_USE_FILESYSTEM - lv_fs_seek(&decoder_file, 4); /*Skip the header*/ - lv_fs_read(&decoder_file, palette_file, palette_size * sizeof(lv_color32_t), NULL); - palette_p = palette_file; -#else - LV_LOG_WARN( - "Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0"); - return LV_IMG_DECODER_OPEN_FAIL; -#endif - } else { - /*The palette begins in the beginning of the image data. Just point to it.*/ - palette_p = (lv_color32_t *)((lv_img_dsc_t *)decoder_src)->data; - } - - uint32_t i; - for(i = 0; i < palette_size; i++) { - decoder_index_map[i] = - lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue); - } - return NULL; -#else - LV_LOG_WARN("Indexed (palette) images are not enabled in lv_conf.h. See LV_IMG_CF_INDEXED"); - return LV_IMG_DECODER_OPEN_FAIL; -#endif - } else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || - cf == LV_IMG_CF_ALPHA_4BIT || cf == LV_IMG_CF_ALPHA_8BIT) { -#if LV_IMG_CF_ALPHA - return NULL; /*Nothing to process*/ -#else - LV_LOG_WARN("Alpha indexed images are not enabled in lv_conf.h. See LV_IMG_CF_ALPHA"); - return LV_IMG_DECODER_OPEN_FAIL; -#endif - } else { - LV_LOG_WARN("Image decoder open: unknown color format") - return LV_IMG_DECODER_OPEN_FAIL; - } -} - -static lv_res_t lv_img_decoder_read_line(lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) -{ - /*Try to read the line with the custom functions*/ - if(decoder_custom) { - if(lv_img_decoder_read_line_custom) { - lv_res_t custom_res; - custom_res = lv_img_decoder_read_line_custom(x, y, len, buf); - return custom_res; - } else { - LV_LOG_WARN("Image open with custom decoder but read not supported") - } - return LV_RES_INV; /*It"s an error if not returned earlier*/ - } - - if(decoder_src_type == LV_IMG_SRC_FILE) { -#if LV_USE_FILESYSTEM - uint8_t px_size = lv_img_color_format_get_px_size(decoder_header.cf); - - lv_fs_res_t res; - - if(decoder_header.cf == LV_IMG_CF_TRUE_COLOR || - decoder_header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA || - decoder_header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) { - uint32_t pos = ((y * decoder_header.w + x) * px_size) >> 3; - pos += 4; /*Skip the header*/ - res = lv_fs_seek(&decoder_file, pos); - if(res != LV_FS_RES_OK) { - LV_LOG_WARN("Built-in image decoder seek failed"); - return false; - } - uint32_t btr = len * (px_size >> 3); - uint32_t br = 0; - lv_fs_read(&decoder_file, buf, btr, &br); - if(res != LV_FS_RES_OK || btr != br) { - LV_LOG_WARN("Built-in image decoder read failed"); - return false; - } - } else if(decoder_header.cf == LV_IMG_CF_ALPHA_1BIT || - decoder_header.cf == LV_IMG_CF_ALPHA_2BIT || - decoder_header.cf == LV_IMG_CF_ALPHA_4BIT || - decoder_header.cf == LV_IMG_CF_ALPHA_8BIT) { - - lv_img_built_in_decoder_line_alpha(x, y, len, buf); - } else if(decoder_header.cf == LV_IMG_CF_INDEXED_1BIT || - decoder_header.cf == LV_IMG_CF_INDEXED_2BIT || - decoder_header.cf == LV_IMG_CF_INDEXED_4BIT || - decoder_header.cf == LV_IMG_CF_INDEXED_8BIT) { - lv_img_built_in_decoder_line_indexed(x, y, len, buf); - } else { - LV_LOG_WARN("Built-in image decoder read not supports the color format"); - return false; - } -#else - LV_LOG_WARN("Image built-in decoder can't read file because LV_USE_FILESYSTEM = 0"); - return false; -#endif - } else if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - const lv_img_dsc_t * img_dsc = decoder_src; - - if(img_dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || - img_dsc->header.cf == LV_IMG_CF_ALPHA_2BIT || - img_dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || - img_dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { - lv_img_built_in_decoder_line_alpha(x, y, len, buf); - } else if(img_dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || - img_dsc->header.cf == LV_IMG_CF_INDEXED_2BIT || - img_dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || - img_dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { - lv_img_built_in_decoder_line_indexed(x, y, len, buf); - } else { - LV_LOG_WARN("Built-in image decoder not supports the color format"); - return false; - } - } - - return true; -} - -static void lv_img_decoder_close(void) -{ - /*Try to close with the custom functions*/ - if(decoder_custom) { - if(lv_img_decoder_close_custom) lv_img_decoder_close_custom(); - return; - } - - /*It was opened with built-in decoder*/ - if(decoder_src) { -#if LV_USE_FILESYSTEM - if(decoder_src_type == LV_IMG_SRC_FILE) { - lv_fs_close(&decoder_file); - } -#endif - decoder_src_type = LV_IMG_SRC_UNKNOWN; - decoder_src = NULL; - } -} - -static lv_res_t lv_img_built_in_decoder_line_alpha(lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf) -{ - -#if LV_IMG_CF_ALPHA - const lv_opa_t alpha1_opa_table[2] = { - 0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/ - const lv_opa_t alpha2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/ - const lv_opa_t alpha4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/ - 68, 85, 102, 119, 136, 153, - 170, 187, 204, 221, 238, 255}; - - /*Simply fill the buffer with the color. Later only the alpha value will be modified.*/ - lv_color_t bg_color = decoder_style->image.color; - lv_coord_t i; - for(i = 0; i < len; i++) { -#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1 - buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full; -#elif LV_COLOR_DEPTH == 16 - /*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/ - buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full & 0xFF; - buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (bg_color.full >> 8) & 0xFF; -#elif LV_COLOR_DEPTH == 32 - *((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = bg_color.full; -#else -#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h" -#endif - } - - const lv_opa_t * opa_table = NULL; - uint8_t px_size = lv_img_color_format_get_px_size(decoder_header.cf); - uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/ - - lv_coord_t w = 0; - uint32_t ofs = 0; - int8_t pos = 0; - switch(decoder_header.cf) { - case LV_IMG_CF_ALPHA_1BIT: - w = (decoder_header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ - if(decoder_header.w & 0x7) w++; - ofs += w * y + (x >> 3); /*First pixel*/ - pos = 7 - (x & 0x7); - opa_table = alpha1_opa_table; - break; - case LV_IMG_CF_ALPHA_2BIT: - w = (decoder_header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ - if(decoder_header.w & 0x3) w++; - ofs += w * y + (x >> 2); /*First pixel*/ - pos = 6 - ((x & 0x3) * 2); - opa_table = alpha2_opa_table; - break; - case LV_IMG_CF_ALPHA_4BIT: - w = (decoder_header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ - if(decoder_header.w & 0x1) w++; - ofs += w * y + (x >> 1); /*First pixel*/ - pos = 4 - ((x & 0x1) * 4); - opa_table = alpha4_opa_table; - break; - case LV_IMG_CF_ALPHA_8BIT: - w = decoder_header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ - ofs += w * y + x; /*First pixel*/ - pos = 0; - break; - } - -#if LV_USE_FILESYSTEM -#if LV_COMPILER_VLA_SUPPORTED - uint8_t fs_buf[w]; -#else - uint8_t fs_buf[LV_HOR_RES_MAX]; -#endif -#endif - const uint8_t * data_tmp = NULL; - if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - const lv_img_dsc_t * img_dsc = decoder_src; - data_tmp = img_dsc->data + ofs; - } else { -#if LV_USE_FILESYSTEM - lv_fs_seek(&decoder_file, ofs + 4); /*+4 to skip the header*/ - lv_fs_read(&decoder_file, fs_buf, w, NULL); - data_tmp = fs_buf; -#else - LV_LOG_WARN( - "Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0"); - data_tmp = NULL; /*To avoid warnings*/ - return LV_RES_INV; -#endif - } - - uint8_t byte_act = 0; - uint8_t val_act; - for(i = 0; i < len; i++) { - val_act = (data_tmp[byte_act] & (mask << pos)) >> pos; - - buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = - decoder_header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act]; - - pos -= px_size; - if(pos < 0) { - pos = 8 - px_size; - data_tmp++; - } - } - - return LV_RES_OK; - -#else - LV_LOG_WARN( - "Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h"); - return LV_RES_INV; -#endif -} - -static lv_res_t lv_img_built_in_decoder_line_indexed(lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf) -{ - -#if LV_IMG_CF_INDEXED - uint8_t px_size = lv_img_color_format_get_px_size(decoder_header.cf); - uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/ - - lv_coord_t w = 0; - int8_t pos = 0; - uint32_t ofs = 0; - switch(decoder_header.cf) { - case LV_IMG_CF_INDEXED_1BIT: - w = (decoder_header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ - if(decoder_header.w & 0x7) w++; - ofs += w * y + (x >> 3); /*First pixel*/ - ofs += 8; /*Skip the palette*/ - pos = 7 - (x & 0x7); - break; - case LV_IMG_CF_INDEXED_2BIT: - w = (decoder_header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ - if(decoder_header.w & 0x3) w++; - ofs += w * y + (x >> 2); /*First pixel*/ - ofs += 16; /*Skip the palette*/ - pos = 6 - ((x & 0x3) * 2); - break; - case LV_IMG_CF_INDEXED_4BIT: - w = (decoder_header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ - if(decoder_header.w & 0x1) w++; - ofs += w * y + (x >> 1); /*First pixel*/ - ofs += 64; /*Skip the palette*/ - pos = 4 - ((x & 0x1) * 4); - break; - case LV_IMG_CF_INDEXED_8BIT: - w = decoder_header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ - ofs += w * y + x; /*First pixel*/ - ofs += 1024; /*Skip the palette*/ - pos = 0; - break; - } - -#if LV_USE_FILESYSTEM -#if LV_COMPILER_VLA_SUPPORTED - uint8_t fs_buf[w]; -#else - uint8_t fs_buf[LV_HOR_RES_MAX]; -#endif -#endif - const uint8_t * data_tmp = NULL; - if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - const lv_img_dsc_t * img_dsc = decoder_src; - data_tmp = img_dsc->data + ofs; - } else { -#if LV_USE_FILESYSTEM - lv_fs_seek(&decoder_file, ofs + 4); /*+4 to skip the header*/ - lv_fs_read(&decoder_file, fs_buf, w, NULL); - data_tmp = fs_buf; -#else - LV_LOG_WARN( - "Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0"); - data_tmp = NULL; /*To avoid warnings*/ - return LV_RES_INV; -#endif - } - - uint8_t byte_act = 0; - uint8_t val_act; - lv_coord_t i; - lv_color_t * cbuf = (lv_color_t *)buf; - for(i = 0; i < len; i++) { - val_act = (data_tmp[byte_act] & (mask << pos)) >> pos; - cbuf[i] = decoder_index_map[val_act]; - - pos -= px_size; - if(pos < 0) { - pos = 8 - px_size; - data_tmp++; - } - } - - return LV_RES_OK; -#else - LV_LOG_WARN( - "Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h"); - return LV_RES_INV; -#endif -} diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 33d332d23..43c1a13df 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -15,108 +15,15 @@ extern "C" { *********************/ #include "lv_draw.h" #include "../lv_core/lv_obj.h" +#include "../lv_misc/lv_img_decoder.h" /********************* * DEFINES *********************/ -#define LV_IMG_DECODER_OPEN_FAIL ((void *)(-1)) /********************** * TYPEDEFS **********************/ -struct _lv_img_t; - -typedef struct -{ - - /* The first 8 bit is very important to distinguish the different source types. - * For more info see `lv_img_get_src_type()` in lv_img.c */ - uint32_t cf : 5; /* Color format: See `lv_img_color_format_t`*/ - uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a - non-printable character*/ - - uint32_t reserved : 2; /*Reserved to be used later*/ - - uint32_t w : 11; /*Width of the image map*/ - uint32_t h : 11; /*Height of the image map*/ -} lv_img_header_t; - -/*Image color format*/ -enum { - LV_IMG_CF_UNKNOWN = 0, - - LV_IMG_CF_RAW, /*Contains the file as it is. Needs custom decoder function*/ - LV_IMG_CF_RAW_ALPHA, /*Contains the file as it is. The image has alpha. Needs custom decoder - function*/ - LV_IMG_CF_RAW_CHROMA_KEYED, /*Contains the file as it is. The image is chroma keyed. Needs - custom decoder function*/ - - LV_IMG_CF_TRUE_COLOR, /*Color format and depth should match with LV_COLOR settings*/ - LV_IMG_CF_TRUE_COLOR_ALPHA, /*Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/ - LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /*Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels - will be transparent*/ - - LV_IMG_CF_INDEXED_1BIT, /*Can have 2 different colors in a palette (always chroma keyed)*/ - LV_IMG_CF_INDEXED_2BIT, /*Can have 4 different colors in a palette (always chroma keyed)*/ - LV_IMG_CF_INDEXED_4BIT, /*Can have 16 different colors in a palette (always chroma keyed)*/ - LV_IMG_CF_INDEXED_8BIT, /*Can have 256 different colors in a palette (always chroma keyed)*/ - - LV_IMG_CF_ALPHA_1BIT, /*Can have one color and it can be drawn or not*/ - LV_IMG_CF_ALPHA_2BIT, /*Can have one color but 4 different alpha value*/ - LV_IMG_CF_ALPHA_4BIT, /*Can have one color but 16 different alpha value*/ - LV_IMG_CF_ALPHA_8BIT, /*Can have one color but 256 different alpha value*/ -}; -typedef uint8_t lv_img_cf_t; - -/* Image header it is compatible with - * the result image converter utility*/ -typedef struct -{ - lv_img_header_t header; - uint32_t data_size; - const uint8_t * data; -} lv_img_dsc_t; - -/* Decoder function definitions */ - -/** - * Get info from an image and store in the `header` - * @param src the image source. Can be a pointer to a C array or a file name (Use - * `lv_img_src_get_type` to determine the type) - * @param header store the info here - * @return LV_RES_OK: info written correctly; LV_RES_INV: failed - */ -typedef lv_res_t (*lv_img_decoder_info_f_t)(const void * src, lv_img_header_t * header); - -/** - * Open an image for decoding. Prepare it as it is required to read it later - * @param src the image source. Can be a pointer to a C array or a file name (Use - * `lv_img_src_get_type` to determine the type) - * @param style the style of image (maybe it will be required to determine a color or something) - * @return there are 3 possible return values: - * 1) buffer with the decoded image - * 2) if can decode the whole image NULL. decoder_read_line will be called to read the image - * line-by-line 3) LV_IMG_DECODER_OPEN_FAIL if the image format is unknown to the decoder or an - * error occurred - */ -typedef const uint8_t * (*lv_img_decoder_open_f_t)(const void * src, const lv_style_t * style); - -/** - * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`. - * Required only if the "open" function can't return with the whole decoded pixel array. - * @param x start x coordinate - * @param y startt y coordinate - * @param len number of pixels to decode - * @param buf a buffer to store the decoded pixels - * @return LV_RES_OK: ok; LV_RES_INV: failed - */ -typedef lv_res_t (*lv_img_decoder_read_line_f_t)(lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf); - -/** - * Close the pending decoding. Free resources etc. - */ -typedef void (*lv_img_decoder_close_f_t)(void); /********************** * GLOBAL PROTOTYPES diff --git a/src/lv_misc/lv_gc.h b/src/lv_misc/lv_gc.h index 97aeb6b79..ac9d93f3d 100644 --- a/src/lv_misc/lv_gc.h +++ b/src/lv_misc/lv_gc.h @@ -37,6 +37,7 @@ extern "C" { prefix lv_ll_t _lv_file_ll; \ prefix lv_ll_t _lv_anim_ll; \ prefix lv_ll_t _lv_group_ll; \ + prefix lv_ll_t _lv_img_defoder_ll; \ prefix void * _lv_task_act; #define LV_NO_PREFIX diff --git a/src/lv_misc/lv_img_decoder.c b/src/lv_misc/lv_img_decoder.c new file mode 100644 index 000000000..d0a045407 --- /dev/null +++ b/src/lv_misc/lv_img_decoder.c @@ -0,0 +1,587 @@ +/** + * @file lv_img_decoder.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_img_decoder.h" +#include "lv_ll.h" + +#if defined(LV_GC_INCLUDE) +#include LV_GC_INCLUDE +#endif /* LV_ENABLE_GC */ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +/** + * Initialize the image decoder module + * */ +void lv_img_decoder_init(void) +{ + lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t)); + + lv_img_decoder_t decoder; + + /*Create a decoder for true color images*/ + decoder = lv_img_decoder_craete(); + if(decoder) return; + + /*Create a decoder for Alpha indexed images*/ + decoder = lv_img_decoder_craete(); + if(decoder) return; + + /*Create a decoder for color indexed images*/ + decoder = lv_img_decoder_craete(); + if(decoder) return; + +} + +lv_img_decoder_t * lv_img_decoder_craete(void) +{ + lv_img_decoder_t * decoder; + decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll)); + lv_mem_assert(decoder); + + return decoder; +} + +void lv_img_decoder_delete(lv_img_decoder_t * decoder) +{ + lv_ll_rem(&LV_GC_ROOT(_lv_img_defoder_ll), decoder); + lv_mem_free(decoder); +} + +void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb) +{ + decoder->info_cb = info_cb; +} + +void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb) +{ + decoder->open_cb = open_cb; +} + +void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb) +{ + decoder->read_line_cb = read_line_cb; +} + +void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb) +{ + decoder->read_line_cb = close_cb; +} + +void lv_img_decoder_set_user_data(lv_img_decoder_t * decoder, lv_img_decoder_t user_data) +{ + memcpy(&decoder->user_data, &user_data, sizeof(user_data)); +} + +lv_img_decoder_t lv_img_decoder_get_user_data(lv_img_decoder_t * decoder) +{ + return decoder->user_data; +} + +lv_img_decoder_t * lv_img_decoder_get_user_data_ptr(lv_img_decoder_t * decoder) +{ + return &decoder->user_data; +} + + +lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) +{ + header->always_zero = 0; + + lv_res_t res; + lv_img_decoder_t * d; + LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) { + res = LV_RES_INV; + if(d->info_cb) { + res = d->info_cb(d, src, header); + if(res == LV_RES_OK) break; + } + } + + return res; +} + + +const uint8_t * lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style) +{ + dsc->style = style; + dsc->src = src; + dsc->src_type = lv_img_src_get_type(src); + + lv_res_t header_res; + header_res = lv_img_decoder_get_info(src, &dsc->header); + if(header_res != LV_RES_OK) return LV_IMG_DECODER_OPEN_FAIL; + + const uint8_t * res = NULL; + lv_img_decoder_t * d; + LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d) { + res = NULL; + dsc->decoder = d; + if(d->open_cb) res = d->open_cb(d, dsc); + + if(res != LV_IMG_DECODER_OPEN_FAIL) break; + } +} + +static lv_res_t lv_img_decoder_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) +{ + lv_res_t res = LV_RES_INV; + if(decoder->read_line_cb)res = decoder->read_line_cb(decoder, dsc, x, y, len, buf); + + return res; +} + +static void lv_img_decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc) +{ + if(decoder->close_cb) decoder->close_cb(decoder, dsc); +} + + +static lv_res_t img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header) +{ + lv_img_src_t src_type = lv_img_src_get_type(src); + if(src_type == LV_IMG_SRC_VARIABLE) { + header->w = ((lv_img_dsc_t *)src)->header.w; + header->h = ((lv_img_dsc_t *)src)->header.h; + header->cf = ((lv_img_dsc_t *)src)->header.cf; + } + #if LV_USE_FILESYSTEM + else if(src_type == LV_IMG_SRC_FILE) { + lv_fs_file_t file; + lv_fs_res_t res; + uint32_t rn; + res = lv_fs_open(&file, src, LV_FS_MODE_RD); + if(res == LV_FS_RES_OK) { + res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn); + lv_fs_close(&file); + } + + /*Create a dummy header on fs error*/ + if(res != LV_FS_RES_OK || rn != sizeof(lv_img_header_t)) { + header->w = LV_DPI; + header->h = LV_DPI; + header->cf = LV_IMG_CF_UNKNOWN; + return LV_RES_INV; + } + } + #endif + else if(src_type == LV_IMG_SRC_SYMBOL) { + /*The size depend on the font but it is unknown here. It should be handled outside of the + * function*/ + header->w = 1; + header->h = 1; + /* Symbols always have transparent parts. Important because of cover check in the design + * function. The actual value doesn't matter because lv_draw_label will draw it*/ + header->cf = LV_IMG_CF_ALPHA_1BIT; + } else { + LV_LOG_WARN("Image get info found unknown src type"); + return LV_RES_INV; + } + return LV_RES_OK; +} + +static uint8_t * img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc,) +{ + if(header_res == LV_RES_INV) { + decoder_src = NULL; + decoder_src_type = LV_IMG_SRC_UNKNOWN; + LV_LOG_WARN("Built-in image decoder can't get the header info"); + return LV_IMG_DECODER_OPEN_FAIL; + } + + /*Open the file if it's a file*/ + if(decoder_src_type == LV_IMG_SRC_FILE) { +#if LV_USE_FILESYSTEM + lv_fs_res_t res = lv_fs_open(&decoder_file, src, LV_FS_MODE_RD); + if(res != LV_FS_RES_OK) { + LV_LOG_WARN("Built-in image decoder can't open the file"); + return LV_IMG_DECODER_OPEN_FAIL; + } +#else + LV_LOG_WARN("Image built-in decoder can read file because LV_USE_FILESYSTEM = 0"); + return LV_IMG_DECODER_OPEN_FAIL; +#endif + } + + /*Process the different color formats*/ + lv_img_cf_t cf = decoder_header.cf; + if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_ALPHA || + cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) { + if(decoder_src_type == LV_IMG_SRC_VARIABLE) { + /*In case of uncompressed formats if the image stored in the ROM/RAM simply give it's + * pointer*/ + return ((lv_img_dsc_t *)decoder_src)->data; + } else { + /*If it's file it need to be read line by line later*/ + return NULL; + } + } else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || + cf == LV_IMG_CF_INDEXED_4BIT || cf == LV_IMG_CF_INDEXED_8BIT) { + +#if LV_IMG_CF_INDEXED +#if LV_USE_FILESYSTEM + lv_color32_t palette_file[256]; +#endif + + lv_color32_t * palette_p = NULL; + uint8_t px_size = lv_img_color_format_get_px_size(cf); + uint32_t palette_size = 1 << px_size; + + if(decoder_src_type == LV_IMG_SRC_FILE) { + /*Read the palette from file*/ +#if LV_USE_FILESYSTEM + lv_fs_seek(&decoder_file, 4); /*Skip the header*/ + lv_fs_read(&decoder_file, palette_file, palette_size * sizeof(lv_color32_t), NULL); + palette_p = palette_file; +#else + LV_LOG_WARN( + "Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0"); + return LV_IMG_DECODER_OPEN_FAIL; +#endif + } else { + /*The palette begins in the beginning of the image data. Just point to it.*/ + palette_p = (lv_color32_t *)((lv_img_dsc_t *)decoder_src)->data; + } + + uint32_t i; + for(i = 0; i < palette_size; i++) { + decoder_index_map[i] = + lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue); + } + return NULL; +#else + LV_LOG_WARN("Indexed (palette) images are not enabled in lv_conf.h. See LV_IMG_CF_INDEXED"); + return LV_IMG_DECODER_OPEN_FAIL; +#endif + } else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || + cf == LV_IMG_CF_ALPHA_4BIT || cf == LV_IMG_CF_ALPHA_8BIT) { +#if LV_IMG_CF_ALPHA + return NULL; /*Nothing to process*/ +#else + LV_LOG_WARN("Alpha indexed images are not enabled in lv_conf.h. See LV_IMG_CF_ALPHA"); + return LV_IMG_DECODER_OPEN_FAIL; +#endif + } else { + LV_LOG_WARN("Image decoder open: unknown color format") + return LV_IMG_DECODER_OPEN_FAIL; + } +} + + +static lv_res_t lv_img_decoder_built_in_line_read(lv_img_decoder_t * decoder, lv_coord_t x, lv_coord_t y, lv_coord_t len, + uint8_t * buf) +{ + if(dsc->src_type == LV_IMG_SRC_FILE) { + #if LV_USE_FILESYSTEM + uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf); + + lv_fs_res_t res; + + if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) + { + uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3; + pos += 4; /*Skip the header*/ + res = lv_fs_seek(&decoder_file, pos); + if(res != LV_FS_RES_OK) { + LV_LOG_WARN("Built-in image decoder seek failed"); + return false; + } + uint32_t btr = len * (px_size >> 3); + uint32_t br = 0; + lv_fs_read(&decoder_file, buf, btr, &br); + if(res != LV_FS_RES_OK || btr != br) { + LV_LOG_WARN("Built-in image decoder read failed"); + return false; + } + } else if(decoder_header.cf == LV_IMG_CF_ALPHA_1BIT || + decoder_header.cf == LV_IMG_CF_ALPHA_2BIT || + decoder_header.cf == LV_IMG_CF_ALPHA_4BIT || + decoder_header.cf == LV_IMG_CF_ALPHA_8BIT) { + + lv_img_built_in_decoder_line_alpha(x, y, len, buf); + } else if(decoder_header.cf == LV_IMG_CF_INDEXED_1BIT || + decoder_header.cf == LV_IMG_CF_INDEXED_2BIT || + decoder_header.cf == LV_IMG_CF_INDEXED_4BIT || + decoder_header.cf == LV_IMG_CF_INDEXED_8BIT) { + lv_img_built_in_decoder_line_indexed(x, y, len, buf); + } else { + LV_LOG_WARN("Built-in image decoder read not supports the color format"); + return false; + } + #else + LV_LOG_WARN("Image built-in decoder can't read file because LV_USE_FILESYSTEM = 0"); + return false; + #endif + } else if(decoder_src_type == LV_IMG_SRC_VARIABLE) { + const lv_img_dsc_t * img_dsc = decoder_src; + + if(img_dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || + img_dsc->header.cf == LV_IMG_CF_ALPHA_2BIT || + img_dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || + img_dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { + lv_img_built_in_decoder_line_alpha(x, y, len, buf); + } else if(img_dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || + img_dsc->header.cf == LV_IMG_CF_INDEXED_2BIT || + img_dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || + img_dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { + lv_img_built_in_decoder_line_indexed(x, y, len, buf); + } else { + LV_LOG_WARN("Built-in image decoder not supports the color format"); + return false; + } + } + + return true; +} + +static void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc) +{ + + /*It was opened with built-in decoder*/ + if(decoder_src) { +#if LV_USE_FILESYSTEM + if(decoder_src_type == LV_IMG_SRC_FILE) { + lv_fs_close(&decoder_file); + } +#endif + decoder_src_type = LV_IMG_SRC_UNKNOWN; + decoder_src = NULL; + } +} + + +static lv_res_t lv_img_built_in_decoder_line_alpha(lv_img_decoder_t * decoder, lv_coord_t x, lv_coord_t y, lv_coord_t len, + uint8_t * buf) +{ + +#if LV_IMG_CF_ALPHA + const lv_opa_t alpha1_opa_table[2] = { + 0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/ + const lv_opa_t alpha2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/ + const lv_opa_t alpha4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/ + 68, 85, 102, 119, 136, 153, + 170, 187, 204, 221, 238, 255}; + + /*Simply fill the buffer with the color. Later only the alpha value will be modified.*/ + lv_color_t bg_color = decoder_style->image.color; + lv_coord_t i; + for(i = 0; i < len; i++) { +#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1 + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full; +#elif LV_COLOR_DEPTH == 16 + /*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/ + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full & 0xFF; + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (bg_color.full >> 8) & 0xFF; +#elif LV_COLOR_DEPTH == 32 + *((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = bg_color.full; +#else +#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h" +#endif + } + + const lv_opa_t * opa_table = NULL; + uint8_t px_size = lv_img_color_format_get_px_size(decoder_header.cf); + uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/ + + lv_coord_t w = 0; + uint32_t ofs = 0; + int8_t pos = 0; + switch(decoder_header.cf) { + case LV_IMG_CF_ALPHA_1BIT: + w = (decoder_header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ + if(decoder_header.w & 0x7) w++; + ofs += w * y + (x >> 3); /*First pixel*/ + pos = 7 - (x & 0x7); + opa_table = alpha1_opa_table; + break; + case LV_IMG_CF_ALPHA_2BIT: + w = (decoder_header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ + if(decoder_header.w & 0x3) w++; + ofs += w * y + (x >> 2); /*First pixel*/ + pos = 6 - ((x & 0x3) * 2); + opa_table = alpha2_opa_table; + break; + case LV_IMG_CF_ALPHA_4BIT: + w = (decoder_header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ + if(decoder_header.w & 0x1) w++; + ofs += w * y + (x >> 1); /*First pixel*/ + pos = 4 - ((x & 0x1) * 4); + opa_table = alpha4_opa_table; + break; + case LV_IMG_CF_ALPHA_8BIT: + w = decoder_header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ + ofs += w * y + x; /*First pixel*/ + pos = 0; + break; + } + +#if LV_USE_FILESYSTEM +#if LV_COMPILER_VLA_SUPPORTED + uint8_t fs_buf[w]; +#else + uint8_t fs_buf[LV_HOR_RES_MAX]; +#endif +#endif + const uint8_t * data_tmp = NULL; + if(decoder_src_type == LV_IMG_SRC_VARIABLE) { + const lv_img_dsc_t * img_dsc = decoder_src; + data_tmp = img_dsc->data + ofs; + } else { +#if LV_USE_FILESYSTEM + lv_fs_seek(&decoder_file, ofs + 4); /*+4 to skip the header*/ + lv_fs_read(&decoder_file, fs_buf, w, NULL); + data_tmp = fs_buf; +#else + LV_LOG_WARN( + "Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0"); + data_tmp = NULL; /*To avoid warnings*/ + return LV_RES_INV; +#endif + } + + uint8_t byte_act = 0; + uint8_t val_act; + for(i = 0; i < len; i++) { + val_act = (data_tmp[byte_act] & (mask << pos)) >> pos; + + buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = + decoder_header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act]; + + pos -= px_size; + if(pos < 0) { + pos = 8 - px_size; + data_tmp++; + } + } + + return LV_RES_OK; + +#else + LV_LOG_WARN( + "Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h"); + return LV_RES_INV; +#endif +} + +static lv_res_t lv_img_built_in_decoder_line_indexed(lv_img_decoder_t * decoder, lv_coord_t x, lv_coord_t y, lv_coord_t len, + uint8_t * buf) +{ + +#if LV_IMG_CF_INDEXED + uint8_t px_size = lv_img_color_format_get_px_size(decoder_header.cf); + uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/ + + lv_coord_t w = 0; + int8_t pos = 0; + uint32_t ofs = 0; + switch(decoder_header.cf) { + case LV_IMG_CF_INDEXED_1BIT: + w = (decoder_header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ + if(decoder_header.w & 0x7) w++; + ofs += w * y + (x >> 3); /*First pixel*/ + ofs += 8; /*Skip the palette*/ + pos = 7 - (x & 0x7); + break; + case LV_IMG_CF_INDEXED_2BIT: + w = (decoder_header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ + if(decoder_header.w & 0x3) w++; + ofs += w * y + (x >> 2); /*First pixel*/ + ofs += 16; /*Skip the palette*/ + pos = 6 - ((x & 0x3) * 2); + break; + case LV_IMG_CF_INDEXED_4BIT: + w = (decoder_header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ + if(decoder_header.w & 0x1) w++; + ofs += w * y + (x >> 1); /*First pixel*/ + ofs += 64; /*Skip the palette*/ + pos = 4 - ((x & 0x1) * 4); + break; + case LV_IMG_CF_INDEXED_8BIT: + w = decoder_header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ + ofs += w * y + x; /*First pixel*/ + ofs += 1024; /*Skip the palette*/ + pos = 0; + break; + } + +#if LV_USE_FILESYSTEM +#if LV_COMPILER_VLA_SUPPORTED + uint8_t fs_buf[w]; +#else + uint8_t fs_buf[LV_HOR_RES_MAX]; +#endif +#endif + const uint8_t * data_tmp = NULL; + if(decoder_src_type == LV_IMG_SRC_VARIABLE) { + const lv_img_dsc_t * img_dsc = decoder_src; + data_tmp = img_dsc->data + ofs; + } else { +#if LV_USE_FILESYSTEM + lv_fs_seek(&decoder_file, ofs + 4); /*+4 to skip the header*/ + lv_fs_read(&decoder_file, fs_buf, w, NULL); + data_tmp = fs_buf; +#else + LV_LOG_WARN( + "Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0"); + data_tmp = NULL; /*To avoid warnings*/ + return LV_RES_INV; +#endif + } + + uint8_t byte_act = 0; + uint8_t val_act; + lv_coord_t i; + lv_color_t * cbuf = (lv_color_t *)buf; + for(i = 0; i < len; i++) { + val_act = (data_tmp[byte_act] & (mask << pos)) >> pos; + cbuf[i] = decoder_index_map[val_act]; + + pos -= px_size; + if(pos < 0) { + pos = 8 - px_size; + data_tmp++; + } + } + + return LV_RES_OK; +#else + LV_LOG_WARN( + "Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h"); + return LV_RES_INV; +#endif +} + + + + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/src/lv_misc/lv_img_decoder.h b/src/lv_misc/lv_img_decoder.h new file mode 100644 index 000000000..7432a4342 --- /dev/null +++ b/src/lv_misc/lv_img_decoder.h @@ -0,0 +1,165 @@ +/** + * @file lv_img_decoder.h + * + */ + +#ifndef LV_IMG_DEOCER_H +#define LV_IMG_DEOCER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#ifdef LV_CONF_INCLUDE_SIMPLE +#include "lv_conf.h" +#else +#include "../../../lv_conf.h" +#endif + +#include +#include "lv_fs.h" + +/********************* + * DEFINES + *********************/ +#define LV_IMG_DECODER_OPEN_FAIL ((void *)(-1)); + +/********************** + * TYPEDEFS + **********************/ +typedef struct +{ + + /* The first 8 bit is very important to distinguish the different source types. + * For more info see `lv_img_get_src_type()` in lv_img.c */ + uint32_t cf : 5; /* Color format: See `lv_img_color_format_t`*/ + uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a + non-printable character*/ + + uint32_t reserved : 2; /*Reserved to be used later*/ + + uint32_t w : 11; /*Width of the image map*/ + uint32_t h : 11; /*Height of the image map*/ +} lv_img_header_t; + +/*Image color format*/ +enum { + LV_IMG_CF_UNKNOWN = 0, + + LV_IMG_CF_RAW, /*Contains the file as it is. Needs custom decoder function*/ + LV_IMG_CF_RAW_ALPHA, /*Contains the file as it is. The image has alpha. Needs custom decoder + function*/ + LV_IMG_CF_RAW_CHROMA_KEYED, /*Contains the file as it is. The image is chroma keyed. Needs + custom decoder function*/ + + LV_IMG_CF_TRUE_COLOR, /*Color format and depth should match with LV_COLOR settings*/ + LV_IMG_CF_TRUE_COLOR_ALPHA, /*Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/ + LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /*Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels + will be transparent*/ + + LV_IMG_CF_INDEXED_1BIT, /*Can have 2 different colors in a palette (always chroma keyed)*/ + LV_IMG_CF_INDEXED_2BIT, /*Can have 4 different colors in a palette (always chroma keyed)*/ + LV_IMG_CF_INDEXED_4BIT, /*Can have 16 different colors in a palette (always chroma keyed)*/ + LV_IMG_CF_INDEXED_8BIT, /*Can have 256 different colors in a palette (always chroma keyed)*/ + + LV_IMG_CF_ALPHA_1BIT, /*Can have one color and it can be drawn or not*/ + LV_IMG_CF_ALPHA_2BIT, /*Can have one color but 4 different alpha value*/ + LV_IMG_CF_ALPHA_4BIT, /*Can have one color but 16 different alpha value*/ + LV_IMG_CF_ALPHA_8BIT, /*Can have one color but 256 different alpha value*/ +}; +typedef uint8_t lv_img_cf_t; + +/* Image header it is compatible with + * the result image converter utility*/ +typedef struct +{ + lv_img_header_t header; + uint32_t data_size; + const uint8_t * data; +} lv_img_dsc_t; + +/* Decoder function definitions */ + +struct _lv_img_decoder; +struct _lv_img_decoder_dsc; + +/** + * Get info from an image and store in the `header` + * @param src the image source. Can be a pointer to a C array or a file name (Use + * `lv_img_src_get_type` to determine the type) + * @param header store the info here + * @return LV_RES_OK: info written correctly; LV_RES_INV: failed + */ +typedef lv_res_t (*lv_img_decoder_info_f_t)(struct _lv_img_decoder * decoder, const void * src, lv_img_header_t * header); + +/** + * Open an image for decoding. Prepare it as it is required to read it later + * @param src the image source. Can be a pointer to a C array or a file name (Use + * `lv_img_src_get_type` to determine the type) + * @param style the style of image (maybe it will be required to determine a color or something) + * @return there are 3 possible return values: + * 1) buffer with the decoded image + * 2) if can decode the whole image NULL. decoder_read_line will be called to read the image + * line-by-line + * 3) LV_IMG_DECODER_OPEN_FAIL if the image format is unknown to the decoder or an + * error occurred + */ +typedef const uint8_t * (*lv_img_decoder_open_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc); + +/** + * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`. + * Required only if the "open" function can't return with the whole decoded pixel array. + * @param x start x coordinate + * @param y start y coordinate + * @param len number of pixels to decode + * @param buf a buffer to store the decoded pixels + * @return LV_RES_OK: ok; LV_RES_INV: failed + */ +typedef lv_res_t (*lv_img_decoder_read_line_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc, + lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf); + +/** + * Close the pending decoding. Free resources etc. + */ +typedef void (*lv_img_decoder_close_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc); + +typedef struct _lv_img_decoder_dsc { + lv_img_decoder_info_f_t info_cb; + lv_img_decoder_open_f_t open_cb; + lv_img_decoder_read_line_f_t read_line_cb; + lv_img_decoder_close_f_t close_cb; + +#if LV_USE_USER_DATA_SINGLE + lv_img_decoder_user_data_t user_data; +#endif +}lv_img_decoder_t; + + +typedef struct { + lv_img_decoder_t * decoder; + const lv_style_t * style; + const void * src; + lv_img_src_t src_type; + lv_img_header_t header; + +#if LV_USE_USER_DATA_SINGLE + void * user_data; +#endif +}lv_img_decoder_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_TEMPL_H*/ From 3a78360b623b12c3a81ecfbf7cbfdb0cb3b58e15 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 14 May 2019 06:47:30 +0200 Subject: [PATCH 03/27] lv_indev: do not leave edit mode manually on POINTER release --- src/lv_core/lv_indev.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 416937af8..7fc131c9e 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -876,12 +876,8 @@ static void indev_proc_release(lv_indev_proc_t * proc) if(proc->reset_query != 0) return; - /*Handle click focus*/ + /*Handle click focus*/ #if LV_USE_GROUP - /*Edit mode is not used by POINTER devices. So leave edit mode if we are in it*/ - lv_group_t * g = lv_obj_get_group(proc->types.pointer.act_obj); - if(lv_group_get_editing(g)) lv_group_set_editing(g, false); - /*Check, if the parent is in a group focus on it.*/ if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_CLICK_FOCUS) == false) { /*Respect the click focus protection*/ From 5afe9c119a1e86fb15e1655e3728385f8398df17 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 14 May 2019 07:19:00 +0200 Subject: [PATCH 04/27] lv_indev fix --- src/lv_core/lv_indev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 7fc131c9e..e89166f07 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -878,6 +878,10 @@ static void indev_proc_release(lv_indev_proc_t * proc) /*Handle click focus*/ #if LV_USE_GROUP + /* Edit mode is not used by POINTER devices. + * So leave edit mode if the focused object is still `act_obj`*/ + lv_group_t * g = lv_obj_get_group(proc->types.pointer.act_obj); + /*Check, if the parent is in a group focus on it.*/ if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_CLICK_FOCUS) == false) { /*Respect the click focus protection*/ From 72fb15c3fb35f5a559ef6bea5d73f7bda17cd72d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 14 May 2019 07:19:56 +0200 Subject: [PATCH 05/27] comment updates --- src/lv_core/lv_indev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index e89166f07..82d788225 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -878,8 +878,6 @@ static void indev_proc_release(lv_indev_proc_t * proc) /*Handle click focus*/ #if LV_USE_GROUP - /* Edit mode is not used by POINTER devices. - * So leave edit mode if the focused object is still `act_obj`*/ lv_group_t * g = lv_obj_get_group(proc->types.pointer.act_obj); /*Check, if the parent is in a group focus on it.*/ From f706de55170e876140a1436406b8d11f58599160 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 14 May 2019 15:45:03 +0200 Subject: [PATCH 06/27] img_decoder is working (not fully tested yet) --- src/lv_core/lv_obj.c | 3 + src/lv_core/lv_obj.h | 8 +- src/lv_draw/lv_draw.h | 16 +- src/lv_draw/lv_draw_img.c | 14 +- src/lv_draw/lv_draw_img.h | 8 - src/lv_misc/lv_img_decoder.c | 563 +++++++++++++++++++---------------- src/lv_misc/lv_img_decoder.h | 56 +++- src/lv_misc/lv_types.h | 44 +++ src/lv_objx/lv_img.c | 3 +- src/lv_objx/lv_imgbtn.c | 2 +- 10 files changed, 423 insertions(+), 294 deletions(-) create mode 100644 src/lv_misc/lv_types.h diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 8ef301738..9ebd4964e 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -16,6 +16,7 @@ #include "../lv_misc/lv_anim.h" #include "../lv_misc/lv_task.h" #include "../lv_misc/lv_fs.h" +#include "../lv_misc/lv_img_decoder.h" #include "../lv_hal/lv_hal.h" #include #include @@ -109,6 +110,8 @@ void lv_init(void) /*Init the input device handling*/ lv_indev_init(); + lv_img_decoder_init(); + lv_initialized = true; LV_LOG_INFO("lv_init ready"); } diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 0e8485030..19a2d9522 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -22,6 +22,7 @@ extern "C" { #include #include #include "lv_style.h" +#include "../lv_misc/lv_types.h" #include "../lv_misc/lv_area.h" #include "../lv_misc/lv_mem.h" #include "../lv_misc/lv_ll.h" @@ -64,13 +65,6 @@ typedef uint8_t lv_design_mode_t; typedef bool (*lv_design_cb_t)(struct _lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode); -enum { - LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action - function or an operation was failed*/ - LV_RES_OK, /*The object is valid (no deleted) after the action*/ -}; -typedef uint8_t lv_res_t; - enum { LV_EVENT_PRESSED, /*The object has been pressed*/ LV_EVENT_PRESSING, /*The object is being pressed (called continuously while pressing)*/ diff --git a/src/lv_draw/lv_draw.h b/src/lv_draw/lv_draw.h index 0d346653a..1828e32c2 100644 --- a/src/lv_draw/lv_draw.h +++ b/src/lv_draw/lv_draw.h @@ -21,30 +21,16 @@ extern "C" { #include "../lv_core/lv_style.h" #include "../lv_misc/lv_txt.h" +#include "../lv_misc/lv_img_decoder.h" /********************* * DEFINES *********************/ -/*If image pixels contains alpha we need to know how much byte is a pixel*/ -#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8 -#define LV_IMG_PX_SIZE_ALPHA_BYTE 2 -#elif LV_COLOR_DEPTH == 16 -#define LV_IMG_PX_SIZE_ALPHA_BYTE 3 -#elif LV_COLOR_DEPTH == 32 -#define LV_IMG_PX_SIZE_ALPHA_BYTE 4 -#endif /********************** * TYPEDEFS **********************/ -enum { - LV_IMG_SRC_VARIABLE, - LV_IMG_SRC_FILE, - LV_IMG_SRC_SYMBOL, - LV_IMG_SRC_UNKNOWN, -}; -typedef uint8_t lv_img_src_t; /********************** * GLOBAL PROTOTYPES diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index ebc9b0e3e..0986f1af4 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -452,20 +452,20 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas lv_img_header_t header; lv_res_t header_res; - header_res = lv_img_dsc_get_info(src, &header); + header_res = lv_img_decoder_get_info(src, &header); if(header_res != LV_RES_OK) { LV_LOG_WARN("Image draw can't get image info"); - lv_img_decoder_close(); return LV_RES_INV; } bool chroma_keyed = lv_img_color_format_is_chroma_keyed(header.cf); bool alpha_byte = lv_img_color_format_has_alpha(header.cf); - const uint8_t * img_data = lv_img_decoder_open(src, style); + lv_img_decoder_dsc_t dsc; + const uint8_t * img_data = lv_img_decoder_open(&dsc, src, style); if(img_data == LV_IMG_DECODER_OPEN_FAIL) { LV_LOG_WARN("Image draw cannot open the image resource"); - lv_img_decoder_close(); + lv_img_decoder_close(&dsc); return LV_RES_INV; } @@ -493,9 +493,9 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas lv_coord_t row; lv_res_t read_res; for(row = mask_com.y1; row <= mask_com.y2; row++) { - read_res = lv_img_decoder_read_line(x, y, width, buf); + read_res = lv_img_decoder_read_line(&dsc, x, y, width, buf); if(read_res != LV_RES_OK) { - lv_img_decoder_close(); + lv_img_decoder_close(&dsc); LV_LOG_WARN("Image draw can't read the line"); return LV_RES_INV; } @@ -507,7 +507,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas } } - lv_img_decoder_close(); + lv_img_decoder_close(&dsc); return LV_RES_OK; } diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 43c1a13df..446b2c302 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -40,14 +40,6 @@ extern "C" { void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style, lv_opa_t opa_scale); -/** - * Initialize and `lv_img_dsc_t` variable with the image's info - * @param src variable, filename or symbol - * @param header store the result here - * @return LV_RES_OK: succeeded; LV_RES_INV: failed - */ -lv_res_t lv_img_dsc_get_info(const char * src, lv_img_header_t * header); - /** * Get the type of an image source * @param src pointer to an image source: diff --git a/src/lv_misc/lv_img_decoder.c b/src/lv_misc/lv_img_decoder.c index d0a045407..a18a9a28b 100644 --- a/src/lv_misc/lv_img_decoder.c +++ b/src/lv_misc/lv_img_decoder.c @@ -7,7 +7,10 @@ * INCLUDES *********************/ #include "lv_img_decoder.h" +#include "../lv_draw/lv_draw_img.h" #include "lv_ll.h" +#include "lv_color.h" +#include "lv_gc.h" #if defined(LV_GC_INCLUDE) #include LV_GC_INCLUDE @@ -20,11 +23,29 @@ /********************** * TYPEDEFS **********************/ +typedef struct { + lv_fs_file_t * f; + lv_color_t * palette; +}lv_img_decoder_built_in_data_t; + /********************** * STATIC PROTOTYPES **********************/ +static lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header); +static const uint8_t * lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc); +static lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, + lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf); +static void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc); +static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, + lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf); +static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, + uint8_t * buf); +static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, + uint8_t * buf); + + /********************** * STATIC VARIABLES **********************/ @@ -36,6 +57,7 @@ /********************** * GLOBAL FUNCTIONS **********************/ + /** * Initialize the image decoder module * */ @@ -43,27 +65,30 @@ void lv_img_decoder_init(void) { lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t)); - lv_img_decoder_t decoder; + lv_img_decoder_t * decoder; - /*Create a decoder for true color images*/ - decoder = lv_img_decoder_craete(); - if(decoder) return; - - /*Create a decoder for Alpha indexed images*/ - decoder = lv_img_decoder_craete(); - if(decoder) return; - - /*Create a decoder for color indexed images*/ - decoder = lv_img_decoder_craete(); - if(decoder) return; + /*Create a decoder for the built in color format*/ + decoder = lv_img_decoder_create(); + if(decoder == NULL) { + LV_LOG_WARN("lv_img_decoder_init: out of memory"); + lv_mem_assert(decoder); + return; + } + lv_img_decoder_set_info_cb(decoder, lv_img_decoder_built_in_info); + lv_img_decoder_set_open_cb(decoder, lv_img_decoder_built_in_open); + lv_img_decoder_set_read_line_cb(decoder, lv_img_decoder_built_in_read_line); + lv_img_decoder_set_close_cb(decoder, lv_img_decoder_built_in_close); } -lv_img_decoder_t * lv_img_decoder_craete(void) +lv_img_decoder_t * lv_img_decoder_create(void) { lv_img_decoder_t * decoder; decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll)); lv_mem_assert(decoder); + if(decoder == NULL) return NULL; + + memset(decoder, 0, sizeof(lv_img_decoder_t)); return decoder; } @@ -91,7 +116,7 @@ void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_ void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb) { - decoder->read_line_cb = close_cb; + decoder->close_cb = close_cb; } void lv_img_decoder_set_user_data(lv_img_decoder_t * decoder, lv_img_decoder_t user_data) @@ -99,17 +124,16 @@ void lv_img_decoder_set_user_data(lv_img_decoder_t * decoder, lv_img_decoder_t u memcpy(&decoder->user_data, &user_data, sizeof(user_data)); } -lv_img_decoder_t lv_img_decoder_get_user_data(lv_img_decoder_t * decoder) +lv_img_decoder_user_data_t lv_img_decoder_get_user_data(lv_img_decoder_t * decoder) { return decoder->user_data; } -lv_img_decoder_t * lv_img_decoder_get_user_data_ptr(lv_img_decoder_t * decoder) +lv_img_decoder_user_data_t * lv_img_decoder_get_user_data_ptr(lv_img_decoder_t * decoder) { return &decoder->user_data; } - lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) { header->always_zero = 0; @@ -127,12 +151,12 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) return res; } - const uint8_t * lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style) { dsc->style = style; dsc->src = src; dsc->src_type = lv_img_src_get_type(src); + dsc->user_data = NULL; lv_res_t header_res; header_res = lv_img_decoder_get_info(src, &dsc->header); @@ -147,251 +171,287 @@ const uint8_t * lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src if(res != LV_IMG_DECODER_OPEN_FAIL) break; } -} - -static lv_res_t lv_img_decoder_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) -{ - lv_res_t res = LV_RES_INV; - if(decoder->read_line_cb)res = decoder->read_line_cb(decoder, dsc, x, y, len, buf); return res; } -static void lv_img_decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc) +lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) { - if(decoder->close_cb) decoder->close_cb(decoder, dsc); + lv_res_t res = LV_RES_INV; + if(dsc->decoder->read_line_cb)res = dsc->decoder->read_line_cb(dsc->decoder, dsc, x, y, len, buf); + + return res; +} + +void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc) +{ + if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc); } -static lv_res_t img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header) +/********************** + * STATIC FUNCTIONS + **********************/ + + +static lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header) { lv_img_src_t src_type = lv_img_src_get_type(src); - if(src_type == LV_IMG_SRC_VARIABLE) { - header->w = ((lv_img_dsc_t *)src)->header.w; - header->h = ((lv_img_dsc_t *)src)->header.h; - header->cf = ((lv_img_dsc_t *)src)->header.cf; + if(src_type == LV_IMG_SRC_VARIABLE) { + header->w = ((lv_img_dsc_t *)src)->header.w; + header->h = ((lv_img_dsc_t *)src)->header.h; + header->cf = ((lv_img_dsc_t *)src)->header.cf; + } +#if LV_USE_FILESYSTEM + else if(src_type == LV_IMG_SRC_FILE) { + lv_fs_file_t file; + lv_fs_res_t res; + uint32_t rn; + res = lv_fs_open(&file, src, LV_FS_MODE_RD); + if(res == LV_FS_RES_OK) { + res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn); + lv_fs_close(&file); } - #if LV_USE_FILESYSTEM - else if(src_type == LV_IMG_SRC_FILE) { - lv_fs_file_t file; - lv_fs_res_t res; - uint32_t rn; - res = lv_fs_open(&file, src, LV_FS_MODE_RD); - if(res == LV_FS_RES_OK) { - res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn); - lv_fs_close(&file); - } - /*Create a dummy header on fs error*/ - if(res != LV_FS_RES_OK || rn != sizeof(lv_img_header_t)) { - header->w = LV_DPI; - header->h = LV_DPI; - header->cf = LV_IMG_CF_UNKNOWN; - return LV_RES_INV; - } - } - #endif - else if(src_type == LV_IMG_SRC_SYMBOL) { - /*The size depend on the font but it is unknown here. It should be handled outside of the - * function*/ - header->w = 1; - header->h = 1; - /* Symbols always have transparent parts. Important because of cover check in the design - * function. The actual value doesn't matter because lv_draw_label will draw it*/ - header->cf = LV_IMG_CF_ALPHA_1BIT; - } else { - LV_LOG_WARN("Image get info found unknown src type"); + /*Create a dummy header on fs error*/ + if(res != LV_FS_RES_OK || rn != sizeof(lv_img_header_t)) { + header->w = LV_DPI; + header->h = LV_DPI; + header->cf = LV_IMG_CF_UNKNOWN; return LV_RES_INV; } - return LV_RES_OK; + } +#endif + else if(src_type == LV_IMG_SRC_SYMBOL) { + /*The size depend on the font but it is unknown here. It should be handled outside of the + * function*/ + header->w = 1; + header->h = 1; + /* Symbols always have transparent parts. Important because of cover check in the design + * function. The actual value doesn't matter because lv_draw_label will draw it*/ + header->cf = LV_IMG_CF_ALPHA_1BIT; + } else { + LV_LOG_WARN("Image get info found unknown src type"); + return LV_RES_INV; + } + return LV_RES_OK; } -static uint8_t * img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc,) +static const uint8_t * lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc) { - if(header_res == LV_RES_INV) { - decoder_src = NULL; - decoder_src_type = LV_IMG_SRC_UNKNOWN; - LV_LOG_WARN("Built-in image decoder can't get the header info"); - return LV_IMG_DECODER_OPEN_FAIL; - } - /*Open the file if it's a file*/ - if(decoder_src_type == LV_IMG_SRC_FILE) { + if(dsc->src_type == LV_IMG_SRC_FILE) { #if LV_USE_FILESYSTEM - lv_fs_res_t res = lv_fs_open(&decoder_file, src, LV_FS_MODE_RD); + lv_fs_file_t f; + lv_fs_res_t res = lv_fs_open(&f, dsc->src, LV_FS_MODE_RD); if(res != LV_FS_RES_OK) { LV_LOG_WARN("Built-in image decoder can't open the file"); return LV_IMG_DECODER_OPEN_FAIL; } + + /*If the file was open successfully save the file descriptor*/ + if(dsc->user_data == NULL) { + dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t)); + if(dsc->user_data == NULL) { + LV_LOG_ERROR("img_decoder_built_in_open: out of memory"); + lv_mem_assert(dsc->user_data); + } + memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t)); + } + + lv_img_decoder_built_in_data_t * user_data = dsc->user_data; + user_data->f = lv_mem_alloc(sizeof(f)); + if(user_data->f == NULL) { + LV_LOG_ERROR("img_decoder_built_in_open: out of memory"); + lv_mem_assert(user_data->f); + } + + memcpy(user_data->f, &f, sizeof(f)); + #else LV_LOG_WARN("Image built-in decoder can read file because LV_USE_FILESYSTEM = 0"); return LV_IMG_DECODER_OPEN_FAIL; #endif } - /*Process the different color formats*/ - lv_img_cf_t cf = decoder_header.cf; + lv_img_cf_t cf = dsc->header.cf; + /*Process true color formats*/ if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_ALPHA || - cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) { - if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - /*In case of uncompressed formats if the image stored in the ROM/RAM simply give it's - * pointer*/ - return ((lv_img_dsc_t *)decoder_src)->data; + cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) { + if(dsc->src_type == LV_IMG_SRC_VARIABLE) { + /* In case of uncompressed formats the image stored in the ROM/RAM. + * So simply give its pointer*/ + return ((lv_img_dsc_t *)dsc->src)->data; } else { - /*If it's file it need to be read line by line later*/ + /*If it's a file it need to be read line by line later*/ return NULL; } - } else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || - cf == LV_IMG_CF_INDEXED_4BIT || cf == LV_IMG_CF_INDEXED_8BIT) { + } + /*Process indexed images. Build a palette*/ + else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || + cf == LV_IMG_CF_INDEXED_4BIT || cf == LV_IMG_CF_INDEXED_8BIT) { #if LV_IMG_CF_INDEXED -#if LV_USE_FILESYSTEM - lv_color32_t palette_file[256]; -#endif - - lv_color32_t * palette_p = NULL; uint8_t px_size = lv_img_color_format_get_px_size(cf); uint32_t palette_size = 1 << px_size; - if(decoder_src_type == LV_IMG_SRC_FILE) { + /*Allocate the palette*/ + if(dsc->user_data == NULL) { + dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t)); + if(dsc->user_data == NULL) { + LV_LOG_ERROR("img_decoder_built_in_open: out of memory"); + lv_mem_assert(dsc->user_data); + } + memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t)); + } + + lv_img_decoder_built_in_data_t * user_data = dsc->user_data; + user_data->palette = lv_mem_alloc(sizeof(palette_size * sizeof(lv_color_t))); + if(user_data->palette == NULL) { + LV_LOG_ERROR("img_decoder_built_in_open: out of memory"); + lv_mem_assert(user_data->f); + } +#if LV_USE_FILESYSTEM + lv_color32_t palette_tmp[256]; +#endif + lv_color32_t * palette_p; + + if(dsc->src_type == LV_IMG_SRC_FILE) { /*Read the palette from file*/ #if LV_USE_FILESYSTEM - lv_fs_seek(&decoder_file, 4); /*Skip the header*/ - lv_fs_read(&decoder_file, palette_file, palette_size * sizeof(lv_color32_t), NULL); - palette_p = palette_file; + lv_fs_seek(user_data->f, 4); /*Skip the header*/ + lv_fs_read(user_data->f, palette_tmp, palette_size * sizeof(lv_color_t), NULL); + palette_p = palette_tmp; #else LV_LOG_WARN( - "Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0"); + "Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0"); return LV_IMG_DECODER_OPEN_FAIL; #endif } else { /*The palette begins in the beginning of the image data. Just point to it.*/ - palette_p = (lv_color32_t *)((lv_img_dsc_t *)decoder_src)->data; + palette_p = (lv_color32_t *)((lv_img_dsc_t *)dsc->src)->data; } uint32_t i; for(i = 0; i < palette_size; i++) { - decoder_index_map[i] = - lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue); + user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue); } return NULL; #else LV_LOG_WARN("Indexed (palette) images are not enabled in lv_conf.h. See LV_IMG_CF_INDEXED"); return LV_IMG_DECODER_OPEN_FAIL; #endif - } else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || - cf == LV_IMG_CF_ALPHA_4BIT || cf == LV_IMG_CF_ALPHA_8BIT) { + } + /*Alpha indexed images. */ + else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || + cf == LV_IMG_CF_ALPHA_4BIT || cf == LV_IMG_CF_ALPHA_8BIT) { #if LV_IMG_CF_ALPHA return NULL; /*Nothing to process*/ #else LV_LOG_WARN("Alpha indexed images are not enabled in lv_conf.h. See LV_IMG_CF_ALPHA"); return LV_IMG_DECODER_OPEN_FAIL; #endif - } else { + } + /*Unknown format. Can't decode it.*/ + else { + /*Free the potentially allocated memories*/ + lv_img_decoder_built_in_close(decoder, dsc); + LV_LOG_WARN("Image decoder open: unknown color format") return LV_IMG_DECODER_OPEN_FAIL; } } -static lv_res_t lv_img_decoder_built_in_line_read(lv_img_decoder_t * decoder, lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf) + +static lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, + lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) { + (void)decoder; /*Unused*/ + + lv_res_t res = LV_RES_INV; + if(dsc->src_type == LV_IMG_SRC_FILE) { - #if LV_USE_FILESYSTEM - uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf); + if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) + { + res = lv_img_decoder_built_in_line_true_color(dsc, x, y, len, buf); + } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || + dsc->header.cf == LV_IMG_CF_ALPHA_2BIT || + dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || + dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { - lv_fs_res_t res; + res = lv_img_decoder_built_in_line_alpha(dsc, x, y, len, buf); + } else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || + dsc->header.cf == LV_IMG_CF_INDEXED_2BIT || + dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || + dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { + res = lv_img_decoder_built_in_line_indexed(dsc, x, y, len, buf); + } else { + LV_LOG_WARN("Built-in image decoder read not supports the color format"); + return false; + } + } - if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || - dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA || - dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) - { - uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3; - pos += 4; /*Skip the header*/ - res = lv_fs_seek(&decoder_file, pos); - if(res != LV_FS_RES_OK) { - LV_LOG_WARN("Built-in image decoder seek failed"); - return false; - } - uint32_t btr = len * (px_size >> 3); - uint32_t br = 0; - lv_fs_read(&decoder_file, buf, btr, &br); - if(res != LV_FS_RES_OK || btr != br) { - LV_LOG_WARN("Built-in image decoder read failed"); - return false; - } - } else if(decoder_header.cf == LV_IMG_CF_ALPHA_1BIT || - decoder_header.cf == LV_IMG_CF_ALPHA_2BIT || - decoder_header.cf == LV_IMG_CF_ALPHA_4BIT || - decoder_header.cf == LV_IMG_CF_ALPHA_8BIT) { - - lv_img_built_in_decoder_line_alpha(x, y, len, buf); - } else if(decoder_header.cf == LV_IMG_CF_INDEXED_1BIT || - decoder_header.cf == LV_IMG_CF_INDEXED_2BIT || - decoder_header.cf == LV_IMG_CF_INDEXED_4BIT || - decoder_header.cf == LV_IMG_CF_INDEXED_8BIT) { - lv_img_built_in_decoder_line_indexed(x, y, len, buf); - } else { - LV_LOG_WARN("Built-in image decoder read not supports the color format"); - return false; - } - #else - LV_LOG_WARN("Image built-in decoder can't read file because LV_USE_FILESYSTEM = 0"); - return false; - #endif - } else if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - const lv_img_dsc_t * img_dsc = decoder_src; - - if(img_dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || - img_dsc->header.cf == LV_IMG_CF_ALPHA_2BIT || - img_dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || - img_dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { - lv_img_built_in_decoder_line_alpha(x, y, len, buf); - } else if(img_dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || - img_dsc->header.cf == LV_IMG_CF_INDEXED_2BIT || - img_dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || - img_dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { - lv_img_built_in_decoder_line_indexed(x, y, len, buf); - } else { - LV_LOG_WARN("Built-in image decoder not supports the color format"); - return false; - } - } - - return true; + return res; } static void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc) { + (void)decoder; /*Unused*/ - /*It was opened with built-in decoder*/ - if(decoder_src) { -#if LV_USE_FILESYSTEM - if(decoder_src_type == LV_IMG_SRC_FILE) { - lv_fs_close(&decoder_file); - } -#endif - decoder_src_type = LV_IMG_SRC_UNKNOWN; - decoder_src = NULL; + lv_img_decoder_built_in_data_t * user_data = dsc->user_data; + if(user_data) { + if(user_data->f) lv_mem_free(user_data->f); + if(user_data->palette) lv_mem_free(user_data->palette); + + lv_mem_free(user_data); + + dsc->user_data = NULL; } } -static lv_res_t lv_img_built_in_decoder_line_alpha(lv_img_decoder_t * decoder, lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf) +static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, + lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) +{ + lv_img_decoder_built_in_data_t * user_data = dsc->user_data; + lv_fs_res_t res; + uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf); + + uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3; + pos += 4; /*Skip the header*/ + res = lv_fs_seek(user_data->f, pos); + if(res != LV_FS_RES_OK) { + LV_LOG_WARN("Built-in image decoder seek failed"); + return LV_RES_INV; + } + uint32_t btr = len * (px_size >> 3); + uint32_t br = 0; + lv_fs_read(user_data->f, buf, btr, &br); + if(res != LV_FS_RES_OK || btr != br) { + LV_LOG_WARN("Built-in image decoder read failed"); + return LV_RES_INV; + } + + return LV_RES_OK; +} + +static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, + uint8_t * buf) { #if LV_IMG_CF_ALPHA const lv_opa_t alpha1_opa_table[2] = { - 0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/ + 0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/ const lv_opa_t alpha2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/ const lv_opa_t alpha4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/ - 68, 85, 102, 119, 136, 153, - 170, 187, 204, 221, 238, 255}; + 68, 85, 102, 119, 136, 153, + 170, 187, 204, 221, 238, 255}; /*Simply fill the buffer with the color. Later only the alpha value will be modified.*/ - lv_color_t bg_color = decoder_style->image.color; + lv_color_t bg_color = dsc->style->image.color; lv_coord_t i; for(i = 0; i < len; i++) { #if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1 @@ -408,42 +468,43 @@ static lv_res_t lv_img_built_in_decoder_line_alpha(lv_img_decoder_t * decoder, l } const lv_opa_t * opa_table = NULL; - uint8_t px_size = lv_img_color_format_get_px_size(decoder_header.cf); + uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf); uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/ lv_coord_t w = 0; uint32_t ofs = 0; int8_t pos = 0; - switch(decoder_header.cf) { - case LV_IMG_CF_ALPHA_1BIT: - w = (decoder_header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ - if(decoder_header.w & 0x7) w++; - ofs += w * y + (x >> 3); /*First pixel*/ - pos = 7 - (x & 0x7); - opa_table = alpha1_opa_table; - break; - case LV_IMG_CF_ALPHA_2BIT: - w = (decoder_header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ - if(decoder_header.w & 0x3) w++; - ofs += w * y + (x >> 2); /*First pixel*/ - pos = 6 - ((x & 0x3) * 2); - opa_table = alpha2_opa_table; - break; - case LV_IMG_CF_ALPHA_4BIT: - w = (decoder_header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ - if(decoder_header.w & 0x1) w++; - ofs += w * y + (x >> 1); /*First pixel*/ - pos = 4 - ((x & 0x1) * 4); - opa_table = alpha4_opa_table; - break; - case LV_IMG_CF_ALPHA_8BIT: - w = decoder_header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ - ofs += w * y + x; /*First pixel*/ - pos = 0; - break; + switch(dsc->header.cf) { + case LV_IMG_CF_ALPHA_1BIT: + w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ + if(dsc->header.w & 0x7) w++; + ofs += w * y + (x >> 3); /*First pixel*/ + pos = 7 - (x & 0x7); + opa_table = alpha1_opa_table; + break; + case LV_IMG_CF_ALPHA_2BIT: + w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ + if(dsc->header.w & 0x3) w++; + ofs += w * y + (x >> 2); /*First pixel*/ + pos = 6 - ((x & 0x3) * 2); + opa_table = alpha2_opa_table; + break; + case LV_IMG_CF_ALPHA_4BIT: + w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ + if(dsc->header.w & 0x1) w++; + ofs += w * y + (x >> 1); /*First pixel*/ + pos = 4 - ((x & 0x1) * 4); + opa_table = alpha4_opa_table; + break; + case LV_IMG_CF_ALPHA_8BIT: + w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ + ofs += w * y + x; /*First pixel*/ + pos = 0; + break; } #if LV_USE_FILESYSTEM + lv_img_decoder_built_in_data_t * user_data = dsc->user_data; #if LV_COMPILER_VLA_SUPPORTED uint8_t fs_buf[w]; #else @@ -451,17 +512,17 @@ static lv_res_t lv_img_built_in_decoder_line_alpha(lv_img_decoder_t * decoder, l #endif #endif const uint8_t * data_tmp = NULL; - if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - const lv_img_dsc_t * img_dsc = decoder_src; + if(dsc->src_type == LV_IMG_SRC_VARIABLE) { + const lv_img_dsc_t * img_dsc = dsc->src; + data_tmp = img_dsc->data + ofs; } else { #if LV_USE_FILESYSTEM - lv_fs_seek(&decoder_file, ofs + 4); /*+4 to skip the header*/ - lv_fs_read(&decoder_file, fs_buf, w, NULL); + lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/ + lv_fs_read(user_data->f, fs_buf, w, NULL); data_tmp = fs_buf; #else - LV_LOG_WARN( - "Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0"); + LV_LOG_WARN( "Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0"); data_tmp = NULL; /*To avoid warnings*/ return LV_RES_INV; #endif @@ -473,7 +534,7 @@ static lv_res_t lv_img_built_in_decoder_line_alpha(lv_img_decoder_t * decoder, l val_act = (data_tmp[byte_act] & (mask << pos)) >> pos; buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = - decoder_header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act]; + dsc->header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act]; pos -= px_size; if(pos < 0) { @@ -486,52 +547,54 @@ static lv_res_t lv_img_built_in_decoder_line_alpha(lv_img_decoder_t * decoder, l #else LV_LOG_WARN( - "Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h"); + "Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h"); return LV_RES_INV; #endif } -static lv_res_t lv_img_built_in_decoder_line_indexed(lv_img_decoder_t * decoder, lv_coord_t x, lv_coord_t y, lv_coord_t len, - uint8_t * buf) +static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, + uint8_t * buf) { #if LV_IMG_CF_INDEXED - uint8_t px_size = lv_img_color_format_get_px_size(decoder_header.cf); + uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf); uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/ lv_coord_t w = 0; int8_t pos = 0; uint32_t ofs = 0; - switch(decoder_header.cf) { - case LV_IMG_CF_INDEXED_1BIT: - w = (decoder_header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ - if(decoder_header.w & 0x7) w++; - ofs += w * y + (x >> 3); /*First pixel*/ - ofs += 8; /*Skip the palette*/ - pos = 7 - (x & 0x7); - break; - case LV_IMG_CF_INDEXED_2BIT: - w = (decoder_header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ - if(decoder_header.w & 0x3) w++; - ofs += w * y + (x >> 2); /*First pixel*/ - ofs += 16; /*Skip the palette*/ - pos = 6 - ((x & 0x3) * 2); - break; - case LV_IMG_CF_INDEXED_4BIT: - w = (decoder_header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ - if(decoder_header.w & 0x1) w++; - ofs += w * y + (x >> 1); /*First pixel*/ - ofs += 64; /*Skip the palette*/ - pos = 4 - ((x & 0x1) * 4); - break; - case LV_IMG_CF_INDEXED_8BIT: - w = decoder_header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ - ofs += w * y + x; /*First pixel*/ - ofs += 1024; /*Skip the palette*/ - pos = 0; - break; + switch(dsc->header.cf) { + case LV_IMG_CF_INDEXED_1BIT: + w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/ + if(dsc->header.w & 0x7) w++; + ofs += w * y + (x >> 3); /*First pixel*/ + ofs += 8; /*Skip the palette*/ + pos = 7 - (x & 0x7); + break; + case LV_IMG_CF_INDEXED_2BIT: + w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/ + if(dsc->header.w & 0x3) w++; + ofs += w * y + (x >> 2); /*First pixel*/ + ofs += 16; /*Skip the palette*/ + pos = 6 - ((x & 0x3) * 2); + break; + case LV_IMG_CF_INDEXED_4BIT: + w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/ + if(dsc->header.w & 0x1) w++; + ofs += w * y + (x >> 1); /*First pixel*/ + ofs += 64; /*Skip the palette*/ + pos = 4 - ((x & 0x1) * 4); + break; + case LV_IMG_CF_INDEXED_8BIT: + w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/ + ofs += w * y + x; /*First pixel*/ + ofs += 1024; /*Skip the palette*/ + pos = 0; + break; } + lv_img_decoder_built_in_data_t * user_data = dsc->user_data; + #if LV_USE_FILESYSTEM #if LV_COMPILER_VLA_SUPPORTED uint8_t fs_buf[w]; @@ -540,17 +603,17 @@ static lv_res_t lv_img_built_in_decoder_line_indexed(lv_img_decoder_t * decoder, #endif #endif const uint8_t * data_tmp = NULL; - if(decoder_src_type == LV_IMG_SRC_VARIABLE) { - const lv_img_dsc_t * img_dsc = decoder_src; + if(dsc->src_type == LV_IMG_SRC_VARIABLE) { + const lv_img_dsc_t * img_dsc = dsc->src; data_tmp = img_dsc->data + ofs; } else { #if LV_USE_FILESYSTEM - lv_fs_seek(&decoder_file, ofs + 4); /*+4 to skip the header*/ - lv_fs_read(&decoder_file, fs_buf, w, NULL); + lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/ + lv_fs_read(user_data->f, fs_buf, w, NULL); data_tmp = fs_buf; #else LV_LOG_WARN( - "Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0"); + "Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0"); data_tmp = NULL; /*To avoid warnings*/ return LV_RES_INV; #endif @@ -562,7 +625,7 @@ static lv_res_t lv_img_built_in_decoder_line_indexed(lv_img_decoder_t * decoder, lv_color_t * cbuf = (lv_color_t *)buf; for(i = 0; i < len; i++) { val_act = (data_tmp[byte_act] & (mask << pos)) >> pos; - cbuf[i] = decoder_index_map[val_act]; + cbuf[i] = user_data->palette[val_act]; pos -= px_size; if(pos < 0) { @@ -574,14 +637,10 @@ static lv_res_t lv_img_built_in_decoder_line_indexed(lv_img_decoder_t * decoder, return LV_RES_OK; #else LV_LOG_WARN( - "Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h"); + "Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h"); return LV_RES_INV; #endif } - -/********************** - * STATIC FUNCTIONS - **********************/ diff --git a/src/lv_misc/lv_img_decoder.h b/src/lv_misc/lv_img_decoder.h index 7432a4342..e431f227a 100644 --- a/src/lv_misc/lv_img_decoder.h +++ b/src/lv_misc/lv_img_decoder.h @@ -21,15 +21,38 @@ extern "C" { #include #include "lv_fs.h" +#include "lv_types.h" +#include "lv_area.h" +#include "../lv_core/lv_style.h" /********************* * DEFINES *********************/ -#define LV_IMG_DECODER_OPEN_FAIL ((void *)(-1)); +/*If image pixels contains alpha we need to know how much byte is a pixel*/ +#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8 +#define LV_IMG_PX_SIZE_ALPHA_BYTE 2 +#elif LV_COLOR_DEPTH == 16 +#define LV_IMG_PX_SIZE_ALPHA_BYTE 3 +#elif LV_COLOR_DEPTH == 32 +#define LV_IMG_PX_SIZE_ALPHA_BYTE 4 +#endif + + +#define LV_IMG_DECODER_OPEN_FAIL ((void *)(-1)) /********************** * TYPEDEFS **********************/ + +enum { + LV_IMG_SRC_VARIABLE, + LV_IMG_SRC_FILE, + LV_IMG_SRC_SYMBOL, + LV_IMG_SRC_UNKNOWN, +}; + +typedef uint8_t lv_img_src_t; + typedef struct { @@ -126,7 +149,7 @@ typedef lv_res_t (*lv_img_decoder_read_line_f_t)(struct _lv_img_decoder * decode */ typedef void (*lv_img_decoder_close_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc); -typedef struct _lv_img_decoder_dsc { +typedef struct _lv_img_decoder { lv_img_decoder_info_f_t info_cb; lv_img_decoder_open_f_t open_cb; lv_img_decoder_read_line_f_t read_line_cb; @@ -138,7 +161,7 @@ typedef struct _lv_img_decoder_dsc { }lv_img_decoder_t; -typedef struct { +typedef struct _lv_img_decoder_dsc { lv_img_decoder_t * decoder; const lv_style_t * style; const void * src; @@ -154,6 +177,33 @@ typedef struct { * GLOBAL PROTOTYPES **********************/ +/** + * Initialize the image decoder module + * */ +void lv_img_decoder_init(void); + +lv_img_decoder_t * lv_img_decoder_create(void); + +void lv_img_decoder_delete(lv_img_decoder_t * decoder); + +void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb); + +void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb); + +void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb); + +void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb); +void lv_img_decoder_set_user_data(lv_img_decoder_t * decoder, lv_img_decoder_t user_data); + +lv_img_decoder_user_data_t lv_img_decoder_get_user_data(lv_img_decoder_t * decoder); +lv_img_decoder_user_data_t * lv_img_decoder_get_user_data_ptr(lv_img_decoder_t * decoder); + +lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header); +const uint8_t * lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style); + +lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf); + +void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc); /********************** * MACROS **********************/ diff --git a/src/lv_misc/lv_types.h b/src/lv_misc/lv_types.h new file mode 100644 index 000000000..bdd860f56 --- /dev/null +++ b/src/lv_misc/lv_types.h @@ -0,0 +1,44 @@ +/** + * @file lv_types.h + * + */ + +#ifndef LV_TYPES_H +#define LV_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +enum { + LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action + function or an operation was failed*/ + LV_RES_OK, /*The object is valid (no deleted) after the action*/ +}; +typedef uint8_t lv_res_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_TYPES_H*/ diff --git a/src/lv_objx/lv_img.c b/src/lv_objx/lv_img.c index 510ad9f58..15a3299d8 100644 --- a/src/lv_objx/lv_img.c +++ b/src/lv_objx/lv_img.c @@ -15,6 +15,7 @@ #endif #include "../lv_themes/lv_theme.h" +#include "../lv_misc/lv_img_decoder.h" #include "../lv_misc/lv_fs.h" #include "../lv_misc/lv_txt.h" #include "../lv_misc/lv_log.h" @@ -148,7 +149,7 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img) } lv_img_header_t header; - lv_img_dsc_get_info(src_img, &header); + lv_img_decoder_get_info(src_img, &header); /*Save the source*/ if(src_type == LV_IMG_SRC_VARIABLE) { diff --git a/src/lv_objx/lv_imgbtn.c b/src/lv_objx/lv_imgbtn.c index cf98c82b1..58a03b1c6 100644 --- a/src/lv_objx/lv_imgbtn.c +++ b/src/lv_objx/lv_imgbtn.c @@ -375,7 +375,7 @@ static void refr_img(lv_obj_t * imgbtn) #endif lv_res_t info_res; - info_res = lv_img_dsc_get_info(src, &header); + info_res = lv_img_decoder_get_info(src, &header); if(info_res == LV_RES_OK) { ext->act_cf = header.cf; #if LV_IMGBTN_TILED == 0 From e31b6a156e07d7b8220b1012103531400dcc8499 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 05:22:03 +0200 Subject: [PATCH 07/27] move lv_img_decoder to lv_draw --- src/lv_core/lv_obj.c | 1 - src/lv_draw/lv_draw.h | 2 +- src/lv_draw/lv_draw_img.h | 3 +-- src/{lv_misc => lv_draw}/lv_img_decoder.c | 6 +++--- src/{lv_misc => lv_draw}/lv_img_decoder.h | 6 +++--- src/lv_objx/lv_img.c | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) rename src/{lv_misc => lv_draw}/lv_img_decoder.c (99%) rename src/{lv_misc => lv_draw}/lv_img_decoder.h (98%) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 9ebd4964e..c49224c72 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -16,7 +16,6 @@ #include "../lv_misc/lv_anim.h" #include "../lv_misc/lv_task.h" #include "../lv_misc/lv_fs.h" -#include "../lv_misc/lv_img_decoder.h" #include "../lv_hal/lv_hal.h" #include #include diff --git a/src/lv_draw/lv_draw.h b/src/lv_draw/lv_draw.h index 1828e32c2..8d3d281a7 100644 --- a/src/lv_draw/lv_draw.h +++ b/src/lv_draw/lv_draw.h @@ -21,7 +21,7 @@ extern "C" { #include "../lv_core/lv_style.h" #include "../lv_misc/lv_txt.h" -#include "../lv_misc/lv_img_decoder.h" +#include "lv_img_decoder.h" /********************* * DEFINES diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 446b2c302..d8e927176 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -14,8 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "lv_draw.h" -#include "../lv_core/lv_obj.h" -#include "../lv_misc/lv_img_decoder.h" +#include "lv_img_decoder.h" /********************* * DEFINES diff --git a/src/lv_misc/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c similarity index 99% rename from src/lv_misc/lv_img_decoder.c rename to src/lv_draw/lv_img_decoder.c index a18a9a28b..b52cd7de2 100644 --- a/src/lv_misc/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -8,9 +8,9 @@ *********************/ #include "lv_img_decoder.h" #include "../lv_draw/lv_draw_img.h" -#include "lv_ll.h" -#include "lv_color.h" -#include "lv_gc.h" +#include "../lv_misc/lv_ll.h" +#include "../lv_misc/lv_color.h" +#include "../lv_misc/lv_gc.h" #if defined(LV_GC_INCLUDE) #include LV_GC_INCLUDE diff --git a/src/lv_misc/lv_img_decoder.h b/src/lv_draw/lv_img_decoder.h similarity index 98% rename from src/lv_misc/lv_img_decoder.h rename to src/lv_draw/lv_img_decoder.h index e431f227a..058360323 100644 --- a/src/lv_misc/lv_img_decoder.h +++ b/src/lv_draw/lv_img_decoder.h @@ -20,9 +20,9 @@ extern "C" { #endif #include -#include "lv_fs.h" -#include "lv_types.h" -#include "lv_area.h" +#include "../lv_misc/lv_fs.h" +#include "../lv_misc/lv_types.h" +#include "../lv_misc/lv_area.h" #include "../lv_core/lv_style.h" /********************* diff --git a/src/lv_objx/lv_img.c b/src/lv_objx/lv_img.c index 15a3299d8..f9eca884d 100644 --- a/src/lv_objx/lv_img.c +++ b/src/lv_objx/lv_img.c @@ -15,7 +15,7 @@ #endif #include "../lv_themes/lv_theme.h" -#include "../lv_misc/lv_img_decoder.h" +#include "../lv_draw/lv_img_decoder.h" #include "../lv_misc/lv_fs.h" #include "../lv_misc/lv_txt.h" #include "../lv_misc/lv_log.h" From 5af101a1eb01249fa1aa67047e53557aa6da4fd4 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 06:15:12 +0200 Subject: [PATCH 08/27] add inline anim set functions --- src/lv_core/lv_obj.c | 2 +- src/lv_core/lv_style.c | 2 +- src/lv_core/lv_style.h | 63 ++++++++++++++++++++++++++++++++ src/lv_misc/lv_anim.c | 2 +- src/lv_misc/lv_anim.h | 83 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 148 insertions(+), 4 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 8ef301738..7766d2862 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -90,7 +90,7 @@ void lv_init(void) lv_font_init(); #if LV_USE_ANIMATION - lv_anim_init(); + lv_anim_core_init(); #endif #if LV_USE_GROUP diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index ea6b3bb59..894326e9b 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -318,7 +318,7 @@ void * lv_style_anim_create(lv_style_anim_t * anim) a.playback_pause = anim->playback_pause; a.repeat = anim->repeat; a.repeat_pause = anim->repeat_pause; - + a.user_data = anim->user_data; lv_anim_create(&a); return dsc; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 4f4ac19b4..05d63331f 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -147,6 +147,69 @@ a.ready_cb = NULL; a.user_data = NULL; lv_style_anim_create(&a); */ + + +static inline void lv_style_anim_init(lv_style_anim_t * a) +{ + memset(a, 0, sizeof(lv_style_anim_t)); +} + +static inline void lv_style_anim_set_styles(lv_style_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end) +{ + a->style_anim = to_anim; + a->style_start = start; + a->style_end = end; +} + +static inline void lv_style_anim_set_time(lv_style_anim_t * a, uint16_t duration, uint16_t delay) +{ + a->time = duration; + a->act_time = -delay; +} + +static inline void lv_style_anim_set_ready_cb(lv_style_anim_t * a, lv_anim_ready_cb_t ready_cb) +{ + a->ready_cb = ready_cb; +} + +static inline void lv_style_anim_set_playback(lv_style_anim_t * a, uint16_t wait_time) +{ + a->playback = 1; + a->playback_pause = wait_time; +} + +static inline void lv_style_anim_clear_playback(lv_style_anim_t * a) +{ + a->playback = 0; +} + +static inline void lv_style_anim_set_repeat(lv_style_anim_t * a, uint16_t wait_time) +{ + a->repeat = 1; + a->repeat_pause = wait_time; +} + +static inline void lv_style_anim_clear_repeat(lv_style_anim_t * a) +{ + a->repeat = 0; +} + +static inline void lv_style_anim_set_user_data(lv_style_anim_t * a, lv_anim_user_data_t user_data) +{ + memcpy(&a->user_data, &user_data, sizeof(user_data)); +} + +static inline lv_anim_user_data_t lv_style_anim_get_user_data(lv_style_anim_t * a) +{ + return a->user_data; +} + +static inline lv_anim_user_data_t * lv_style_anim_get_user_data_ptr(lv_style_anim_t * a) +{ + return &a->user_data; +} + + #endif /********************** diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index ef2d6696c..24d158325 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -53,7 +53,7 @@ static bool anim_list_changed; /** * Init. the animation module */ -void lv_anim_init(void) +void lv_anim_core_init(void) { lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t)); last_task_run = lv_tick_get(); diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index 95444d60b..393a7c6fa 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -98,7 +98,88 @@ lv_anim_create(&a); /** * Init. the animation module */ -void lv_anim_init(void); +void lv_anim_core_init(void); + + +/** + * Initialize an animation variable + * @param a pointer to animation + */ +static inline void lv_anim_init(lv_anim_t * a) +{ + memset(a, 0, sizeof(lv_anim_t)); +} + + +static inline void lv_anim_set_var(lv_anim_t * a, void * var) +{ + a->var = var; +} + +static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay) +{ + a->time = duration; + a->act_time = -delay; +} + +static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end) +{ + a->start = start; + a->end = end; +} + +static inline void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_cb_t exec_cb) +{ + a->exec_cb = exec_cb; +} + +static inline void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb) +{ + a->path_cb = path_cb; +} + +static inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb) +{ + a->ready_cb = ready_cb; +} + +static inline void lv_anim_set_playback(lv_anim_t * a, uint16_t wait_time) +{ + a->playback = 1; + a->playback_pause = wait_time; +} + +static inline void lv_anim_clear_playback(lv_anim_t * a) +{ + a->playback = 0; +} + +static inline void lv_anim_set_repeat(lv_anim_t * a, uint16_t wait_time) +{ + a->repeat = 1; + a->repeat_pause = wait_time; +} + +static inline void lv_anim_clear_repeat(lv_anim_t * a) +{ + a->repeat = 0; +} + +static inline void lv_anim_set_user_data(lv_anim_t * a, lv_anim_user_data_t user_data) +{ + memcpy(&a->user_data, &user_data, sizeof(user_data)); +} + +static inline lv_anim_user_data_t lv_anim_get_user_data(lv_anim_t * a) +{ + return a->user_data; +} + +static inline lv_anim_user_data_t * lv_anim_get_user_data_ptr(lv_anim_t * a) +{ + return &a->user_data; +} + /** * Create an animation From fe8157cc882735de7c04ee7cdb6706fa6a135653 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 06:43:16 +0200 Subject: [PATCH 09/27] add LV_EVENT_KEY --- src/lv_core/lv_group.c | 10 +++++++++- src/lv_core/lv_obj.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lv_core/lv_group.c b/src/lv_core/lv_group.c index 7d6cfa1fd..2a0afee30 100644 --- a/src/lv_core/lv_group.c +++ b/src/lv_core/lv_group.c @@ -285,7 +285,15 @@ lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c) lv_obj_t * act = lv_group_get_focused(group); if(act == NULL) return LV_RES_OK; - return act->signal_cb(act, LV_SIGNAL_CONTROL, &c); + lv_res_t res; + + res = act->signal_cb(act, LV_SIGNAL_CONTROL, &c); + if(res != LV_RES_OK) return res; + + res = lv_event_send(act, LV_EVENT_KEY, &c); + if(res != LV_RES_OK) return res; + + return res; } /** diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 0e8485030..d9159f9ba 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -84,6 +84,7 @@ enum { LV_EVENT_DRAG_BEGIN, LV_EVENT_DRAG_END, LV_EVENT_DRAG_THROW_BEGIN, + LV_EVENT_KEY, LV_EVENT_FOCUSED, LV_EVENT_DEFOCUSED, LV_EVENT_VALUE_CHANGED, From eebe04bd9504f991b40cd46b58c2ed4e8e43a73c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 06:46:27 +0200 Subject: [PATCH 10/27] lv_key_t: fix format --- src/lv_core/lv_group.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lv_core/lv_group.h b/src/lv_core/lv_group.h index c58ed48c4..6119df80c 100644 --- a/src/lv_core/lv_group.h +++ b/src/lv_core/lv_group.h @@ -27,7 +27,7 @@ extern "C" { /*Predefined keys to control the focused object via lv_group_send(group, c)*/ /*For compatibility in signal function define the keys regardless to `LV_USE_GROUP`*/ -typedef enum { +enum { LV_KEY_UP = 17, /*0x11*/ LV_KEY_DOWN = 18, /*0x12*/ LV_KEY_RIGHT = 19, /*0x13*/ @@ -40,7 +40,8 @@ typedef enum { LV_KEY_PREV=11, /*0x0B, '*/ LV_KEY_HOME = 2, /*0x02, STX*/ LV_KEY_END = 3, /*0x03, ETX*/ -} lv_key_t; +}; +typedef uint8_t lv_key_t; #if LV_USE_GROUP != 0 /********************** From 6a265896a233d64387eac70d91b9dd221406d66b Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 07:34:19 +0200 Subject: [PATCH 11/27] fix screen copy --- src/lv_core/lv_indev.c | 4 ++-- src/lv_core/lv_obj.c | 7 ++++++- src/lv_misc/lv_mem.c | 8 ++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 82d788225..f2ab53c3c 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -881,8 +881,8 @@ static void indev_proc_release(lv_indev_proc_t * proc) lv_group_t * g = lv_obj_get_group(proc->types.pointer.act_obj); /*Check, if the parent is in a group focus on it.*/ - if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_CLICK_FOCUS) == - false) { /*Respect the click focus protection*/ + /*Respect the click focus protection*/ + if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_CLICK_FOCUS) == false) { lv_obj_t * parent = proc->types.pointer.act_obj; while(g == NULL) { diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 8ef301738..ba60312da 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -359,7 +359,12 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) } #endif - lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy)); + /*Set the same coordinates for non screen objects*/ + if(lv_obj_get_parent(copy) != NULL) { + lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy)); + } else { + lv_obj_set_pos(new_obj, 0, 0); + } LV_LOG_INFO("Object create ready"); } diff --git a/src/lv_misc/lv_mem.c b/src/lv_misc/lv_mem.c index bfea3490b..6dfcea849 100644 --- a/src/lv_misc/lv_mem.c +++ b/src/lv_misc/lv_mem.c @@ -126,7 +126,9 @@ void * lv_mem_alloc(uint32_t size) #endif void * alloc = NULL; -#if LV_MEM_CUSTOM == 0 /*Use the allocation from dyn_mem*/ + +#if LV_MEM_CUSTOM == 0 + /*Use the built-in allocators*/ lv_mem_ent_t * e = NULL; // Search for a appropriate entry @@ -141,7 +143,8 @@ void * lv_mem_alloc(uint32_t size) // End if there is not next entry OR the alloc. is successful } while(e != NULL && alloc == NULL); -#else /*Use custom, user defined malloc function*/ +#else +/*Use custom, user defined malloc function*/ #if LV_ENABLE_GC == 1 /*gc must not include header*/ alloc = LV_MEM_CUSTOM_ALLOC(size); #else /* LV_ENABLE_GC */ @@ -150,6 +153,7 @@ void * lv_mem_alloc(uint32_t size) if(alloc != NULL) { ((lv_mem_ent_t *)alloc)->header.s.d_size = size; ((lv_mem_ent_t *)alloc)->header.s.used = 1; + alloc = &((lv_mem_ent_t *)alloc)->first_data; } #endif /* LV_ENABLE_GC */ From 648d42ec947919dc7a4613d2550e96b94f17754a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 07:36:13 +0200 Subject: [PATCH 12/27] fix screen copy --- src/lv_core/lv_obj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index ba60312da..f786ee0a8 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -360,7 +360,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) #endif /*Set the same coordinates for non screen objects*/ - if(lv_obj_get_parent(copy) != NULL) { + if(lv_obj_get_parent(copy) != NULL && parent != NULL) { lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy)); } else { lv_obj_set_pos(new_obj, 0, 0); From 569bbdf0589a6c57e6839a8bf94d17984339d680 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 18:27:26 +0200 Subject: [PATCH 13/27] remove lv_style_anim_t and replace it with simply lv_anim_t --- src/lv_core/lv_style.c | 68 +++++-------- src/lv_core/lv_style.h | 226 ++++++++++++++++++++++------------------- src/lv_misc/lv_anim.c | 29 ++++-- src/lv_misc/lv_anim.h | 141 ++++++++++++++++++------- 4 files changed, 278 insertions(+), 186 deletions(-) diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index 894326e9b..2d6b67fda 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -26,16 +26,6 @@ /********************** * TYPEDEFS **********************/ -#if LV_USE_ANIMATION -typedef struct -{ - lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it - will be modified too*/ - lv_style_t style_end; - lv_style_t * style_anim; - lv_anim_ready_cb_t ready_cb; -} lv_style_anim_dsc_t; -#endif /********************** * STATIC PROTOTYPES @@ -286,44 +276,38 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * #if LV_USE_ANIMATION -/** - * Create an animation from a pre-configured 'lv_style_anim_t' variable - * @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied) - * @return pointer to a descriptor. Really this variable will be animated. (Can be used in - * `lv_anim_del(dsc, NULL)`) - */ -void * lv_style_anim_create(lv_style_anim_t * anim) + +void lv_style_anim_init(lv_anim_t * a) { - lv_style_anim_dsc_t * dsc; - dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t)); - lv_mem_assert(dsc); - if(dsc == NULL) return NULL; + lv_anim_init(a); + a->start = 0; + a->end = STYLE_MIX_MAX; + a->exec_cb = (lv_anim_exec_cb_t)style_animator; + a->path_cb = lv_anim_path_linear; + a->ready_cb = style_animation_common_end_cb; - dsc->style_anim = anim->style_anim; - memcpy(&dsc->style_start, anim->style_start, sizeof(lv_style_t)); - memcpy(&dsc->style_end, anim->style_end, sizeof(lv_style_t)); - memcpy(dsc->style_anim, anim->style_start, sizeof(lv_style_t)); - dsc->ready_cb = anim->ready_cb; + lv_style_anim_dsc_t * dsc; + dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t)); + lv_mem_assert(dsc); + if(dsc == NULL) return; + dsc->ready_cb = NULL; + dsc->style_anim = NULL; + lv_style_copy(&dsc->style_start, &lv_style_plain); + lv_style_copy(&dsc->style_end, &lv_style_plain); - lv_anim_t a; - a.var = (void *)dsc; - a.start = 0; - a.end = STYLE_MIX_MAX; - a.exec_cb = (lv_anim_exec_cb_t)style_animator; - a.path_cb = lv_anim_path_linear; - a.ready_cb = style_animation_common_end_cb; - a.act_time = anim->act_time; - a.time = anim->time; - a.playback = anim->playback; - a.playback_pause = anim->playback_pause; - a.repeat = anim->repeat; - a.repeat_pause = anim->repeat_pause; - a.user_data = anim->user_data; - lv_anim_create(&a); + a->var = (void *)dsc; - return dsc; } +void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end) +{ + + lv_style_anim_dsc_t * dsc = a->var; + dsc->style_anim = to_anim; + memcpy(&dsc->style_start, start, sizeof(lv_style_t)); + memcpy(&dsc->style_end, end, sizeof(lv_style_t)); + memcpy(dsc->style_anim, start, sizeof(lv_style_t)); +} #endif /********************** * STATIC FUNCTIONS diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 05d63331f..a4d5b6f8e 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -112,104 +112,12 @@ typedef struct #if LV_USE_ANIMATION typedef struct { - const lv_style_t * style_start; /*Pointer to the starting style*/ - const lv_style_t * style_end; /*Pointer to the destination style*/ - lv_style_t * style_anim; /*Pointer to a style to animate*/ - lv_anim_ready_cb_t ready_cb; /*Call it when the animation is ready (NULL if unused)*/ - int16_t time; /*Animation time in ms*/ - int16_t act_time; /*Current time in animation. Set to negative to make delay.*/ - uint16_t playback_pause; /*Wait before play back*/ - uint16_t repeat_pause; /*Wait before repeat*/ -#if LV_USE_USER_DATA_SINGLE - lv_anim_user_data_t user_data; /*Custom user data*/ -#endif - -#if LV_USE_USER_DATA_MULTI - lv_anim_user_data_t ready_user_data; -#endif - - uint8_t playback : 1; /*When the animation is ready play it back*/ - uint8_t repeat : 1; /*Repeat the animation infinitely*/ -} lv_style_anim_t; - -/* Example initialization -lv_style_anim_t a; -a.style_anim = &style_to_anim; -a.style_start = &style_1; -a.style_end = &style_2; -a.act_time = 0; -a.time = 1000; -a.playback = 0; -a.playback_pause = 0; -a.repeat = 0; -a.repeat_pause = 0; -a.ready_cb = NULL; -a.user_data = NULL; -lv_style_anim_create(&a); - */ - - -static inline void lv_style_anim_init(lv_style_anim_t * a) -{ - memset(a, 0, sizeof(lv_style_anim_t)); -} - -static inline void lv_style_anim_set_styles(lv_style_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end) -{ - a->style_anim = to_anim; - a->style_start = start; - a->style_end = end; -} - -static inline void lv_style_anim_set_time(lv_style_anim_t * a, uint16_t duration, uint16_t delay) -{ - a->time = duration; - a->act_time = -delay; -} - -static inline void lv_style_anim_set_ready_cb(lv_style_anim_t * a, lv_anim_ready_cb_t ready_cb) -{ - a->ready_cb = ready_cb; -} - -static inline void lv_style_anim_set_playback(lv_style_anim_t * a, uint16_t wait_time) -{ - a->playback = 1; - a->playback_pause = wait_time; -} - -static inline void lv_style_anim_clear_playback(lv_style_anim_t * a) -{ - a->playback = 0; -} - -static inline void lv_style_anim_set_repeat(lv_style_anim_t * a, uint16_t wait_time) -{ - a->repeat = 1; - a->repeat_pause = wait_time; -} - -static inline void lv_style_anim_clear_repeat(lv_style_anim_t * a) -{ - a->repeat = 0; -} - -static inline void lv_style_anim_set_user_data(lv_style_anim_t * a, lv_anim_user_data_t user_data) -{ - memcpy(&a->user_data, &user_data, sizeof(user_data)); -} - -static inline lv_anim_user_data_t lv_style_anim_get_user_data(lv_style_anim_t * a) -{ - return a->user_data; -} - -static inline lv_anim_user_data_t * lv_style_anim_get_user_data_ptr(lv_style_anim_t * a) -{ - return &a->user_data; -} - - + lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it + will be modified too*/ + lv_style_t style_end; + lv_style_t * style_anim; + lv_anim_ready_cb_t ready_cb; +} lv_style_anim_dsc_t; #endif /********************** @@ -241,12 +149,124 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * #if LV_USE_ANIMATION /** - * Create an animation from a pre-configured 'lv_style_anim_t' variable - * @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied) - * @return pointer to a descriptor. Really this variable will be animated. (Can be used in - * `lv_anim_del(dsc, NULL)`) + * Initialize an animation variable. + * E.g.: + * lv_anim_t a; + * lv_style_anim__init(&a); + * lv_style_anim_set_...(&a); + * lv_style_anim_create(&a); + * @param a pointer to an `lv_anim_t` variable to initialize */ -void * lv_style_anim_create(lv_style_anim_t * anim); +void lv_style_anim_init(lv_anim_t * a); + +/** + * + * @param a pointer to an initialized `lv_anim_t` variable + * @param to_anim pointer to the style to animate + * @param start pointer to a style to animate from (start value) + * @param end pointer to a style to animate to (end value) + */ +void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end); + +/** + * Set the duration and delay of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param duration duration of the animation in milliseconds + * @param delay delay before the animation in milliseconds + */ +static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay) +{ + lv_anim_set_time(a, duration, delay); +} + +/** + * Set a function call when the animation is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param ready_cb a function call when the animation is ready + */ +static inline void lv_style_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb) +{ + lv_style_anim_dsc_t * dsc = a->var; + dsc->ready_cb = ready_cb; +} + +/** + * Make the animation to play back to when the forward direction is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the back direction + */ +static inline void lv_style_anim_set_playback(lv_anim_t * a, uint16_t wait_time) +{ + lv_anim_set_playback(a, wait_time); +} + +/** + * Disable playback. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ +static inline void lv_style_anim_clear_playback(lv_anim_t * a) +{ + lv_anim_clear_playback(a); +} + +/** + * Make the animation to start again when ready. + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the animation again + */ +static inline void lv_style_anim_set_repeat(lv_anim_t * a, uint16_t wait_time) +{ + lv_anim_set_repeat(a, wait_time); +} + +/** + * Disable repeat. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ +static inline void lv_style_anim_clear_repeat(lv_anim_t * a) +{ + lv_anim_clear_repeat(a); +} + +/** + * Set a user specific data for the animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param user_data the user data + */ +static inline void lv_style_anim_set_user_data(lv_anim_t * a, lv_anim_user_data_t user_data) +{ + lv_anim_set_user_data(a, user_data); +} + +/** + * Get the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return the user data + */ +static inline lv_anim_user_data_t lv_style_anim_get_user_data(lv_anim_t * a) +{ + return lv_anim_get_user_data(a); +} + +/** + * Get pointer to the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return pointer to the user data + */ +static inline lv_anim_user_data_t * lv_style_anim_get_user_data_ptr(lv_anim_t * a) +{ + return lv_style_anim_get_user_data_ptr(a); +} + +/** + * Create an animation + * @param a an initialized 'anim_t' variable. Not required after call. + */ +static inline void lv_style_anim_create(lv_anim_t * a) +{ + return lv_anim_create(a); +} + #endif /************************* diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index 24d158325..77251a40c 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -61,15 +61,30 @@ void lv_anim_core_init(void) } /** - * Create an animation - * @param anim_p an initialized 'anim_t' variable. Not required after call. + * Initialize an animation variable. + * E.g.: + * lv_anim_t a; + * lv_anim_init(&a); + * lv_anim_set_...(&a); + * lv_anim_craete(&a); + * @param a pointer to an `lv_anim_t` variable to initialize */ -void lv_anim_create(lv_anim_t * anim_p) +void lv_anim_init(lv_anim_t * a) +{ + memset(a, 0, sizeof(lv_anim_t)); + a->time = 500; + a->end = 100; +} +/** + * Create an animation + * @param a an initialized 'anim_t' variable. Not required after call. + */ +void lv_anim_create(lv_anim_t * a) { LV_LOG_TRACE("animation create started") /* Do not let two animations for the same 'var' with the same 'fp'*/ - if(anim_p->exec_cb != NULL) - lv_anim_del(anim_p->var, anim_p->exec_cb); /*fp == NULL would delete all animations of var*/ + if(a->exec_cb != NULL) + lv_anim_del(a->var, a->exec_cb); /*fp == NULL would delete all animations of var*/ /*Add the new animation to the animation linked list*/ lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll)); @@ -77,8 +92,8 @@ void lv_anim_create(lv_anim_t * anim_p) if(new_anim == NULL) return; /*Initialize the animation descriptor*/ - anim_p->playback_now = 0; - memcpy(new_anim, anim_p, sizeof(lv_anim_t)); + a->playback_now = 0; + memcpy(new_anim, a, sizeof(lv_anim_t)); /*Set the start value*/ if(new_anim->exec_cb != NULL) new_anim->exec_cb(new_anim->var, new_anim->start); diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index 393a7c6fa..77e50b8b4 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -23,6 +23,7 @@ extern "C" { #include #include +#include /********************* * DEFINES @@ -32,19 +33,28 @@ extern "C" { * TYPEDEFS **********************/ -typedef int16_t lv_anim_value_t; /*Type of the animated value*/ - struct _lv_anim_t; -/*Generic prototype of "animator" functions*/ +/*Type of the animated value*/ +typedef int16_t lv_anim_value_t; + +/* Generic prototype of "animator" functions. + * First parameter is the variable to animate. + * Second parameter is the value to set. + * Compatible with `lv_xxx_set_yyy(obj, value)` functions*/ typedef void (*lv_anim_exec_cb_t)(void *, lv_anim_value_t); -/*Get the current value in an animation*/ +/* Same as `lv_anim_exec_cb_t` but receives `lv_anim_t *` as the first parameter. + * It's more consistent but less convenient. Might be used by binding generator functions.*/ +typedef void (*lv_anim_custom_exec_cb_t)(struct _lv_anim_t *, lv_anim_value_t); + +/*Get the current value during an animation*/ typedef lv_anim_value_t (*lv_anim_path_cb_t)(const struct _lv_anim_t *); -/*Callback for animation ready*/ +/*Callback to call when the animation is ready*/ typedef void (*lv_anim_ready_cb_t)(struct _lv_anim_t *); +/*Describe an animation*/ typedef struct _lv_anim_t { void * var; /*Variable to animate*/ @@ -71,26 +81,9 @@ typedef struct _lv_anim_t uint8_t repeat : 1; /*Repeat the animation infinitely*/ /*Animation system use these - user shouldn't set*/ uint8_t playback_now : 1; /*Play back is in progress*/ - uint32_t has_run : 1; /*Indicates the animation has run it this round*/ + uint32_t has_run : 1; /*Indicates the animation has run in this round*/ } lv_anim_t; -/*Example initialization -lv_anim_t a; -a.var = obj; -a.start = lv_obj_get_height(obj); -a.end = new_height; -a.exec_cb = (lv_anim_exec_cb_t)lv_obj_set_height; -a.path_cb = lv_anim_path_linear; -a.ready_cb = NULL; -a.act_time = 0; -a.time = 200; -a.playback = 0; -a.playback_pause = 0; -a.repeat = 0; -a.repeat_pause = 0; -a.user_data = NULL; -lv_anim_create(&a); - */ /********************** * GLOBAL PROTOTYPES **********************/ @@ -100,92 +93,172 @@ lv_anim_create(&a); */ void lv_anim_core_init(void); +/** + * Initialize an animation variable. + * E.g.: + * lv_anim_t a; + * lv_anim_init(&a); + * lv_anim_set_...(&a); + * lv_anim_create(&a); + * @param a pointer to an `lv_anim_t` variable to initialize + */ +void lv_anim_init(lv_anim_t * a); /** - * Initialize an animation variable - * @param a pointer to animation + * Set a variable to animate + * @param a pointer to an initialized `lv_anim_t` variable + * @param var pointer to a variable to animate */ -static inline void lv_anim_init(lv_anim_t * a) -{ - memset(a, 0, sizeof(lv_anim_t)); -} - - static inline void lv_anim_set_var(lv_anim_t * a, void * var) { a->var = var; } +/** + * Set the duration and delay of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param duration duration of the animation in milliseconds + * @param delay delay before the animation in milliseconds + */ static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay) { a->time = duration; a->act_time = -delay; } +/** + * Set the start and end values of an animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param start the start value + * @param end the end value + */ static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end) { a->start = start; a->end = end; } +/** + * Set a function to execute by the aniamtion + * @param a pointer to an initialized `lv_anim_t` variable + * @param exec_cb a function to execute. + * LittelvGL's built-in functions can be used. + * E.g. lv_obj_set_x + */ static inline void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_cb_t exec_cb) { a->exec_cb = exec_cb; } +/** + * The same as `lv_anim_set_exec_cb` but `lv_anim_custom_exec_cb_t` receives + * `lv_anim_t * ` as its first parameter instead of `void *`. + * This function might be used when LittlevGL is binded to other languages because + * it's more consistent to have `lv_anim_t *` as first parameter. + * @param a pointer to an initialized `lv_anim_t` variable + * @param exec_cb a function to execute. + */ +static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +{ + a->exec_cb = (lv_anim_exec_cb_t)exec_cb; +} + +/** + * Set the path (curve) of the animation. + * @param a pointer to an initialized `lv_anim_t` variable + * @param path_cb a function the get the current value of the animation. + * The built in functions starts with `lv_anim_path_...` + */ static inline void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb) { a->path_cb = path_cb; } +/** + * Set a function call when the animation is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param ready_cb a function call when the animation is ready + */ static inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb) { a->ready_cb = ready_cb; } +/** + * Make the animation to play back to when the forward direction is ready + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the back direction + */ static inline void lv_anim_set_playback(lv_anim_t * a, uint16_t wait_time) { a->playback = 1; a->playback_pause = wait_time; } +/** + * Disable playback. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ static inline void lv_anim_clear_playback(lv_anim_t * a) { a->playback = 0; } +/** + * Make the animation to start again when ready. + * @param a pointer to an initialized `lv_anim_t` variable + * @param wait_time time in milliseconds to wait before starting the animation again + */ static inline void lv_anim_set_repeat(lv_anim_t * a, uint16_t wait_time) { a->repeat = 1; a->repeat_pause = wait_time; } +/** + * Disable repeat. (Disabled after `lv_anim_init()`) + * @param a pointer to an initialized `lv_anim_t` variable + */ static inline void lv_anim_clear_repeat(lv_anim_t * a) { a->repeat = 0; } +/** + * Set a user specific data for the animation + * @param a pointer to an initialized `lv_anim_t` variable + * @param user_data the user data + */ static inline void lv_anim_set_user_data(lv_anim_t * a, lv_anim_user_data_t user_data) { memcpy(&a->user_data, &user_data, sizeof(user_data)); } +/** + * Get the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return the user data + */ static inline lv_anim_user_data_t lv_anim_get_user_data(lv_anim_t * a) { return a->user_data; } +/** + * Get pointer to the user data + * @param a pointer to an initialized `lv_anim_t` variable + * @return pointer to the user data + */ static inline lv_anim_user_data_t * lv_anim_get_user_data_ptr(lv_anim_t * a) { return &a->user_data; } - /** * Create an animation - * @param anim_p an initialized 'anim_t' variable. Not required after call. + * @param a an initialized 'anim_t' variable. Not required after call. */ -void lv_anim_create(lv_anim_t * anim_p); +void lv_anim_create(lv_anim_t * a); /** * Delete an animation for a variable with a given animatior function From 78c527ee4fc8784c4595d4a64e58a9d8ec55de2c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 18:50:38 +0200 Subject: [PATCH 14/27] remove LV_USE_USER_DATA_MULTI --- lv_conf_template.h | 3 --- src/lv_conf_checker.h | 5 ----- src/lv_core/lv_group.c | 6 ------ src/lv_core/lv_group.h | 6 ------ src/lv_core/lv_obj.c | 16 ---------------- src/lv_core/lv_obj.h | 6 ------ src/lv_draw/lv_draw.mk | 1 + src/lv_draw/lv_img_decoder.c | 2 ++ src/lv_hal/lv_hal_disp.h | 9 --------- src/lv_hal/lv_hal_indev.h | 6 ------ src/lv_misc/lv_anim.h | 6 ------ src/lv_misc/lv_task.c | 4 ---- src/lv_misc/lv_task.h | 4 ---- 13 files changed, 3 insertions(+), 71 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index 7eb4065f6..baa076c03 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -151,9 +151,6 @@ typedef void * lv_img_decoder_user_data_t; /*1: Add a `user_data` to drivers and objects*/ #define LV_USE_USER_DATA_SINGLE 1 -/*1: Add separate `user_data` for every callback*/ -#define LV_USE_USER_DATA_MULTI 0 - /*===================== * Compiler settings *====================*/ diff --git a/src/lv_conf_checker.h b/src/lv_conf_checker.h index 770a84ae5..e7f975b54 100644 --- a/src/lv_conf_checker.h +++ b/src/lv_conf_checker.h @@ -209,11 +209,6 @@ #define LV_USE_USER_DATA_SINGLE 1 #endif -/*1: Add separate `user_data` for every callback*/ -#ifndef LV_USE_USER_DATA_MULTI -#define LV_USE_USER_DATA_MULTI 0 -#endif - /*===================== * Compiler settings *====================*/ diff --git a/src/lv_core/lv_group.c b/src/lv_core/lv_group.c index 2a0afee30..98c36a825 100644 --- a/src/lv_core/lv_group.c +++ b/src/lv_core/lv_group.c @@ -78,12 +78,6 @@ lv_group_t * lv_group_create(void) memset(&group->user_data, 0, sizeof(lv_group_user_data_t)); #endif -#if LV_USE_USER_DATA_MULTI - memset(&group->focus_user_data, 0, sizeof(lv_group_user_data_t)); - memset(&group->style_mod_user_data, 0, sizeof(lv_group_user_data_t)); - memset(&group->style_mod_edit_user_data, 0, sizeof(lv_group_user_data_t)); -#endif - /*Initialize style modification callbacks from current theme*/ refresh_theme(group, lv_theme_get_current()); diff --git a/src/lv_core/lv_group.h b/src/lv_core/lv_group.h index 6119df80c..8827325e9 100644 --- a/src/lv_core/lv_group.h +++ b/src/lv_core/lv_group.h @@ -65,12 +65,6 @@ typedef struct _lv_group_t lv_group_user_data_t user_data; #endif -#if LV_USE_USER_DATA_MULTI - lv_group_user_data_t focus_user_data; - lv_group_user_data_t style_mod_user_data; - lv_group_user_data_t style_mod_edit_user_data; -#endif - uint8_t frozen : 1; /*1: can't focus to new object*/ uint8_t editing : 1; /*1: Edit mode, 0: Navigate mode*/ uint8_t click_focus : 1; /*1: If an object in a group is clicked by an indev then it will be diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index df24e25c3..5735e0810 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -188,11 +188,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) #if LV_USE_USER_DATA_SINGLE memset(&new_obj->user_data, 0, sizeof(lv_obj_user_data_t)); #endif -#if LV_USE_USER_DATA_MULTI - memset(&new_obj->event_user_data, 0, sizeof(lv_obj_user_data_t)); - memset(&new_obj->signal_user_data, 0, sizeof(lv_obj_user_data_t)); - memset(&new_obj->design_user_data, 0, sizeof(lv_obj_user_data_t)); -#endif #if LV_USE_GROUP new_obj->group_p = NULL; @@ -275,11 +270,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) #if LV_USE_USER_DATA_SINGLE memset(&new_obj->user_data, 0, sizeof(lv_obj_user_data_t)); #endif -#if LV_USE_USER_DATA_MULTI - memset(&new_obj->event_user_data, 0, sizeof(lv_obj_user_data_t)); - memset(&new_obj->signal_user_data, 0, sizeof(lv_obj_user_data_t)); - memset(&new_obj->design_user_data, 0, sizeof(lv_obj_user_data_t)); -#endif #if LV_USE_GROUP new_obj->group_p = NULL; @@ -319,12 +309,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) #if LV_USE_USER_DATA_SINGLE memcpy(&new_obj->user_data, ©->user_data, sizeof(lv_obj_user_data_t)); #endif -#if LV_USE_USER_DATA_MULTI - memcpy(&new_obj->event_user_data, ©->event_user_data, sizeof(lv_obj_user_data_t)); - memcpy(&new_obj->signal_user_data, ©->signal_user_data, sizeof(lv_obj_user_data_t)); - memcpy(&new_obj->design_user_data, ©->design_user_data, sizeof(lv_obj_user_data_t)); -#endif - /*Copy realign*/ #if LV_USE_OBJ_REALIGN new_obj->realign.align = copy->realign.align; diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 5cec76484..2e1debe91 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -223,12 +223,6 @@ typedef struct _lv_obj_t lv_obj_user_data_t user_data; #endif -#if LV_USE_USER_DATA_MULTI - lv_obj_user_data_t event_user_data; - lv_obj_user_data_t signal_user_data; - lv_obj_user_data_t design_user_data; -#endif - } lv_obj_t; /*Protect some attributes (max. 8 bit)*/ diff --git a/src/lv_draw/lv_draw.mk b/src/lv_draw/lv_draw.mk index ac9e76041..43b5ee48a 100644 --- a/src/lv_draw/lv_draw.mk +++ b/src/lv_draw/lv_draw.mk @@ -6,6 +6,7 @@ CSRCS += lv_draw_line.c CSRCS += lv_draw_img.c CSRCS += lv_draw_arc.c CSRCS += lv_draw_triangle.c +CSRCS += lv_img_decoder.c DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_draw VPATH += :$(LVGL_DIR)/lvgl/src/lv_draw diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index b52cd7de2..5822be982 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -196,6 +196,8 @@ void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc) static lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header) { + (void)decoder; /*Unused*/ + lv_img_src_t src_type = lv_img_src_get_type(src); if(src_type == LV_IMG_SRC_VARIABLE) { header->w = ((lv_img_dsc_t *)src)->header.w; diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index 320af018e..e541d4279 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -103,15 +103,6 @@ typedef struct _disp_drv_t lv_disp_drv_user_data_t user_data; #endif -#if LV_USE_USER_DATA_MULTI - lv_disp_drv_user_data_t flush_user_data; - lv_disp_drv_user_data_t mem_blend_user_data; - lv_disp_drv_user_data_t mem_fill_user_data; - lv_disp_drv_user_data_t rounder_user_data; - lv_disp_drv_user_data_t set_px_user_data; - lv_disp_drv_user_data_t monitor_user_data; -#endif - } lv_disp_drv_t; struct _lv_obj_t; diff --git a/src/lv_hal/lv_hal_indev.h b/src/lv_hal/lv_hal_indev.h index d5ac7f4f2..97ab836e6 100644 --- a/src/lv_hal/lv_hal_indev.h +++ b/src/lv_hal/lv_hal_indev.h @@ -85,12 +85,6 @@ typedef struct _lv_indev_drv_t lv_indev_drv_user_data_t user_data; #endif -#if LV_USE_USER_DATA_MULTI - lv_indev_drv_user_data_t read_user_data; - lv_indev_drv_user_data_t feedback_user_data; -#endif - - /*Pointer to the assigned display*/ struct _disp_t * disp; diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index 77e50b8b4..a86052e14 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -71,12 +71,6 @@ typedef struct _lv_anim_t lv_anim_user_data_t user_data; /*Custom user data*/ #endif -#if LV_USE_USER_DATA_MULTI - lv_anim_user_data_t exec_user_data; - lv_anim_user_data_t path_user_data; - lv_anim_user_data_t ready_user_data; -#endif - uint8_t playback : 1; /*When the animation is ready play it back*/ uint8_t repeat : 1; /*Repeat the animation infinitely*/ /*Animation system use these - user shouldn't set*/ diff --git a/src/lv_misc/lv_task.c b/src/lv_misc/lv_task.c index af7c105aa..c0ac14335 100644 --- a/src/lv_misc/lv_task.c +++ b/src/lv_misc/lv_task.c @@ -206,10 +206,6 @@ lv_task_t * lv_task_create(void (*task)(lv_task_t *), uint32_t period, lv_task_p new_lv_task->user_data = user_data; -#if LV_USE_USER_DATA_MULTI - new_lv_task->task_user_data = NULL; -#endif - task_created = true; return new_lv_task; diff --git a/src/lv_misc/lv_task.h b/src/lv_misc/lv_task.h index 0a01a6acf..67b219a71 100644 --- a/src/lv_misc/lv_task.h +++ b/src/lv_misc/lv_task.h @@ -59,10 +59,6 @@ typedef struct _lv_task_t void * user_data; -#if LV_USE_USER_DATA_MULTI - void * task_user_data; -#endif - uint8_t prio : 3; uint8_t once : 1; } lv_task_t; From de824833a00bbb6a113080995e0b5eaae2dde514 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 18:51:31 +0200 Subject: [PATCH 15/27] remove LV_USE_USER_DATA_SINGE to LV_USE_USER_DATA --- lv_conf_template.h | 2 +- src/lv_conf_checker.h | 4 ++-- src/lv_core/lv_group.c | 4 ++-- src/lv_core/lv_group.h | 4 ++-- src/lv_core/lv_obj.c | 8 ++++---- src/lv_core/lv_obj.h | 4 ++-- src/lv_draw/lv_img_decoder.h | 4 ++-- src/lv_hal/lv_hal_disp.h | 2 +- src/lv_hal/lv_hal_indev.h | 2 +- src/lv_misc/lv_anim.h | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index baa076c03..c9a8a62d0 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -149,7 +149,7 @@ typedef void * lv_group_user_data_t; typedef void * lv_img_decoder_user_data_t; /*1: Add a `user_data` to drivers and objects*/ -#define LV_USE_USER_DATA_SINGLE 1 +#define LV_USE_USER_DATA 1 /*===================== * Compiler settings diff --git a/src/lv_conf_checker.h b/src/lv_conf_checker.h index e7f975b54..8be7b83d9 100644 --- a/src/lv_conf_checker.h +++ b/src/lv_conf_checker.h @@ -205,8 +205,8 @@ #endif /*1: Add a `user_data` to drivers and objects*/ -#ifndef LV_USE_USER_DATA_SINGLE -#define LV_USE_USER_DATA_SINGLE 1 +#ifndef LV_USE_USER_DATA +#define LV_USE_USER_DATA 1 #endif /*===================== diff --git a/src/lv_core/lv_group.c b/src/lv_core/lv_group.c index 98c36a825..fd5f25753 100644 --- a/src/lv_core/lv_group.c +++ b/src/lv_core/lv_group.c @@ -74,7 +74,7 @@ lv_group_t * lv_group_create(void) group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV; group->wrap = 1; -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA memset(&group->user_data, 0, sizeof(lv_group_user_data_t)); #endif @@ -403,7 +403,7 @@ lv_obj_t * lv_group_get_focused(const lv_group_t * group) return *group->obj_focus; } -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA /** * Get a pointer to the group's user data * @param group pointer to an group diff --git a/src/lv_core/lv_group.h b/src/lv_core/lv_group.h index 8827325e9..89d71ee8b 100644 --- a/src/lv_core/lv_group.h +++ b/src/lv_core/lv_group.h @@ -61,7 +61,7 @@ typedef struct _lv_group_t lv_group_style_mod_cb_t style_mod_edit_cb; /*A function which modifies the style of the edited object*/ lv_group_focus_cb_t focus_cb; /*A function to call when a new object is focused (optional)*/ lv_style_t style_tmp; /*Stores the modified style of the focused object */ -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA lv_group_user_data_t user_data; #endif @@ -211,7 +211,7 @@ lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style); */ lv_obj_t * lv_group_get_focused(const lv_group_t * group); -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA /** * Get a pointer to the group's user data * @param group pointer to an group diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 5735e0810..5bbd838c1 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -185,7 +185,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->event_cb = NULL; /*Init. user date*/ -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA memset(&new_obj->user_data, 0, sizeof(lv_obj_user_data_t)); #endif @@ -267,7 +267,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) #endif /*Init. user date*/ -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA memset(&new_obj->user_data, 0, sizeof(lv_obj_user_data_t)); #endif @@ -306,7 +306,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) #endif /*Set free data*/ -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA memcpy(&new_obj->user_data, ©->user_data, sizeof(lv_obj_user_data_t)); #endif /*Copy realign*/ @@ -1958,7 +1958,7 @@ void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf) } } -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA /** * Get the object's user data diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 2e1debe91..47aad3231 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -219,7 +219,7 @@ typedef struct _lv_obj_t lv_reailgn_t realign; #endif -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA lv_obj_user_data_t user_data; #endif @@ -896,7 +896,7 @@ void * lv_obj_get_ext_attr(const lv_obj_t * obj); */ void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf); -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA /** * Get the object's user data * @param obj pointer to an object diff --git a/src/lv_draw/lv_img_decoder.h b/src/lv_draw/lv_img_decoder.h index 058360323..2dc6227bf 100644 --- a/src/lv_draw/lv_img_decoder.h +++ b/src/lv_draw/lv_img_decoder.h @@ -155,7 +155,7 @@ typedef struct _lv_img_decoder { lv_img_decoder_read_line_f_t read_line_cb; lv_img_decoder_close_f_t close_cb; -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA lv_img_decoder_user_data_t user_data; #endif }lv_img_decoder_t; @@ -168,7 +168,7 @@ typedef struct _lv_img_decoder_dsc { lv_img_src_t src_type; lv_img_header_t header; -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA void * user_data; #endif }lv_img_decoder_dsc_t; diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index e541d4279..ba35b6c67 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -99,7 +99,7 @@ typedef struct _disp_drv_t const lv_area_t * fill_area, lv_color_t color); #endif -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA lv_disp_drv_user_data_t user_data; #endif diff --git a/src/lv_hal/lv_hal_indev.h b/src/lv_hal/lv_hal_indev.h index 97ab836e6..cea6ebba7 100644 --- a/src/lv_hal/lv_hal_indev.h +++ b/src/lv_hal/lv_hal_indev.h @@ -81,7 +81,7 @@ typedef struct _lv_indev_drv_t /*Called when an action happened on the input device.*/ void (*feedback_cb)(struct _lv_indev_drv_t *, uint8_t); -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA lv_indev_drv_user_data_t user_data; #endif diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index a86052e14..39d65c5bc 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -67,7 +67,7 @@ typedef struct _lv_anim_t int16_t act_time; /*Current time in animation. Set to negative to make delay.*/ uint16_t playback_pause; /*Wait before play back*/ uint16_t repeat_pause; /*Wait before repeat*/ -#if LV_USE_USER_DATA_SINGLE +#if LV_USE_USER_DATA lv_anim_user_data_t user_data; /*Custom user data*/ #endif From 5a712931efb20bcea8a3f95aef02be488fd5180e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 May 2019 18:58:01 +0200 Subject: [PATCH 16/27] lv_page: fix vertical scrollbar position --- src/lv_objx/lv_page.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/lv_objx/lv_page.c b/src/lv_objx/lv_page.c index 49dc46143..e243add98 100644 --- a/src/lv_objx/lv_page.c +++ b/src/lv_objx/lv_page.c @@ -1124,15 +1124,16 @@ static void lv_page_sb_refresh(lv_obj_t * page) return; } - /*Horizontal scrollbar*/ + /*Full sized horizontal scrollbar*/ if(scrl_w <= - obj_w - style->body.padding.left - style->body.padding.right) { /*Full sized scroll bar*/ + obj_w - style->body.padding.left - style->body.padding.right) { lv_area_set_width(&ext->sb.hor_area, obj_w - 2 * sb_hor_pad); lv_area_set_pos(&ext->sb.hor_area, sb_hor_pad, - obj_h - ext->sb.style->body.padding.inner - - ext->sb.style->body.padding.bottom); + obj_h - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.bottom); if(ext->sb.mode == LV_SB_MODE_AUTO || ext->sb.mode == LV_SB_MODE_DRAG) ext->sb.hor_draw = 0; - } else { + } + /*Smaller horizontal scrollbar*/ + else { size_tmp = (obj_w * (obj_w - (2 * sb_hor_pad))) / (scrl_w + style->body.padding.left + style->body.padding.right); if(size_tmp < LV_PAGE_SB_MIN_SIZE) size_tmp = LV_PAGE_SB_MIN_SIZE; @@ -1149,16 +1150,16 @@ static void lv_page_sb_refresh(lv_obj_t * page) if(ext->sb.mode == LV_SB_MODE_AUTO || ext->sb.mode == LV_SB_MODE_DRAG) ext->sb.hor_draw = 1; } - /*Vertical scrollbar*/ - if(scrl_h <= - obj_h - style->body.padding.top - style->body.padding.bottom) { /*Full sized scroll bar*/ + /*Full sized vertical scroll bar*/ + if(scrl_h <= obj_h - style->body.padding.top - style->body.padding.bottom) { lv_area_set_height(&ext->sb.ver_area, obj_h - 2 * sb_ver_pad); lv_area_set_pos(&ext->sb.ver_area, - obj_w - ext->sb.style->body.padding.inner - - ext->sb.style->body.padding.right, + obj_w - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.right, sb_ver_pad); if(ext->sb.mode == LV_SB_MODE_AUTO || ext->sb.mode == LV_SB_MODE_DRAG) ext->sb.ver_draw = 0; - } else { + } + /*Smaller vertical scroll bar*/ + else { size_tmp = (obj_h * (obj_h - (2 * sb_ver_pad))) / (scrl_h + style->body.padding.top + style->body.padding.bottom); if(size_tmp < LV_PAGE_SB_MIN_SIZE) size_tmp = LV_PAGE_SB_MIN_SIZE; @@ -1166,7 +1167,7 @@ static void lv_page_sb_refresh(lv_obj_t * page) lv_area_set_pos( &ext->sb.ver_area, - obj_w - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.bottom, + obj_w - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.right, sb_ver_pad + (-(lv_obj_get_y(scrl) - ext->sb.style->body.padding.bottom) * (obj_h - size_tmp - 2 * sb_ver_pad)) / From c1b8c2f522ca113bb8b3b67405564382b60fed14 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 16 May 2019 10:27:45 +0200 Subject: [PATCH 17/27] imgbtn: follow image decder changes --- src/lv_objx/lv_imgbtn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_objx/lv_imgbtn.c b/src/lv_objx/lv_imgbtn.c index 58a03b1c6..952644087 100644 --- a/src/lv_objx/lv_imgbtn.c +++ b/src/lv_objx/lv_imgbtn.c @@ -281,7 +281,7 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig src = ext->img_src_left[state]; if(src) { - lv_img_dsc_get_info(src, &header); + lv_img_decoder_get_info(src, &header); left_w = header.w; coords.x1 = imgbtn->coords.x1; coords.y1 = imgbtn->coords.y1; @@ -292,7 +292,7 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig src = ext->img_src_right[state]; if(src) { - lv_img_dsc_get_info(src, &header); + lv_img_decoder_get_info(src, &header); right_w = header.w; coords.x1 = imgbtn->coords.x2 - header.w + 1; coords.y1 = imgbtn->coords.y1; @@ -305,7 +305,7 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig if(src) { lv_coord_t obj_w = lv_obj_get_width(imgbtn); lv_coord_t i; - lv_img_dsc_get_info(src, &header); + lv_img_decoder_get_info(src, &header); coords.x1 = imgbtn->coords.x1 + left_w; coords.y1 = imgbtn->coords.y1; From 04df148f0c55dfb421b9628841479493a7513549 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 16 May 2019 15:30:52 +0200 Subject: [PATCH 18/27] add comments to lv_img_decoder --- src/lv_draw/lv_img_decoder.c | 152 ++++++++++++++++++++++------------- src/lv_draw/lv_img_decoder.h | 126 +++++++++++++++++++++++++---- 2 files changed, 207 insertions(+), 71 deletions(-) diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index 5822be982..bf10848f4 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -81,59 +81,13 @@ void lv_img_decoder_init(void) lv_img_decoder_set_close_cb(decoder, lv_img_decoder_built_in_close); } -lv_img_decoder_t * lv_img_decoder_create(void) -{ - lv_img_decoder_t * decoder; - decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll)); - lv_mem_assert(decoder); - if(decoder == NULL) return NULL; - - memset(decoder, 0, sizeof(lv_img_decoder_t)); - - return decoder; -} - -void lv_img_decoder_delete(lv_img_decoder_t * decoder) -{ - lv_ll_rem(&LV_GC_ROOT(_lv_img_defoder_ll), decoder); - lv_mem_free(decoder); -} - -void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb) -{ - decoder->info_cb = info_cb; -} - -void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb) -{ - decoder->open_cb = open_cb; -} - -void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb) -{ - decoder->read_line_cb = read_line_cb; -} - -void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb) -{ - decoder->close_cb = close_cb; -} - -void lv_img_decoder_set_user_data(lv_img_decoder_t * decoder, lv_img_decoder_t user_data) -{ - memcpy(&decoder->user_data, &user_data, sizeof(user_data)); -} - -lv_img_decoder_user_data_t lv_img_decoder_get_user_data(lv_img_decoder_t * decoder) -{ - return decoder->user_data; -} - -lv_img_decoder_user_data_t * lv_img_decoder_get_user_data_ptr(lv_img_decoder_t * decoder) -{ - return &decoder->user_data; -} - +/** + * Get information about an image. + * Try the created image decoder one by one. Once one is able to get info that info will be used. + * @param src the image source. E.g. file name or variable. + * @param header the image info will be stored here + * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image + */ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) { header->always_zero = 0; @@ -151,6 +105,19 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) return res; } +/** + * Open an image. + * Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc` + * @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable. + * @param src the image source. Can be + * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`) + * 2) Variable: Pointer to an `lv_img_dsc_t` variable + * 3) Symbol: E.g. `LV_SYMBOL_OK` + * @param style the style of the image + * @return LV_IMG_DECODER_OPEN_FAIL: can open the image + * NULL: the image is opened but `lv_img_decoder_read_line` needs to be used to get the info line by line + * Else: a pointer to a buffer which holds the uncompressed pixels of the image + */ const uint8_t * lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style) { dsc->style = style; @@ -175,6 +142,15 @@ const uint8_t * lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src return res; } +/** + * Read a line from an opened image + * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open` + * @param x start X coordinate (from left) + * @param y start Y coordinate (from top) + * @param len number of pixels to read + * @param buf store the data here + * @return LV_RES_OK: success; LV_RES_INV: an error occurred + */ lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf) { lv_res_t res = LV_RES_INV; @@ -183,17 +159,85 @@ lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_c return res; } +/** + * Close a decoding session + * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open` + */ void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc) { if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc); } +/** + * Create a new image decoder + * @return pointer to the new image decoder + */ +lv_img_decoder_t * lv_img_decoder_create(void) +{ + lv_img_decoder_t * decoder; + decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll)); + lv_mem_assert(decoder); + if(decoder == NULL) return NULL; + + memset(decoder, 0, sizeof(lv_img_decoder_t)); + + return decoder; +} + +/** + * Delete an image decoder + * @param decoder pointer to an image decoder + */ +void lv_img_decoder_delete(lv_img_decoder_t * decoder) +{ + lv_ll_rem(&LV_GC_ROOT(_lv_img_defoder_ll), decoder); + lv_mem_free(decoder); +} + +/** + * Set a callback to get information about the image + * @param decoder pointer to an image decoder + * @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct) + */ +void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb) +{ + decoder->info_cb = info_cb; +} + +/** + * Set a callback to open an image + * @param decoder pointer to an image decoder + * @param open_cb a function to open an image + */ +void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb) +{ + decoder->open_cb = open_cb; +} + +/** + * Set a callback to a decoded line of an image + * @param decoder pointer to an image decoder + * @param read_line_cb a function to read a line of an image + */ +void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb) +{ + decoder->read_line_cb = read_line_cb; +} + +/** + * Set a callback to close a decoding session. E.g. close files and free other resources. + * @param decoder pointer to an image decoder + * @param close_cb a function to close a decoding session + */ +void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb) +{ + decoder->close_cb = close_cb; +} /********************** * STATIC FUNCTIONS **********************/ - static lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header) { (void)decoder; /*Unused*/ diff --git a/src/lv_draw/lv_img_decoder.h b/src/lv_draw/lv_img_decoder.h index 2dc6227bf..811247869 100644 --- a/src/lv_draw/lv_img_decoder.h +++ b/src/lv_draw/lv_img_decoder.h @@ -179,31 +179,123 @@ typedef struct _lv_img_decoder_dsc { /** * Initialize the image decoder module - * */ + */ void lv_img_decoder_init(void); -lv_img_decoder_t * lv_img_decoder_create(void); - -void lv_img_decoder_delete(lv_img_decoder_t * decoder); - -void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb); - -void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb); - -void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb); - -void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb); -void lv_img_decoder_set_user_data(lv_img_decoder_t * decoder, lv_img_decoder_t user_data); - -lv_img_decoder_user_data_t lv_img_decoder_get_user_data(lv_img_decoder_t * decoder); -lv_img_decoder_user_data_t * lv_img_decoder_get_user_data_ptr(lv_img_decoder_t * decoder); - +/** + * Get information about an image. + * Try the created image decoder one by one. Once one is able to get info that info will be used. + * @param src the image source. Can be + * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`) + * 2) Variable: Pointer to an `lv_img_dsc_t` variable + * 3) Symbol: E.g. `LV_SYMBOL_OK` + * @param header the image info will be stored here + * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image + */ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header); + +/** + * Open an image. + * Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc` + * @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable. + * @param src the image source. Can be + * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`) + * 2) Variable: Pointer to an `lv_img_dsc_t` variable + * 3) Symbol: E.g. `LV_SYMBOL_OK` + * @param style the style of the image + * @return LV_IMG_DECODER_OPEN_FAIL: can open the image + * NULL: the image is opened but `lv_img_decoder_read_line` needs to be used to get the info line by line + * Else: a pointer to a buffer which holds the uncompressed pixels of the image + */ const uint8_t * lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style); +/** + * Read a line from an opened image + * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open` + * @param x start X coordinate (from left) + * @param y start Y coordinate (from top) + * @param len number of pixels to read + * @param buf store the data here + * @return LV_RES_OK: success; LV_RES_INV: an error occurred + */ lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf); +/** + * Close a decoding session + * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open` + */ void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc); + +/** + * Create a new image decoder + * @return pointer to the new image decoder + */ +lv_img_decoder_t * lv_img_decoder_create(void); + +/** + * Delete an image decoder + * @param decoder pointer to an image decoder + */ +void lv_img_decoder_delete(lv_img_decoder_t * decoder); + +/** + * Set a callback to get information about the image + * @param decoder pointer to an image decoder + * @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct) + */ +void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb); + +/** + * Set a callback to open an image + * @param decoder pointer to an image decoder + * @param open_cb a function to open an image + */ +void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb); + +/** + * Set a callback to a decoded line of an image + * @param decoder pointer to an image decoder + * @param read_line_cb a function to read a line of an image + */ +void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb); + +/** + * Set a callback to close a decoding session. E.g. close files and free other resources. + * @param decoder pointer to an image decoder + * @param close_cb a function to close a decoding session + */ +void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb); + +/** + * Set a custom user data in an image decoder. + * @param decoder pointer to an image decoder + * @param user_data the user data to set + */ +static inline void lv_img_decoder_set_user_data(lv_img_decoder_t * decoder, lv_img_decoder_t user_data) +{ + memcpy(&decoder->user_data, &user_data, sizeof(user_data)); +} + +/** + * Get the user data + * @param decoder pointer to an image decoder + * @return the user data + */ +static inline lv_img_decoder_user_data_t lv_img_decoder_get_user_data(lv_img_decoder_t * decoder) +{ + return decoder->user_data; +} + +/** + * Get a pointer to the user data + * @param decoder pointer to an image decoder + * @return pointer to the user data + */ +static inline lv_img_decoder_user_data_t * lv_img_decoder_get_user_data_ptr(lv_img_decoder_t * decoder) +{ + return &decoder->user_data; +} + /********************** * MACROS **********************/ From bd15b805db64d228368443047d680fbf5be909de Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 16 May 2019 19:42:50 -0400 Subject: [PATCH 19/27] Apply fix from #1064 to dev-6.0 Fix mixup of SB and SCRL styles in lv_list_get_style --- src/lv_objx/lv_list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_objx/lv_list.c b/src/lv_objx/lv_list.c index 3d7e9dee4..6d06470a7 100644 --- a/src/lv_objx/lv_list.c +++ b/src/lv_objx/lv_list.c @@ -582,8 +582,8 @@ const lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type switch(type) { case LV_LIST_STYLE_BG: style = lv_page_get_style(list, LV_PAGE_STYLE_BG); break; - case LV_LIST_STYLE_SCRL: style = lv_page_get_style(list, LV_PAGE_STYLE_SB); break; - case LV_LIST_STYLE_SB: style = lv_page_get_style(list, LV_PAGE_STYLE_SCRL); break; + case LV_LIST_STYLE_SCRL: style = lv_page_get_style(list, LV_PAGE_STYLE_SCRL); break; + case LV_LIST_STYLE_SB: style = lv_page_get_style(list, LV_PAGE_STYLE_SB); break; case LV_LIST_STYLE_EDGE_FLASH: style = lv_page_get_style(list, LV_PAGE_STYLE_EDGE_FLASH); break; From e421e08c2fadbc4f81846c5634c8e96f49346ddb Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 07:39:56 +0200 Subject: [PATCH 20/27] remove unused lv_img_decoder_set_custom --- src/lv_draw/lv_draw_img.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index d8e927176..5db721af7 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -49,18 +49,6 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * */ lv_img_src_t lv_img_src_get_type(const void * src); -/** - * Set custom decoder functions. See the typdefs of the function typed above for more info about - * them - * @param info_fp info get function - * @param open_fp open function - * @param read_fp read line function - * @param close_fp clode function - */ -void lv_img_decoder_set_custom(lv_img_decoder_info_f_t info_fp, lv_img_decoder_open_f_t open_fp, - lv_img_decoder_read_line_f_t read_fp, - lv_img_decoder_close_f_t close_fp); - /** * Get the color of an image's pixel * @param dsc an image descriptor From 4c623cae445a88c2157922164d6bed8a6ac324d8 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 07:50:00 +0200 Subject: [PATCH 21/27] add lv_anim_del_custom --- src/lv_misc/lv_anim.c | 4 ++-- src/lv_misc/lv_anim.h | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index 77251a40c..5d8288c3c 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -112,7 +112,7 @@ void lv_anim_create(lv_anim_t * a) * or NULL to delete all animations of 'var' * @return true: at least 1 animation is deleted, false: no animation is deleted */ -bool lv_anim_del(void * var, lv_anim_exec_cb_t fp) +bool lv_anim_del(void * var, lv_anim_exec_cb_t exec_cb) { lv_anim_t * a; lv_anim_t * a_next; @@ -122,7 +122,7 @@ bool lv_anim_del(void * var, lv_anim_exec_cb_t fp) /*'a' might be deleted, so get the next object while 'a' is valid*/ a_next = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a); - if(a->var == var && (a->exec_cb == fp || fp == NULL)) { + if(a->var == var && (a->exec_cb == exec_cb || exec_cb == NULL)) { lv_ll_rem(&LV_GC_ROOT(_lv_anim_ll), a); lv_mem_free(a); anim_list_changed = true; /*Read by `anim_task`. It need to know if a delete occurred in diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index 39d65c5bc..a4bdbeec1 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -255,13 +255,29 @@ static inline lv_anim_user_data_t * lv_anim_get_user_data_ptr(lv_anim_t * a) void lv_anim_create(lv_anim_t * a); /** - * Delete an animation for a variable with a given animatior function + * Delete an animation of a variable with a given animator function * @param var pointer to variable - * @param fp a function pointer which is animating 'var', - * or NULL to ignore it and delete all animation with 'var + * @param exec_cb a function pointer which is animating 'var', + * or NULL to ignore it and delete all the animations of 'var * @return true: at least 1 animation is deleted, false: no animation is deleted */ -bool lv_anim_del(void * var, lv_anim_exec_cb_t fp); +bool lv_anim_del(void * var, lv_anim_exec_cb_t exec_cb); + +/** + * Delete an aniamation by getting the animated variable from `a`. + * Only animations with `exec_cb` will be deleted. + * This function exist becasue it's logical that all anim functions receives an + * `lv_anim_t` as their first parameter. It's not practical in C but might makes + * the API more conequent and makes easier to genrate bindings. + * @param a pointer to an animation. + * @param exec_cb a function pointer which is animating 'var', + * or NULL to ignore it and delete all the animations of 'var + * @return true: at least 1 animation is deleted, false: no animation is deleted + */ +static inline bool lv_anim_del_custom(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +{ + return lv_anim_del(a->var, (lv_anim_exec_cb_t)exec_cb); +} /** * Get the number of currently running animations From b926fd496605c1b7068e54b2f9330f9e7daf90a7 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 07:58:47 +0200 Subject: [PATCH 22/27] add lv_task_set_cb --- src/lv_core/lv_obj.c | 2 +- src/lv_misc/lv_anim.c | 6 +++--- src/lv_misc/lv_task.c | 12 +++++++++++- src/lv_misc/lv_task.h | 21 ++++++++++++++++++--- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 5bbd838c1..667eb5ad2 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -82,7 +82,7 @@ void lv_init(void) /*Initialize the lv_misc modules*/ lv_mem_init(); - lv_task_init(); + lv_task_core_init(); #if LV_USE_FILESYSTEM lv_fs_init(); diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index 5d8288c3c..40e9eec8b 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -106,10 +106,10 @@ void lv_anim_create(lv_anim_t * a) } /** - * Delete an animation for a variable with a given animator function + * Delete an animation of a variable with a given animator function * @param var pointer to variable - * @param fp a function pointer which is animating 'var', - * or NULL to delete all animations of 'var' + * @param exec_cb a function pointer which is animating 'var', + * or NULL to delete all the animations of 'var' * @return true: at least 1 animation is deleted, false: no animation is deleted */ bool lv_anim_del(void * var, lv_anim_exec_cb_t exec_cb) diff --git a/src/lv_misc/lv_task.c b/src/lv_misc/lv_task.c index c0ac14335..c68b5d0e3 100644 --- a/src/lv_misc/lv_task.c +++ b/src/lv_misc/lv_task.c @@ -49,7 +49,7 @@ static bool task_created; /** * Init the lv_task module */ -void lv_task_init(void) +void lv_task_core_init(void) { lv_ll_init(&LV_GC_ROOT(_lv_task_ll), sizeof(lv_task_t)); @@ -211,6 +211,16 @@ lv_task_t * lv_task_create(void (*task)(lv_task_t *), uint32_t period, lv_task_p return new_lv_task; } +/** + * Set the callback the task (the function to call periodically) + * @param task pointer to a task + * @param task_cb teh function to call periodically + */ +void lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb) +{ + task->task_cb = task_cb; +} + /** * Delete a lv_task * @param lv_task_p pointer to task created by lv_task_p diff --git a/src/lv_misc/lv_task.h b/src/lv_misc/lv_task.h index 67b219a71..322450032 100644 --- a/src/lv_misc/lv_task.h +++ b/src/lv_misc/lv_task.h @@ -34,6 +34,14 @@ extern "C" { /********************** * TYPEDEFS **********************/ + +struct _lv_task_t; + +/** + * Tasks execte this type type of functions. + */ +typedef void (*lv_task_cb_t)(struct _lv_task_t *); + /** * Possible priorities for lv_tasks */ @@ -55,7 +63,7 @@ typedef struct _lv_task_t { uint32_t period; uint32_t last_run; - void (*task_cb)(struct _lv_task_t *); + lv_task_cb_t task_cb; void * user_data; @@ -70,7 +78,7 @@ typedef struct _lv_task_t /** * Init the lv_task module */ -void lv_task_init(void); +void lv_task_core_init(void); /** * Call it periodically to handle lv_tasks. @@ -85,7 +93,7 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void); * @param user_data custom parameter * @return pointer to the new task_cb */ -lv_task_t * lv_task_create(void (*task)(lv_task_t *), uint32_t period, lv_task_prio_t prio, void * user_data); +lv_task_t * lv_task_create(lv_task_cb_t task_cb, uint32_t period, lv_task_prio_t prio, void * user_data); /** * Delete a lv_task @@ -93,6 +101,13 @@ lv_task_t * lv_task_create(void (*task)(lv_task_t *), uint32_t period, lv_task_p */ void lv_task_del(lv_task_t * lv_task_p); +/** + * Set the callback the task (the function to call periodically) + * @param task pointer to a task + * @param taack_cb teh function to call periodically + */ +void lv_task_set_cb(lv_task_t * task, lv_task_cb_t taack_cb); + /** * Set new priority for a lv_task * @param lv_task_p pointer to a lv_task From e525c08a0c692cd36b661d6dd6d187f32ef6a815 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 08:01:22 +0200 Subject: [PATCH 23/27] rename lv_anim_del_custom to lv_anim_custom_del --- src/lv_misc/lv_anim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index a4bdbeec1..552b7ac14 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -274,7 +274,7 @@ bool lv_anim_del(void * var, lv_anim_exec_cb_t exec_cb); * or NULL to ignore it and delete all the animations of 'var * @return true: at least 1 animation is deleted, false: no animation is deleted */ -static inline bool lv_anim_del_custom(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +static inline bool lv_anim_custom_del(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) { return lv_anim_del(a->var, (lv_anim_exec_cb_t)exec_cb); } From c136382be324d2909c49e8eccca1b948588963bf Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 08:29:38 +0200 Subject: [PATCH 24/27] add lv_task_create_basic --- src/lv_misc/lv_task.c | 166 ++++++++++++++++++++++++------------------ src/lv_misc/lv_task.h | 35 +++++---- 2 files changed, 118 insertions(+), 83 deletions(-) diff --git a/src/lv_misc/lv_task.c b/src/lv_misc/lv_task.c index c68b5d0e3..4b35e3997 100644 --- a/src/lv_misc/lv_task.c +++ b/src/lv_misc/lv_task.c @@ -20,6 +20,8 @@ * DEFINES *********************/ #define IDLE_MEAS_PERIOD 500 /*[ms]*/ +#define DEF_PRIO LV_TASK_PRIO_MID +#define DEF_PERIOD 500 /********************** * TYPEDEFS @@ -28,7 +30,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static bool lv_task_exec(lv_task_t * lv_task_p); +static bool lv_task_exec(lv_task_t * task); /********************** * STATIC VARIABLES @@ -159,6 +161,59 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void) LV_LOG_TRACE("lv_task_handler ready"); } +/** + * Create an "empty" task. It needs to initialzed with at least + * `lv_task_set_cb` and `lv_task_set_period` + * @return pointer to the craeted task + */ +lv_task_t * lv_task_create_basic(void) +{ + lv_task_t * new_task = NULL; + lv_task_t * tmp; + + /*Create task lists in order of priority from high to low*/ + tmp = lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll)); + + /*It's the first task*/ + if(NULL == tmp) { + new_task = lv_ll_ins_head(&LV_GC_ROOT(_lv_task_ll)); + lv_mem_assert(new_task); + if(new_task == NULL) return NULL; + } + /*Insert the new task to proper place according to its priority*/ + else { + do { + if(tmp->prio <= DEF_PRIO) { + new_task = lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp); + lv_mem_assert(new_task); + if(new_task == NULL) return NULL; + break; + } + tmp = lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), tmp); + } while(tmp != NULL); + + /*Only too high priority tasks were found. Add the task to the end*/ + if(tmp == NULL) { + new_task = lv_ll_ins_tail(&LV_GC_ROOT(_lv_task_ll)); + lv_mem_assert(new_task); + if(new_task == NULL) return NULL; + } + } + + new_task->period = DEF_PERIOD; + new_task->task_cb = NULL; + new_task->prio = DEF_PRIO; + + new_task->once = 0; + new_task->last_run = lv_tick_get(); + + new_task->user_data= NULL; + + task_created = true; + + return new_task; +} + /** * Create a new lv_task @@ -168,47 +223,18 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void) * @param user_data custom parameter * @return pointer to the new task */ -lv_task_t * lv_task_create(void (*task)(lv_task_t *), uint32_t period, lv_task_prio_t prio, void * user_data) +lv_task_t * lv_task_create(lv_task_cb_t task_cb, uint32_t period, lv_task_prio_t prio, void * user_data) { - lv_task_t * new_lv_task = NULL; - lv_task_t * tmp; + lv_task_t * new_task = lv_task_create_basic(); + lv_mem_assert(new_task); + if(new_task == NULL) return NULL; - /*Create task lists in order of priority from high to low*/ - tmp = lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll)); - if(NULL == tmp) { /*First task*/ - new_lv_task = lv_ll_ins_head(&LV_GC_ROOT(_lv_task_ll)); - lv_mem_assert(new_lv_task); - if(new_lv_task == NULL) return NULL; - } else { - do { - if(tmp->prio <= prio) { - new_lv_task = lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp); - lv_mem_assert(new_lv_task); - if(new_lv_task == NULL) return NULL; - break; - } - tmp = lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), tmp); - } while(tmp != NULL); + lv_task_set_cb(new_task, task_cb); + lv_task_set_period(new_task, period); + lv_task_set_prio(new_task, prio); + new_task->user_data = user_data; - if(tmp == NULL) { /*Only too high priority tasks were found*/ - new_lv_task = lv_ll_ins_tail(&LV_GC_ROOT(_lv_task_ll)); - lv_mem_assert(new_lv_task); - if(new_lv_task == NULL) return NULL; - } - } - - new_lv_task->period = period; - new_lv_task->task_cb = task; - new_lv_task->prio = prio; - - new_lv_task->once = 0; - new_lv_task->last_run = lv_tick_get(); - - new_lv_task->user_data = user_data; - - task_created = true; - - return new_lv_task; + return new_task; } /** @@ -223,78 +249,80 @@ void lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb) /** * Delete a lv_task - * @param lv_task_p pointer to task created by lv_task_p + * @param task pointer to task created by task */ -void lv_task_del(lv_task_t * lv_task_p) +void lv_task_del(lv_task_t * task) { - lv_ll_rem(&LV_GC_ROOT(_lv_task_ll), lv_task_p); + lv_ll_rem(&LV_GC_ROOT(_lv_task_ll), task); - lv_mem_free(lv_task_p); + lv_mem_free(task); - if(LV_GC_ROOT(_lv_task_act) == lv_task_p) task_deleted = true; /*The active task was deleted*/ + if(LV_GC_ROOT(_lv_task_act) == task) task_deleted = true; /*The active task was deleted*/ } /** * Set new priority for a lv_task - * @param lv_task_p pointer to a lv_task + * @param task pointer to a lv_task * @param prio the new priority */ -void lv_task_set_prio(lv_task_t * lv_task_p, lv_task_prio_t prio) +void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio) { + if(task->prio == prio) return; + /*Find the tasks with new priority*/ lv_task_t * i; LV_LL_READ(LV_GC_ROOT(_lv_task_ll), i) { if(i->prio <= prio) { - if(i != lv_task_p) lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), lv_task_p, i); + if(i != task) lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, i); break; } } /*There was no such a low priority so far then add the node to the tail*/ if(i == NULL) { - lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), lv_task_p, NULL); + lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, NULL); } - lv_task_p->prio = prio; + task->prio = prio; } /** * Set new period for a lv_task - * @param lv_task_p pointer to a lv_task + * @param task pointer to a lv_task * @param period the new period */ -void lv_task_set_period(lv_task_t * lv_task_p, uint32_t period) +void lv_task_set_period(lv_task_t * task, uint32_t period) { - lv_task_p->period = period; + task->period = period; } /** * Make a lv_task ready. It will not wait its period. - * @param lv_task_p pointer to a lv_task. + * @param task pointer to a lv_task. */ -void lv_task_ready(lv_task_t * lv_task_p) +void lv_task_ready(lv_task_t * task) { - lv_task_p->last_run = lv_tick_get() - lv_task_p->period - 1; + task->last_run = lv_tick_get() - task->period - 1; } /** * Delete the lv_task after one call - * @param lv_task_p pointer to a lv_task. + * @param task pointer to a lv_task. */ -void lv_task_once(lv_task_t * lv_task_p) +void lv_task_once(lv_task_t * task) { - lv_task_p->once = 1; + task->once = 1; } /** * Reset a lv_task. * It will be called the previously set period milliseconds later. - * @param lv_task_p pointer to a lv_task. + * @param task pointer to a lv_task. */ -void lv_task_reset(lv_task_t * lv_task_p) +void lv_task_reset(lv_task_t * task) { - lv_task_p->last_run = lv_tick_get(); + task->last_run = lv_tick_get(); } /** @@ -321,25 +349,25 @@ uint8_t lv_task_get_idle(void) /** * Execute task if its the priority is appropriate - * @param lv_task_p pointer to lv_task + * @param task pointer to lv_task * @return true: execute, false: not executed */ -static bool lv_task_exec(lv_task_t * lv_task_p) +static bool lv_task_exec(lv_task_t * task) { bool exec = false; /*Execute if at least 'period' time elapsed*/ - uint32_t elp = lv_tick_elaps(lv_task_p->last_run); - if(elp >= lv_task_p->period) { - lv_task_p->last_run = lv_tick_get(); + uint32_t elp = lv_tick_elaps(task->last_run); + if(elp >= task->period) { + task->last_run = lv_tick_get(); task_deleted = false; task_created = false; - lv_task_p->task_cb(lv_task_p); + if(task->task_cb) task->task_cb(task); /*Delete if it was a one shot lv_task*/ if(task_deleted == false) { /*The task might be deleted by itself as well*/ - if(lv_task_p->once != 0) { - lv_task_del(lv_task_p); + if(task->once != 0) { + lv_task_del(task); } } exec = true; diff --git a/src/lv_misc/lv_task.h b/src/lv_misc/lv_task.h index 322450032..7a814a6ff 100644 --- a/src/lv_misc/lv_task.h +++ b/src/lv_misc/lv_task.h @@ -85,21 +85,28 @@ void lv_task_core_init(void); */ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void); +/** + * Create an "empty" task. It needs to initialzed with at least + * `lv_task_set_cb` and `lv_task_set_period` + * @return pointer to the craeted task + */ +lv_task_t * lv_task_create_basic(void); + /** * Create a new lv_task * @param task a function which is the task itself * @param period call period in ms unit * @param prio priority of the task (LV_TASK_PRIO_OFF means the task is stopped) * @param user_data custom parameter - * @return pointer to the new task_cb + * @return pointer to the new task */ -lv_task_t * lv_task_create(lv_task_cb_t task_cb, uint32_t period, lv_task_prio_t prio, void * user_data); +lv_task_t * lv_task_create(lv_task_cb_t task_cb, uint32_t period, lv_task_prio_t prio, void * user_data); /** * Delete a lv_task - * @param lv_task_p pointer to task_cb created by lv_task_p + * @param task pointer to task_cb created by task */ -void lv_task_del(lv_task_t * lv_task_p); +void lv_task_del(lv_task_t * task); /** * Set the callback the task (the function to call periodically) @@ -110,36 +117,36 @@ void lv_task_set_cb(lv_task_t * task, lv_task_cb_t taack_cb); /** * Set new priority for a lv_task - * @param lv_task_p pointer to a lv_task + * @param task pointer to a lv_task * @param prio the new priority */ -void lv_task_set_prio(lv_task_t * lv_task_p, lv_task_prio_t prio); +void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio); /** * Set new period for a lv_task - * @param lv_task_p pointer to a lv_task + * @param task pointer to a lv_task * @param period the new period */ -void lv_task_set_period(lv_task_t * lv_task_p, uint32_t period); +void lv_task_set_period(lv_task_t * task, uint32_t period); /** * Make a lv_task ready. It will not wait its period. - * @param lv_task_p pointer to a lv_task. + * @param task pointer to a lv_task. */ -void lv_task_ready(lv_task_t * lv_task_p); +void lv_task_ready(lv_task_t * task); /** * Delete the lv_task after one call - * @param lv_task_p pointer to a lv_task. + * @param task pointer to a lv_task. */ -void lv_task_once(lv_task_t * lv_task_p); +void lv_task_once(lv_task_t * task); /** * Reset a lv_task. * It will be called the previously set period milliseconds later. - * @param lv_task_p pointer to a lv_task. + * @param task pointer to a lv_task. */ -void lv_task_reset(lv_task_t * lv_task_p); +void lv_task_reset(lv_task_t * task); /** * Enable or disable the whole lv_task handling From 1f334ba88be7a5f4c60a6882cf7355118aca6b74 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 08:29:51 +0200 Subject: [PATCH 25/27] mbox: close anim bugfix --- src/lv_objx/lv_mbox.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_objx/lv_mbox.c b/src/lv_objx/lv_mbox.c index cb9de0e2a..2a5aa026e 100644 --- a/src/lv_objx/lv_mbox.c +++ b/src/lv_objx/lv_mbox.c @@ -218,6 +218,7 @@ void lv_mbox_start_auto_close(lv_obj_t * mbox, uint16_t delay) lv_anim_create(&a); a.start = lv_obj_get_width(mbox); + a.exec_cb = (lv_anim_exec_cb_t)lv_obj_set_width; a.ready_cb = lv_mbox_close_ready_cb; lv_anim_create(&a); From b842db91aa9932cfe14ba31af082cd98cb753c98 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 08:42:25 +0200 Subject: [PATCH 26/27] lv_ll_move_before: bugfix --- src/lv_misc/lv_ll.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lv_misc/lv_ll.c b/src/lv_misc/lv_ll.c index 755a76ccb..438afedd1 100644 --- a/src/lv_misc/lv_ll.c +++ b/src/lv_misc/lv_ll.c @@ -355,6 +355,9 @@ void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after) /*If `n_act` was moved before NULL then it become the new tail*/ if(n_after == NULL) ll_p->tail = n_act; + + /*If `n_act` was moved before `NULL` then it's the new head*/ + if(n_before == NULL) ll_p->head = n_act; } /** From 1ef0c197cdd725a682f5140c66efb1fe45762e1d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 May 2019 09:03:53 +0200 Subject: [PATCH 27/27] built-in img decodder read line bug fix --- src/lv_draw/lv_img_decoder.c | 40 +++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index bf10848f4..a66303cbf 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -417,27 +417,29 @@ static lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, l lv_res_t res = LV_RES_INV; - if(dsc->src_type == LV_IMG_SRC_FILE) { - if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || - dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA || - dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) - { + if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA || + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) + { + /* For TRUE_COLOE images read line required only for files. + * For variables the image data was returned in `open`*/ + if(dsc->src_type == LV_IMG_SRC_FILE) { res = lv_img_decoder_built_in_line_true_color(dsc, x, y, len, buf); - } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || - dsc->header.cf == LV_IMG_CF_ALPHA_2BIT || - dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || - dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { - - res = lv_img_decoder_built_in_line_alpha(dsc, x, y, len, buf); - } else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || - dsc->header.cf == LV_IMG_CF_INDEXED_2BIT || - dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || - dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { - res = lv_img_decoder_built_in_line_indexed(dsc, x, y, len, buf); - } else { - LV_LOG_WARN("Built-in image decoder read not supports the color format"); - return false; } + } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || + dsc->header.cf == LV_IMG_CF_ALPHA_2BIT || + dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || + dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { + + res = lv_img_decoder_built_in_line_alpha(dsc, x, y, len, buf); + } else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || + dsc->header.cf == LV_IMG_CF_INDEXED_2BIT || + dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || + dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) { + res = lv_img_decoder_built_in_line_indexed(dsc, x, y, len, buf); + } else { + LV_LOG_WARN("Built-in image decoder read not supports the color format"); + return false; } return res;