From 8643aa627320e072043ab3ec7c5229bd06d85892 Mon Sep 17 00:00:00 2001 From: Arthur Bonnaudet Date: Tue, 5 Sep 2023 15:19:39 +0200 Subject: [PATCH] Fat: Extend compression to smaller images Work on glyphs generation script. Smaller images were excluded from compression (because compression is incompatible with geometry transformation, and smaller images are the only ones being transformed). This commit adds the possibility to exclude an image from compression by suffixing it with "_nocomp". This allow to compress images that were not compressed before. --- ...mp => quarter_circle_16px_1bpp_nocomp.bmp} | Bin ...mp => quarter_circle_20px_1bpp_nocomp.bmp} | Bin ...mp => quarter_circle_24px_1bpp_nocomp.bmp} | Bin ...mp => quarter_circle_32px_1bpp_nocomp.bmp} | Bin ...mp => quarter_circle_40px_1bpp_nocomp.bmp} | Bin ...mp => quarter_circle_48px_1bpp_nocomp.bmp} | Bin ...bmp => quarter_circle_8px_1bpp_nocomp.bmp} | Bin ...bmp => quarter_round_16px_1bpp_nocomp.bmp} | Bin ...bmp => quarter_round_20px_1bpp_nocomp.bmp} | Bin ...bmp => quarter_round_24px_1bpp_nocomp.bmp} | Bin ...bmp => quarter_round_32px_1bpp_nocomp.bmp} | Bin ...bmp => quarter_round_40px_1bpp_nocomp.bmp} | Bin ...bmp => quarter_round_48px_1bpp_nocomp.bmp} | Bin ....bmp => quarter_round_8px_1bpp_nocomp.bmp} | Bin ...itch_60_40.bmp => switch_60_40_nocomp.bmp} | Bin lib_nbgl/include/nbgl_draw.h | 2 ++ lib_nbgl/src/nbgl_draw.c | 18 ++++++++++++ lib_nbgl/src/nbgl_obj.c | 17 +++++------ lib_nbgl/src/nbgl_obj_keyboard.c | 11 ++++--- lib_nbgl/src/nbgl_obj_keypad.c | 12 +++++++- lib_nbgl/tools/icon2glyph.py | 27 ++++++++++++------ 21 files changed, 62 insertions(+), 25 deletions(-) rename lib_nbgl/glyphs/{quarter_circle_16px_1bpp.bmp => quarter_circle_16px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_circle_20px_1bpp.bmp => quarter_circle_20px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_circle_24px_1bpp.bmp => quarter_circle_24px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_circle_32px_1bpp.bmp => quarter_circle_32px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_circle_40px_1bpp.bmp => quarter_circle_40px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_circle_48px_1bpp.bmp => quarter_circle_48px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_circle_8px_1bpp.bmp => quarter_circle_8px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_round_16px_1bpp.bmp => quarter_round_16px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_round_20px_1bpp.bmp => quarter_round_20px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_round_24px_1bpp.bmp => quarter_round_24px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_round_32px_1bpp.bmp => quarter_round_32px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_round_40px_1bpp.bmp => quarter_round_40px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_round_48px_1bpp.bmp => quarter_round_48px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{quarter_round_8px_1bpp.bmp => quarter_round_8px_1bpp_nocomp.bmp} (100%) rename lib_nbgl/glyphs/{switch_60_40.bmp => switch_60_40_nocomp.bmp} (100%) diff --git a/lib_nbgl/glyphs/quarter_circle_16px_1bpp.bmp b/lib_nbgl/glyphs/quarter_circle_16px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_circle_16px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_circle_16px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_circle_20px_1bpp.bmp b/lib_nbgl/glyphs/quarter_circle_20px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_circle_20px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_circle_20px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_circle_24px_1bpp.bmp b/lib_nbgl/glyphs/quarter_circle_24px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_circle_24px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_circle_24px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_circle_32px_1bpp.bmp b/lib_nbgl/glyphs/quarter_circle_32px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_circle_32px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_circle_32px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_circle_40px_1bpp.bmp b/lib_nbgl/glyphs/quarter_circle_40px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_circle_40px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_circle_40px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_circle_48px_1bpp.bmp b/lib_nbgl/glyphs/quarter_circle_48px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_circle_48px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_circle_48px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_circle_8px_1bpp.bmp b/lib_nbgl/glyphs/quarter_circle_8px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_circle_8px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_circle_8px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_round_16px_1bpp.bmp b/lib_nbgl/glyphs/quarter_round_16px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_round_16px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_round_16px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_round_20px_1bpp.bmp b/lib_nbgl/glyphs/quarter_round_20px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_round_20px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_round_20px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_round_24px_1bpp.bmp b/lib_nbgl/glyphs/quarter_round_24px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_round_24px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_round_24px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_round_32px_1bpp.bmp b/lib_nbgl/glyphs/quarter_round_32px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_round_32px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_round_32px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_round_40px_1bpp.bmp b/lib_nbgl/glyphs/quarter_round_40px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_round_40px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_round_40px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_round_48px_1bpp.bmp b/lib_nbgl/glyphs/quarter_round_48px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_round_48px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_round_48px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/quarter_round_8px_1bpp.bmp b/lib_nbgl/glyphs/quarter_round_8px_1bpp_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/quarter_round_8px_1bpp.bmp rename to lib_nbgl/glyphs/quarter_round_8px_1bpp_nocomp.bmp diff --git a/lib_nbgl/glyphs/switch_60_40.bmp b/lib_nbgl/glyphs/switch_60_40_nocomp.bmp similarity index 100% rename from lib_nbgl/glyphs/switch_60_40.bmp rename to lib_nbgl/glyphs/switch_60_40_nocomp.bmp diff --git a/lib_nbgl/include/nbgl_draw.h b/lib_nbgl/include/nbgl_draw.h index 0567dad8b..c74d34aa1 100644 --- a/lib_nbgl/include/nbgl_draw.h +++ b/lib_nbgl/include/nbgl_draw.h @@ -31,6 +31,8 @@ extern "C" { /********************** * GLOBAL PROTOTYPES **********************/ + +void nbgl_drawIcon(nbgl_area_t *area, nbgl_color_map_t color_map, const nbgl_icon_details_t *icon); void nbgl_drawRoundedRect(const nbgl_area_t *area, nbgl_radius_t radius, color_t innerColor); void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area, nbgl_radius_t radius, uint8_t stroke, color_t innerColor, color_t borderColor); void nbgl_drawText(const nbgl_area_t *area, const char* text, uint16_t textLen, nbgl_font_id_e fontId, color_t fontColor); diff --git a/lib_nbgl/src/nbgl_draw.c b/lib_nbgl/src/nbgl_draw.c index ee2ca7741..4b8891b43 100644 --- a/lib_nbgl/src/nbgl_draw.c +++ b/lib_nbgl/src/nbgl_draw.c @@ -363,6 +363,24 @@ void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area, nbgl_radius_t radiusI } } +/** + * @brief Helper function to render an icon directly from its `nbgl_icon_details_t` structure. + * + * The icon is rendered whether it's an image file or not. + * No transformation is applied to the icon. + * + * @param area Area of drawing + * @param color_map Color map applied to icon + * @param icon Icon details structure to draw + */ +void nbgl_drawIcon(nbgl_area_t *area, nbgl_color_map_t color_map, const nbgl_icon_details_t *icon) { + if (icon->isFile) { + nbgl_frontDrawImageFile(area, icon->bitmap, color_map, ramBuffer); + } else { + nbgl_frontDrawImage(area, icon->bitmap, NO_TRANSFORMATION, color_map); + } +} + /** * @brief Return the size of the bitmap associated to the input font and character * diff --git a/lib_nbgl/src/nbgl_obj.c b/lib_nbgl/src/nbgl_obj.c index f4eb18e16..b25218d74 100644 --- a/lib_nbgl/src/nbgl_obj.c +++ b/lib_nbgl/src/nbgl_obj.c @@ -332,8 +332,9 @@ static void draw_button(nbgl_button_t* obj, nbgl_obj_t *prevObj, bool computePos rectArea.y0 = iconY0; rectArea.width = obj->icon->width; rectArea.height = obj->icon->height; - rectArea.bpp = NBGL_BPP_1; - nbgl_frontDrawImage(&rectArea,(uint8_t*)obj->icon->bitmap,NO_TRANSFORMATION, obj->foregroundColor); + rectArea.bpp = obj->icon->bpp; + + nbgl_drawIcon(&rectArea, obj->foregroundColor, obj->icon); } } @@ -428,12 +429,8 @@ static void draw_image(nbgl_image_t* obj, nbgl_obj_t *prevObj, bool computePosit else { colorMap = obj->foregroundColor; } - if (!iconDetails->isFile) { - nbgl_frontDrawImage((nbgl_area_t*)obj, (uint8_t*)iconDetails->bitmap, NO_TRANSFORMATION, colorMap); - } - else { - nbgl_frontDrawImageFile((nbgl_area_t*)obj, (uint8_t*)iconDetails->bitmap, colorMap, ramBuffer); - } + + nbgl_drawIcon((nbgl_area_t *) obj, colorMap, iconDetails); } static void draw_switch(nbgl_switch_t* obj, nbgl_obj_t *prevObj, bool computePosition) { @@ -492,10 +489,10 @@ static void draw_radioButton(nbgl_radio_t* obj, nbgl_obj_t *prevObj, bool comput rectArea.backgroundColor = obj->obj.area.backgroundColor; rectArea.bpp = NBGL_BPP_1; if (obj->state == OFF_STATE) { - nbgl_frontDrawImage(&rectArea,(uint8_t*)C_radio_inactive_32px.bitmap,NO_TRANSFORMATION,obj->borderColor); + nbgl_drawIcon(&rectArea, obj->borderColor, &C_radio_inactive_32px); } else { - nbgl_frontDrawImage(&rectArea,(uint8_t*)C_radio_active_32px.bitmap,NO_TRANSFORMATION,obj->activeColor); + nbgl_drawIcon(&rectArea, obj->activeColor, &C_radio_active_32px); } } diff --git a/lib_nbgl/src/nbgl_obj_keyboard.c b/lib_nbgl/src/nbgl_obj_keyboard.c index 5a242b851..3202b6558 100644 --- a/lib_nbgl/src/nbgl_obj_keyboard.c +++ b/lib_nbgl/src/nbgl_obj_keyboard.c @@ -328,10 +328,9 @@ static void keyboardDrawLetters(nbgl_keyboard_t *keyboard) { rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT*2 + (KEYBOARD_KEY_HEIGHT-rectArea.height)/2) & 0xFFC; rectArea.x0 = (SHIFT_KEY_WIDTH-rectArea.width)/2; rectArea.backgroundColor = (keyboard->casing != LOWER_CASE)?BLACK:WHITE; - nbgl_frontDrawImage(&rectArea, - (keyboard->casing == LOCKED_UPPER_CASE)?(uint8_t*)C_shift_lock32px.bitmap:(uint8_t*)C_shift32px.bitmap, - NO_TRANSFORMATION, - (keyboard->casing != LOWER_CASE)?WHITE:BLACK); + nbgl_drawIcon(&rectArea, + (keyboard->casing != LOWER_CASE)?WHITE:BLACK, + (keyboard->casing != LOCKED_UPPER_CASE)?(&C_shift_lock32px):(&C_shift32px)); rectArea.backgroundColor = WHITE; offsetX = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH; } @@ -358,7 +357,7 @@ static void keyboardDrawLetters(nbgl_keyboard_t *keyboard) { else { rectArea.x0 += (BACKSPACE_KEY_WIDTH_LETTERS_ONLY-rectArea.width)/2; } - nbgl_frontDrawImage(&rectArea,(uint8_t*)C_backspace32px.bitmap,NO_TRANSFORMATION,BLACK); + nbgl_drawIcon(&rectArea, BLACK, &C_backspace32px); // 4th row, only in Full mode if (!keyboard->lettersOnly) { @@ -367,7 +366,7 @@ static void keyboardDrawLetters(nbgl_keyboard_t *keyboard) { nbgl_drawText(&rectArea, ".?123", 5, BAGL_FONT_INTER_REGULAR_24px_1bpp, BLACK); rectArea.x0 = SWITCH_KEY_WIDTH+(SPACE_KEY_WIDTH-C_space32px.width)/2; - nbgl_frontDrawImage(&rectArea,(uint8_t*)C_space32px.bitmap, NO_TRANSFORMATION, (keyboard->keyMask&(1<keyMask&(1<digitIndexes[_digit>>1]>>4):(_keypad->digitIndexes[_digit>>1]&0xF)) #define SET_DIGIT_INDEX(_keypad, _digit, _index) (_keypad->digitIndexes[_digit>>1] |= (_digit&1)?(_index<<4):_index) +extern uint8_t ramBuffer[GZLIB_UNCOMPRESSED_CHUNK]; + /********************** * TYPEDEFS **********************/ @@ -163,7 +165,11 @@ static void keypadDrawDigits(nbgl_keypad_t *keypad) { rectArea.bpp = NBGL_BPP_1; rectArea.x0 = keypad->obj.area.x0 + (KEY_WIDTH-rectArea.width)/2; rectArea.y0 = keypad->obj.area.y0 + KEYPAD_KEY_HEIGHT*3 + (KEYPAD_KEY_HEIGHT-rectArea.height)/2; - nbgl_frontDrawImage(&rectArea,(uint8_t*)C_backspace32px.bitmap,NO_TRANSFORMATION, keypad->enableBackspace?BLACK:WHITE); + #if GLYPH_backspace32px_ISFILE + nbgl_frontDrawImageFile(&rectArea,(uint8_t*)C_backspace32px.bitmap, keypad->enableBackspace?BLACK:WHITE, ramBuffer); + #else + nbgl_frontDrawImage(&rectArea,(uint8_t*)C_backspace32px.bitmap, NO_TRANSFORMATION, keypad->enableBackspace?BLACK:WHITE); + #endif // draw 0 key_value = GET_DIGIT_INDEX(keypad,0)+0x30; @@ -197,7 +203,11 @@ static void keypadDrawDigits(nbgl_keypad_t *keypad) { rectArea.bpp = NBGL_BPP_1; rectArea.x0 = keypad->obj.area.x0 + 2*KEY_WIDTH + (KEY_WIDTH-rectArea.width)/2; rectArea.y0 = keypad->obj.area.y0 + KEYPAD_KEY_HEIGHT*3 + (KEYPAD_KEY_HEIGHT-rectArea.height)/2; +#if GLYPH_check32px_ISFILE + nbgl_frontDrawImageFile(&rectArea,(uint8_t*)C_check32px.bitmap, WHITE, ramBuffer); +#else nbgl_frontDrawImage(&rectArea,(uint8_t*)C_check32px.bitmap,NO_TRANSFORMATION, WHITE); +#endif } } diff --git a/lib_nbgl/tools/icon2glyph.py b/lib_nbgl/tools/icon2glyph.py index d15601ca7..60f2d5084 100755 --- a/lib_nbgl/tools/icon2glyph.py +++ b/lib_nbgl/tools/icon2glyph.py @@ -211,23 +211,22 @@ def compute_app_icon_data(im: Image, bpp) -> Tuple[bool, bytes]: return is_file, image_data -def compute_regular_icon_data(im: Image, bpp) -> Tuple[bool, bytes]: +def compute_regular_icon_data(no_comp: bool, im: Image, bpp) -> Tuple[bool, bytes]: """ Process image as regular icon: - Regular icon are image file only if compressed - Compression is limited to images bigger than 64x64 """ width, height = im.size - # We do not compress regular icon smaller than 64x64 because - # these smaller images are the one being transformed through - # symmetry. And the symmetry is not implemented for compressed - # icons (yet). - if (width >= 64) and (height >= 64): + + if not no_comp: compression, image_data = compress(im, bpp) if compression != NbglFileCompression.NoCompression: is_file = True image_data = convert_to_image_file( image_data, width, height, bpp, compression) + else: + is_file = False else: is_file = False image_data = image_to_packed_buffer(im, bpp) @@ -284,7 +283,11 @@ def print_glyphcheader_data(image_name, bpp, width, height, is_file, image_data) def main(): parser = argparse.ArgumentParser( description='Generate source code for NBGL icons.') - parser.add_argument('image_file', help="Icons to process", nargs='+') + parser.add_argument('image_file', help=""" + Icons to process. + Images that will be transformed through rotation or symmetry + must be suffixed by '_nocomp' (example: image_nocomp.png) + """, nargs='+') parser.add_argument('--hexbitmaponly', action='store_true') parser.add_argument('--glyphcheader', action='store_true') parser.add_argument('--glyphcfile', action='store_true') @@ -319,7 +322,15 @@ def main(): else: # Prepare and print regular icon data width, height = im.size - is_file, image_data = compute_regular_icon_data(im, bpp) + + # Forbid compression if the image name ends with nocomp. + if image_name.endswith('_nocomp'): + no_comp = True + image_name = image_name[:-7] # Remove nocomp suffix + else: + no_comp = False + + is_file, image_data = compute_regular_icon_data(no_comp, im, bpp) if args.glyphcfile: print_glyphcfile_data(image_name, bpp, image_data)