1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-21 06:53:01 +08:00

Merge 1e91569763ecedd1cdbf24ae287c513af8d3cbeb into dev

This commit is contained in:
github-actions[bot] 2021-01-27 10:21:10 +00:00 committed by GitHub
commit b74b200485
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 66 deletions

View File

@ -47,10 +47,10 @@ typedef struct {
/** Format of font character map. */ /** Format of font character map. */
enum { enum {
LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,
LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL,
LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,
LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, LV_FONT_FMT_TXT_CMAP_SPARSE_FULL,
LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,
LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,
}; };
typedef uint8_t lv_font_fmt_txt_cmap_type_t; typedef uint8_t lv_font_fmt_txt_cmap_type_t;

View File

@ -48,6 +48,8 @@ typedef struct font_header_bin {
uint8_t compression_id; uint8_t compression_id;
uint8_t subpixels_mode; uint8_t subpixels_mode;
uint8_t padding; uint8_t padding;
int16_t underline_position;
uint16_t underline_thickness;
} font_header_bin_t; } font_header_bin_t;
typedef struct cmap_table_bin { typedef struct cmap_table_bin {
@ -68,7 +70,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font);
int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start); int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start);
static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res); static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res);
static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res); static unsigned int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res);
/********************** /**********************
* MACROS * MACROS
@ -95,20 +97,20 @@ lv_font_t * lv_font_load(const char * font_name)
if(res == LV_FS_RES_OK) { if(res == LV_FS_RES_OK) {
success = lvgl_load_font(&file, font); success = lvgl_load_font(&file, font);
}
if(!success) { if(!success) {
LV_LOG_WARN("Error loading font file: %s\n", font_name); LV_LOG_WARN("Error loading font file: %s\n", font_name);
/* /*
* When `lvgl_load_font` fails it can leak some pointers. * When `lvgl_load_font` fails it can leak some pointers.
* All non-null pointers can be assumed as allocated and * All non-null pointers can be assumed as allocated and
* `lv_font_free` should free them correctly. * `lv_font_free` should free them correctly.
*/ */
lv_font_free(font); lv_font_free(font);
font = NULL; font = NULL;
} }
lv_fs_close(&file); lv_fs_close(&file);
}
return font; return font;
} }
@ -194,9 +196,9 @@ static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp)
return it; return it;
} }
static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res) static unsigned int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res)
{ {
int value = 0; unsigned int value = 0;
while(n_bits--) { while(n_bits--) {
it->byte_value = it->byte_value << 1; it->byte_value = it->byte_value << 1;
it->bit_pos--; it->bit_pos--;
@ -205,7 +207,7 @@ static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res)
it->bit_pos = 7; it->bit_pos = 7;
*res = lv_fs_read(it->fp, &(it->byte_value), 1, NULL); *res = lv_fs_read(it->fp, &(it->byte_value), 1, NULL);
if(*res != LV_FS_RES_OK) { if(*res != LV_FS_RES_OK) {
return -1; return 0;
} }
} }
int8_t bit = (it->byte_value & 0x80) ? 1 : 0; int8_t bit = (it->byte_value & 0x80) ? 1 : 0;
@ -218,11 +220,9 @@ static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res)
static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res) static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res)
{ {
int value = read_bits(it, n_bits, res); unsigned int value = read_bits(it, n_bits, res);
if(value & (1 << (n_bits - 1))) { if(value & (1 << (n_bits - 1))) {
for(int bit = n_bits; bit < 16; ++bit) { value |= ~0u << n_bits;
value |= (1 << bit);
}
} }
return value; return value;
} }
@ -247,16 +247,8 @@ static int read_label(lv_fs_file_t * fp, int start, const char * label)
static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc,
uint32_t cmaps_start, cmap_table_bin_t * cmap_table) uint32_t cmaps_start, cmap_table_bin_t * cmap_table)
{ {
for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { if(lv_fs_read(fp, cmap_table, font_dsc->cmap_num * sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) {
if(lv_fs_read(fp, &cmap_table[i], sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) { return false;
return false;
}
lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) & (font_dsc->cmaps[i]);
cmap->range_start = cmap_table[i].range_start;
cmap->range_length = cmap_table[i].range_length;
cmap->glyph_id_start = cmap_table[i].glyph_id_start;
} }
for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) {
@ -267,8 +259,13 @@ static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_ds
lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) & (font_dsc->cmaps[i]); lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) & (font_dsc->cmaps[i]);
cmap->range_start = cmap_table[i].range_start;
cmap->range_length = cmap_table[i].range_length;
cmap->glyph_id_start = cmap_table[i].glyph_id_start;
cmap->type = cmap_table[i].format_type;
switch(cmap_table[i].format_type) { switch(cmap_table[i].format_type) {
case 0: { case LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL: {
uint8_t ids_size = sizeof(uint8_t) * cmap_table[i].data_entries_count; uint8_t ids_size = sizeof(uint8_t) * cmap_table[i].data_entries_count;
uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size); uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size);
@ -278,19 +275,13 @@ static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_ds
return false; return false;
} }
cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL;
cmap->list_length = cmap->range_length; cmap->list_length = cmap->range_length;
cmap->unicode_list = NULL;
break; break;
} }
case 2: case LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY:
cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY;
cmap->list_length = 0;
cmap->unicode_list = NULL;
cmap->glyph_id_ofs_list = NULL;
break; break;
case 1: case LV_FONT_FMT_TXT_CMAP_SPARSE_FULL:
case 3: { case LV_FONT_FMT_TXT_CMAP_SPARSE_TINY: {
uint32_t list_size = sizeof(uint16_t) * cmap_table[i].data_entries_count; uint32_t list_size = sizeof(uint16_t) * cmap_table[i].data_entries_count;
uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size); uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size);
@ -301,20 +292,15 @@ static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_ds
return false; return false;
} }
if(cmap_table[i].format_type == 1) { if(cmap_table[i].format_type == LV_FONT_FMT_TXT_CMAP_SPARSE_FULL) {
uint16_t * buf = lv_mem_alloc(sizeof(uint16_t) * cmap->list_length); uint16_t * buf = lv_mem_alloc(sizeof(uint16_t) * cmap->list_length);
cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_FULL;
cmap->glyph_id_ofs_list = buf; cmap->glyph_id_ofs_list = buf;
if(lv_fs_read(fp, buf, sizeof(uint16_t) * cmap->list_length, NULL) != LV_FS_RES_OK) { if(lv_fs_read(fp, buf, sizeof(uint16_t) * cmap->list_length, NULL) != LV_FS_RES_OK) {
return false; return false;
} }
} }
else {
cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY;
cmap->glyph_id_ofs_list = NULL;
}
break; break;
} }
default: default:
@ -460,12 +446,20 @@ static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc,
int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t)(glyph_length - 1); int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t)(glyph_length - 1);
int bmp_size = next_offset - glyph_offset[i] - nbits / 8; int bmp_size = next_offset - glyph_offset[i] - nbits / 8;
for(int k = 0; k < bmp_size; ++k) { if (nbits % 8 == 0) { /* Fast path */
glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res); if(lv_fs_read(fp, &glyph_bmp[cur_bmp_size], bmp_size, NULL) != LV_FS_RES_OK) {
if(res != LV_FS_RES_OK) {
return -1; return -1;
} }
} }
else {
for(int k = 0; k < bmp_size; ++k) {
glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res);
if(res != LV_FS_RES_OK) {
return -1;
}
}
}
cur_bmp_size += bmp_size; cur_bmp_size += bmp_size;
} }
return glyph_length; return glyph_length;
@ -508,6 +502,8 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font)
font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt; font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt;
font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt; font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt;
font->subpx = font_header.subpixels_mode; font->subpx = font_header.subpixels_mode;
font->underline_position = font_header.underline_position;
font->underline_thickness = font_header.underline_thickness;
font_dsc->bpp = font_header.bits_per_pixel; font_dsc->bpp = font_header.bits_per_pixel;
font_dsc->kern_scale = font_header.kerning_scale; font_dsc->kern_scale = font_header.kerning_scale;
@ -535,8 +531,8 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font)
bool failed = false; bool failed = false;
uint32_t * glyph_offset = lv_mem_alloc(sizeof(uint32_t) * (loca_count + 1)); uint32_t * glyph_offset = lv_mem_alloc(sizeof(uint32_t) * (loca_count + 1));
for(unsigned int i = 0; i < loca_count; ++i) { if(font_header.index_to_loc_format == 0) {
if(font_header.index_to_loc_format == 0) { for(unsigned int i = 0; i < loca_count; ++i) {
uint16_t offset; uint16_t offset;
if(lv_fs_read(fp, &offset, sizeof(uint16_t), NULL) != LV_FS_RES_OK) { if(lv_fs_read(fp, &offset, sizeof(uint16_t), NULL) != LV_FS_RES_OK) {
failed = true; failed = true;
@ -544,20 +540,16 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font)
} }
glyph_offset[i] = offset; glyph_offset[i] = offset;
} }
else if(font_header.index_to_loc_format == 1) { }
uint32_t offset; else if(font_header.index_to_loc_format == 1) {
if(lv_fs_read(fp, &offset, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { if(lv_fs_read(fp, glyph_offset, loca_count * sizeof(uint32_t), NULL) != LV_FS_RES_OK) {
failed = true;
break;
}
glyph_offset[i] = offset;
}
else {
LV_LOG_WARN("Unknown index_to_loc_format: %d.", font_header.index_to_loc_format);
failed = true; failed = true;
break;
} }
} }
else {
LV_LOG_WARN("Unknown index_to_loc_format: %d.", font_header.index_to_loc_format);
failed = true;
}
if(failed) { if(failed) {
lv_mem_free(glyph_offset); lv_mem_free(glyph_offset);

View File

@ -85,11 +85,11 @@ extern "C" {
/*------------------------------- /*-------------------------------
* Symbols from "normal" font * Symbols from "normal" font
*-----------------------------*/ *-----------------------------*/
#define LV_SYMBOL_BULLET "\xE2\x80\xA2" /*20042, 0x2022*/ #define LV_SYMBOL_BULLET "\xE2\x80\xA2" /*20042, 0x2022*/
/* /*
* The following list is generated using * The following list is generated using
* cat src/lv_misc/lv_symbol_def.h | sed -E -n 's/^#define\s+(LV_SYMBOL_\w+).*"$/ _LV_STR_\1,/p' * cat src/lv_font/lv_symbol_def.h | sed -E -n 's/^#define\s+LV_(SYMBOL_\w+).*".*$/ _LV_STR_\1,/p'
*/ */
enum { enum {
_LV_STR_SYMBOL_AUDIO, _LV_STR_SYMBOL_AUDIO,
@ -150,6 +150,7 @@ enum {
_LV_STR_SYMBOL_SD_CARD, _LV_STR_SYMBOL_SD_CARD,
_LV_STR_SYMBOL_NEW_LINE, _LV_STR_SYMBOL_NEW_LINE,
_LV_STR_SYMBOL_DUMMY, _LV_STR_SYMBOL_DUMMY,
_LV_STR_SYMBOL_BULLET,
}; };
#ifdef __cplusplus #ifdef __cplusplus