From e78fa9a7d12c3dafcafd46c01a4a1e2e3c7af4c5 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 27 Apr 2020 12:57:26 +0200 Subject: [PATCH] optimize font decompression writer --- src/lv_draw/lv_draw_label.c | 75 +++++++++++++++------------- src/lv_draw/lv_draw_label.h | 9 ++++ src/lv_font/lv_font.h | 28 +++++++++++ src/lv_font/lv_font_fmt_txt.c | 92 ++++++++++------------------------- 4 files changed, 104 insertions(+), 100 deletions(-) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 53d9975d2..13b15dd58 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -45,32 +45,39 @@ static uint8_t hex_char_to_num(char hex); /********************** * STATIC VARIABLES **********************/ -/*clang-format off*/ -static const uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/ -static const uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/ -static const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/ - 68, 85, 102, 119, - 136, 153, 170, 187, - 204, 221, 238, 255 - }; -static const uint8_t bpp8_opa_table[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 - }; -/*clang-format on*/ + +/********************** + * GLOBAL VARIABLES + **********************/ + +const uint8_t _lv_bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/ +const uint8_t _lv_bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/ + +const uint8_t _lv_bpp3_opa_table[8] = {0, 36, 73, 109, /*Opacity mapping with bpp = 3*/ + 146, 182, 219, 255}; + +const uint8_t _lv_bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/ + 68, 85, 102, 119, + 136, 153, 170, 187, + 204, 221, 238, 255 +}; +const uint8_t _lv_bpp8_opa_table[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 +}; /********************** * MACROS @@ -448,22 +455,22 @@ static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph switch(bpp) { case 1: - bpp_opa_table_p = bpp1_opa_table; + bpp_opa_table_p = _lv_bpp1_opa_table; bitmask_init = 0x80; shades = 2; break; case 2: - bpp_opa_table_p = bpp2_opa_table; + bpp_opa_table_p = _lv_bpp2_opa_table; bitmask_init = 0xC0; shades = 4; break; case 4: - bpp_opa_table_p = bpp4_opa_table; + bpp_opa_table_p = _lv_bpp4_opa_table; bitmask_init = 0xF0; shades = 16; break; case 8: - bpp_opa_table_p = bpp8_opa_table; + bpp_opa_table_p = _lv_bpp8_opa_table; bitmask_init = 0xFF; shades = 256; break; /*No opa table, pixel value will be used directly*/ @@ -601,19 +608,19 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_ switch(bpp) { case 1: - bpp_opa_table = bpp1_opa_table; + bpp_opa_table = _lv_bpp1_opa_table; bitmask_init = 0x80; break; case 2: - bpp_opa_table = bpp2_opa_table; + bpp_opa_table = _lv_bpp2_opa_table; bitmask_init = 0xC0; break; case 4: - bpp_opa_table = bpp4_opa_table; + bpp_opa_table = _lv_bpp4_opa_table; bitmask_init = 0xF0; break; case 8: - bpp_opa_table = bpp8_opa_table; + bpp_opa_table = _lv_bpp8_opa_table; bitmask_init = 0xFF; break; /*No opa table, pixel value will be used directly*/ default: diff --git a/src/lv_draw/lv_draw_label.h b/src/lv_draw/lv_draw_label.h index 9e5df892c..93186fcc5 100644 --- a/src/lv_draw/lv_draw_label.h +++ b/src/lv_draw/lv_draw_label.h @@ -76,6 +76,15 @@ void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc); void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_label_dsc_t * dsc, const char * txt, lv_draw_label_hint_t * hint); +/*********************** + * GLOBAL VARIABLES + ***********************/ +extern const uint8_t _lv_bpp2_opa_table[]; +extern const uint8_t _lv_bpp3_opa_table[]; +extern const uint8_t _lv_bpp1_opa_table[]; +extern const uint8_t _lv_bpp4_opa_table[]; +extern const uint8_t _lv_bpp8_opa_table[]; + /********************** * MACROS **********************/ diff --git a/src/lv_font/lv_font.h b/src/lv_font/lv_font.h index 04d2572c6..27b4a6165 100644 --- a/src/lv_font/lv_font.h +++ b/src/lv_font/lv_font.h @@ -171,6 +171,34 @@ LV_FONT_DECLARE(lv_font_montserrat_30) LV_FONT_DECLARE(lv_font_montserrat_32) #endif +#if LV_FONT_MONTSERRAT_36 +LV_FONT_DECLARE(lv_font_montserrat_36) +#endif + +#if LV_FONT_MONTSERRAT_38 +LV_FONT_DECLARE(lv_font_montserrat_38) +#endif + +#if LV_FONT_MONTSERRAT_40 +LV_FONT_DECLARE(lv_font_montserrat_40) +#endif + +#if LV_FONT_MONTSERRAT_42 +LV_FONT_DECLARE(lv_font_montserrat_42) +#endif + +#if LV_FONT_MONTSERRAT_44 +LV_FONT_DECLARE(lv_font_montserrat_44) +#endif + +#if LV_FONT_MONTSERRAT_46 +LV_FONT_DECLARE(lv_font_montserrat_46) +#endif + +#if LV_FONT_MONTSERRAT_48 +LV_FONT_DECLARE(lv_font_montserrat_48) +#endif + #if LV_FONT_MONTSERRAT_28_COMPRESSED LV_FONT_DECLARE(lv_font_montserrat_28_compressed) #endif diff --git a/src/lv_font/lv_font_fmt_txt.c b/src/lv_font/lv_font_fmt_txt.c index 6c025b351..2066493fd 100644 --- a/src/lv_font/lv_font_fmt_txt.c +++ b/src/lv_font/lv_font_fmt_txt.c @@ -40,7 +40,6 @@ static int32_t kern_pair_16_compare(const void * ref, const void * element); static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp); static inline void decompress_line(uint8_t * out, lv_coord_t w); static inline uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len); -static inline void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len); static inline void rle_init(const uint8_t * in, uint8_t bpp); static inline uint8_t rle_next(void); @@ -94,17 +93,8 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic uint32_t gsize = gdsc->box_w * gdsc->box_h; if(gsize == 0) return NULL; - uint32_t buf_size = gsize; - /*Compute memory size needed to hold decompressed glyph, rounding up*/ - switch(fdsc->bpp) { - case 1: buf_size = (gsize + 7) >> 3; break; - case 2: buf_size = (gsize + 3) >> 2; break; - case 3: buf_size = (gsize + 1) >> 1; break; - case 4: buf_size = (gsize + 1) >> 1; break; - } - - if(lv_mem_get_size(buf) < buf_size) { - buf = lv_mem_realloc(buf, buf_size); + if(lv_mem_get_size(buf) < gsize) { + buf = lv_mem_realloc(buf, gsize); LV_ASSERT_MEM(buf); if(buf == NULL) return NULL; } @@ -161,7 +151,7 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out->box_w = gdsc->box_w; dsc_out->ofs_x = gdsc->ofs_x; dsc_out->ofs_y = gdsc->ofs_y; - dsc_out->bpp = (uint8_t)fdsc->bpp; + dsc_out->bpp = fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN ? (uint8_t)fdsc->bpp : 8; if(is_tab) dsc_out->box_w = dsc_out->box_w * 2; @@ -323,6 +313,25 @@ static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord rle_init(in, bpp); + const uint8_t * bpp_opa_table; + switch(bpp) { + case 1: + bpp_opa_table = _lv_bpp1_opa_table; + break; + case 2: + bpp_opa_table = _lv_bpp2_opa_table; + break; + case 3: + bpp_opa_table = _lv_bpp3_opa_table; + break; + case 4: + bpp_opa_table = _lv_bpp4_opa_table; + break; + case 8: + bpp_opa_table = _lv_bpp8_opa_table; + break; + } + uint8_t * line_buf1 = lv_mem_buf_get(w); uint8_t * line_buf2 = lv_mem_buf_get(w); @@ -332,8 +341,8 @@ static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord lv_coord_t x; for(x = 0; x < w; x++) { - bits_write(out, wrp, line_buf1[x], bpp); - wrp += wr_size; + *out = bpp_opa_table[line_buf1[x]]; + out++; } for(y = 1; y < h; y++) { @@ -341,8 +350,8 @@ static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord for(x = 0; x < w; x++) { line_buf1[x] = line_buf2[x] ^ line_buf1[x]; - bits_write(out, wrp, line_buf1[x], bpp); - wrp += wr_size; + *out = bpp_opa_table[line_buf1[x]]; + out++; } } @@ -405,55 +414,6 @@ static inline uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len } } -/** - * Write `val` data to `bit_pos` position of `out`. The write can NOT cross byte boundary. - * @param out buffer where to write - * @param bit_pos bit index to write - * @param val value to write - * @param len length of bits to write from `val`. (Counted from the LSB). - * @note `len == 3` will be converted to `len = 4` and `val` will be upscaled too - */ -static inline void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len) -{ - if(len == 3) { - len = 4; - switch(val) { - case 0: - val = 0; - break; - case 1: - val = 2; - break; - case 2: - val = 4; - break; - case 3: - val = 6; - break; - case 4: - val = 9; - break; - case 5: - val = 11; - break; - case 6: - val = 13; - break; - case 7: - val = 15; - break; - } - } - - uint16_t byte_pos = bit_pos >> 3; - bit_pos = bit_pos & 0x7; - bit_pos = 8 - bit_pos - len; - - uint8_t bit_mask = (uint16_t)((uint16_t) 1 << len) - 1; - out[byte_pos] &= ((~bit_mask) << bit_pos); - out[byte_pos] |= (val << bit_pos); -} - static inline void rle_init(const uint8_t * in, uint8_t bpp) { rle_in = in;