diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 010528494..0edaded54 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -26,6 +26,7 @@ jobs: cmake -Bbuild -H. && make -C build && make -C build test cd ../lib_nbgl/ cmake -Bbuild -H. && make -C build && CTEST_OUTPUT_ON_FAILURE=1 make -C build test + STAX=1 cmake -Bbuild -H. && make -C build && CTEST_OUTPUT_ON_FAILURE=1 make -C build test - name: Generate code coverage run: | diff --git a/Makefile.defines b/Makefile.defines index 1400a4e1b..3fa78fcf1 100644 --- a/Makefile.defines +++ b/Makefile.defines @@ -30,6 +30,11 @@ ifeq ($(filter $(TARGET),$(TARGETS)),) $(error TARGET not set to a valid value (possible values: $(TARGETS))) endif +# for Stax, NBGL must be used +ifeq ($(TARGET),stax) +USE_NBGL ?= 1 +endif + API_LEVEL := 0 TARGET_PATH := $(BOLOS_SDK)/target/$(TARGET) TARGET_ID := $(shell cat $(TARGET_PATH)/include/bolos_target.h | grep TARGET_ID | cut -f3 -d' ') @@ -55,8 +60,13 @@ endif # Command to print ICONNAME hexadecimal bitmap on stdout # according to the hardware target. -ifeq ($(TARGET_NAME),TARGET_STAX) +ifneq ($(TARGET),nanos) +#inverse B&W for non Stax +ifneq ($(TARGET_NAME),TARGET_STAX) +ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --reverse --hexbitmaponly $(ICONNAME) +else ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --hexbitmaponly $(ICONNAME) +endif else ICONHEX_CMD=python3 $(BOLOS_SDK)/icon3.py --hexbitmaponly $(ICONNAME) endif @@ -187,13 +197,21 @@ DEFINES += NBGL_PAGE DEFINES += NBGL_USE_CASE #DEFINES += HAVE_DISPLAY_FAST_MODE else -DEFINES += HAVE_BAGL DEFINES += BAGL_WIDTH=128 +ifdef USE_NBGL +DEFINES += HAVE_NBGL +DEFINES += NBGL_STEP +DEFINES += NBGL_USE_CASE +else +DEFINES += HAVE_BAGL +endif ifeq ($(TARGET_NAME),TARGET_NANOS) DEFINES += BAGL_HEIGHT=32 endif ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2)) +ifndef USE_NBGL DEFINES += HAVE_UX_FLOW +endif DEFINES += BAGL_HEIGHT=64 DEFINES += HAVE_BAGL_ELLIPSIS DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX diff --git a/Makefile.glyphs b/Makefile.glyphs index cf19b7dcf..bb14c13f9 100644 --- a/Makefile.glyphs +++ b/Makefile.glyphs @@ -31,8 +31,8 @@ endif GLYPH_DESTC := $(GLYPH_SRC_DIR)/glyphs.c GLYPH_DESTH := $(GLYPH_SRC_DIR)/glyphs.h -ifeq ($(TARGET_NAME),TARGET_STAX) -# Stax glyphs files and generation script +ifdef USE_NBGL +# Not NanoS glyphs files and generation script GLYPH_FILES += $(addprefix $(BOLOS_SDK)/lib_nbgl/glyphs/,$(sort $(notdir $(shell find $(BOLOS_SDK)/lib_nbgl/glyphs/)))) GLYPH_FILES += $(addprefix glyphs/,$(sort $(notdir $(shell find glyphs/)))) ifneq (,$(wildcard $(ICONNAME))) @@ -40,11 +40,18 @@ ifneq (,$(wildcard $(ICONNAME))) GLYPH_FILES += $(ICONNAME) endif ICON_SCRIPT = $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py -GENERATE_GLYPHS_CMD = python3 $(ICON_SCRIPT) --glyphcfile $(GLYPH_FILES) +#inverse B&W for non Stax +ifneq ($(TARGET_NAME),TARGET_STAX) +GLYPH_OPT := --reverse +else +GLYPH_OPT := +endif +GENERATE_GLYPHS_CMD = python3 $(ICON_SCRIPT) $(GLYPH_OPT) --glyphcfile $(GLYPH_FILES) else # Nano glyphs files and generation script GLYPH_FILES += $(addprefix glyphs/,$(sort $(notdir $(shell find glyphs/)))) GLYPH_FILES += $(addprefix $(BOLOS_SDK)/lib_ux/glyphs/,$(sort $(notdir $(shell find $(BOLOS_SDK)/lib_ux/glyphs/)))) +GLYPH_OPT := ICON_SCRIPT = $(BOLOS_SDK)/icon3.py GENERATE_GLYPHS_CMD = python3 $(ICON_SCRIPT) --factorize --glyphcfile $(GLYPH_FILES) endif @@ -54,7 +61,7 @@ $(GLYPH_DESTH): $(GLYPH_FILES) $(ICON_SCRIPT) $(L)-mkdir -p $(GLYPH_SRC_DIR) $(L)rm -f $(GLYPH_DESTC) $(GLYPH_DESTH) @# Use temporary files to prevent issues when build is interrupted - $(L)python3 $(ICON_SCRIPT) --glyphcheader $(GLYPH_FILES) > $(GLYPH_DESTH)_tmp + $(L)python3 $(ICON_SCRIPT) $(GLYPH_OPT) --glyphcheader $(GLYPH_FILES) > $(GLYPH_DESTH)_tmp $(L)$(GENERATE_GLYPHS_CMD) > $(GLYPH_DESTC)_tmp $(L)mv $(GLYPH_DESTC)_tmp $(GLYPH_DESTC) $(L)mv $(GLYPH_DESTH)_tmp $(GLYPH_DESTH) diff --git a/Makefile.rules b/Makefile.rules index ed8f8db51..8769969dc 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -17,9 +17,9 @@ # temporary redef, to ensure wider compliance of the SDK with pre-1.6 apps ifeq ($(DISABLE_UI),0) - ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOS TARGET_NANOX TARGET_NANOS2)) + ifndef USE_NBGL SDK_SOURCE_PATH += lib_bagl lib_ux - else ifeq ($(TARGET_NAME),TARGET_STAX) + else SDK_SOURCE_PATH += lib_nbgl lib_ux_stax endif endif diff --git a/Makefile.rules_generic b/Makefile.rules_generic index b94c82ed5..352b1ed9c 100644 --- a/Makefile.rules_generic +++ b/Makefile.rules_generic @@ -32,7 +32,7 @@ ifeq ($(shell $(CC) -v 2>&1 | grep clang),) $(error Compiler is not CLANG) endif -ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2 TARGET_STAX)) +ifneq ($(TARGET_NAME),TARGET_NANOS) ifeq ($(shell $(LD) -v 2>&1 | grep clang),) LD := $(CC) ifneq ($(shell [ `$(CC) -v 2>&1 | grep -o "version .*" | cut -f2 -d' ' | cut -f1 -d'.'` -ge 7 ] && echo ok),ok) diff --git a/Makefile.standard_app b/Makefile.standard_app index 668585fd5..4199a179a 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -107,7 +107,7 @@ ifneq ($(DISABLE_STANDARD_WEBUSB), 1) endif ifneq ($(DISABLE_STANDARD_BAGL_UX_FLOW), 1) -ifneq ($(TARGET_NAME), TARGET_STAX) +ifndef USE_NBGL DEFINES += HAVE_UX_FLOW endif endif diff --git a/include/cx_trampoline.h b/include/cx_trampoline.h index 998d47b53..715886184 100644 --- a/include/cx_trampoline.h +++ b/include/cx_trampoline.h @@ -7,7 +7,7 @@ #elif defined(TARGET_NANOX) #define CX_TRAMPOLINE_ADDR 0x00210001 #elif defined(TARGET_NANOS2) -#define CX_TRAMPOLINE_ADDR 0x00808001 +#define CX_TRAMPOLINE_ADDR 0x00810001 #elif defined(TARGET_STAX) #define CX_TRAMPOLINE_ADDR 0x00818001 #endif diff --git a/include/os_screen.h b/include/os_screen.h index 18b9c212b..1e57e3dc5 100644 --- a/include/os_screen.h +++ b/include/os_screen.h @@ -4,7 +4,6 @@ #include "decorators.h" #include "os_types.h" -#ifdef HAVE_BAGL #ifdef HAVE_SE_SCREEN // SYSCALL void screen_write_frame(unsigned char* framebuffer PLENGTH(BAGL_WIDTH*BAGL_HEIGHT/8)); /** @@ -54,4 +53,3 @@ SYSCALL void bagl_hal_draw_rect(unsigned int color, unsigned int width, unsigned int height); #endif // HAVE_SE_SCREEN -#endif // HAVE_BAGL diff --git a/lib_nbgl/doc/mainpage.dox b/lib_nbgl/doc/mainpage.dox index 3131b28d6..f9c4f4793 100644 --- a/lib_nbgl/doc/mainpage.dox +++ b/lib_nbgl/doc/mainpage.dox @@ -1,3 +1,4 @@ +#ifdef HAVE_SE_TOUCH /** @page nbgl_mainpage New BOLOS Graphic API @section mainpage_intro Introduction @@ -57,3 +58,4 @@ Applications are free to define \b NBGL_KEYBOARD, \b NBGL_KEYPAD or \b NBGL_QRCO "rare" objects. */ +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/doc/mainpage_nanos.dox b/lib_nbgl/doc/mainpage_nanos.dox new file mode 100644 index 000000000..f2dfa14db --- /dev/null +++ b/lib_nbgl/doc/mainpage_nanos.dox @@ -0,0 +1,65 @@ +#ifndef HAVE_SE_TOUCH +/** @page nbgl_mainpage New BOLOS Graphic API + +@section mainpage_intro Introduction + +This documentation describes the different interfaces of NBGL, the library that +is targeted to be integrated in Stax product. + +NBGL Engine is responsible for constructing screens and handling Touchscreen input. + +@section mainpage_overall_archi Overall architecture + +NBGL Engine is a library to be integrated in SDK. +It is intended to replace existing BAGL/FLOW Graphical Engine (used on Nanos/Blue products) + +\image{inline} html NBGLArchi.png "caption" height=600 + +@section nbgl_drawing_api Screen drawing APIs + +@subsection nbgl_app_use_case_api_1 Application Use-cases API +This is the most preferred API level to write an embedded Application. + +The @subpage nbgl_app_use_case_nanos page contains all information necessary to understand +and use \b NBGL Application Use cases API + +@subsection nbgl_flow_level_api_1 Flow API +The @subpage nbgl_flow page contains all information necessary to understand +and use \b NBGL Flow API, managing a scenario flow, made of one or several steps + +@subsection nbgl_step_level_api_1 Step API +The @subpage nbgl_step page contains all information necessary to understand +and use \b NBGL Step API, managing the page(s) of a scenario step + +@subsection nbgl_mid_level_api_1 Complex objects (layout) API +The @subpage nbgl_layout page contains all information necessary to understand +and use \b NBGL Mid-Level API, using complex objects + +@subsection nbgl_low_level_api_1 Low-Level API +The @subpage nbgl_obj page contains all information necessary to understand +and use \b NBGL Low-Level API + +@section nbgl_screen_objs Screen and objects management +The @subpage nbgl_screens_and_objs page contains all information necessary to understand +how \b NBGL manages the screens stack and the dynamically allocated objects + +@section nbgl_touch_api Touchscreen events management +The @subpage nbgl_touchscreen page contains all information necessary to understand +how \b NBGL manages the touchscreen events and how to receive and process these events. + +@section nbgl_building Compilation options +In order to reduce the footprint (RAM+Flash), some features are only activated if some building options are defined. + +Define | Meaning | Default state +------------- | ------------- | ------------- +\b NBGL_PAGE | Activate High-Level API | Active in SDK, not in OS +\b NBGL_USE_CASE | Activate Use Case API | Active in SDK, not in OS +\b NBGL_KEYBOARD | Activate Keyboard object | Active in OS, not in SDK +\b NBGL_KEYPAD | Activate Keypad object | Active in OS, not in SDK +\b NBGL_QRCODE | Activate QRCode object | Active in OS, not in SDK + +Applications are free to define \b NBGL_KEYBOARD, \b NBGL_KEYPAD or \b NBGL_QRCODE in their own Makefile if they need to use these +"rare" objects. + +*/ +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/doc/nbgl_flow.dox b/lib_nbgl/doc/nbgl_flow.dox new file mode 100644 index 000000000..560f1db23 --- /dev/null +++ b/lib_nbgl/doc/nbgl_flow.dox @@ -0,0 +1,104 @@ +#ifdef NBGL_STEP +/** @page nbgl_flow Flow API + +@section nbgl_flow_intro Introduction +This chapter describes briefly the Flow API of Advanced BOLOS Graphic Library. + +This layer offers a way to handle multi-steps flows in typical scenarios of Nanos OS or Apps, like a transaction, a navigation in a menu. + +A full description of the way to create and interact with a flow can be found in this document + +@section nbgl_flow_concepts Concepts + +This layer uses the step API described in @ref nbgl_step, but for list of steps. The navigation between steps is entirely managed +by the flow engine. + +@subsection nbgl_flow_example Example + +\image{inline} html layout_nanos_flow1.png "caption" height=200 + +In this example, a flow made of 4 steps (each on one page) is built. The navigation is possible between these steps (no loop), and the +last step can be selected (double button press). + +@section nbgl_flow_operations Operations + +@subsection create_flow Draw a flow + +The configuration of a flow is provided in a single function call, through @ref nbgl_flowDraw() which will: + +- draw the first step +- Refresh after first step drawing + +The arguments of @ref nbgl_flowDraw() are: + +- An array of step descriptions (see below) +- The index of the step to start with in step descriptions array +- A boolean indicating whether the flow shall be modal or not +- A boolean indicating whether the flow is circular or not (loop) + +@code +static char string_buffer[128]; + +static void onPrepareOSversion(void); +static void onPrepareMCUversion(void); +static void onPrepareBootloaderversion(void); +static void onBack(void); + +static nbgl_flow_t flowContext; + +static const nbgl_stepDesc_t flowSteps[] = { + { + .text = "\bSecure Element", + .subText = string_buffer, + .init = onPrepareOSversion + }, + { + .text = "\bMicrocontroller", + .subText = string_buffer, + .init = onPrepareMCUversion + }, + { + .text = "\bBootloader", + .subText = string_buffer, + .init = onPrepareBootloaderversion + }, + { + .text = "\bBack", + .callback = onBack, + .icon = &C_icon_back + } +}; + +static void onPrepareOSversion(void) { + os_version((unsigned char*)string_buffer, 32); +} + +static void onPrepareMCUversion(void) { + os_seph_version((unsigned char*)string_buffer, 32); +} + +static void onPrepareBootloaderversion(void) { + os_bootloader_version((unsigned char*)string_buffer, 32); +} + +static void onBack(void) { + nbgl_flowRelease(flowContext); + // go to parent flow +} + +void displayInfo() { + // use string_buffer as temporary buffer + memset(string_buffer, 0, 128); + flowContext = nbgl_flowDraw(flowSteps, 4, 0, false, false); +} + +@endcode + +@subsection page_release Releasing a predefined page + +Before leaving a screen built with a layout, it must be released with a call to @ref nbgl_flowRelease(). It will free the allocated +objects. + + +*/ +#endif // NBGL_STEP diff --git a/lib_nbgl/doc/nbgl_layout.dox b/lib_nbgl/doc/nbgl_layout.dox index eda54fa8f..e422d736a 100644 --- a/lib_nbgl/doc/nbgl_layout.dox +++ b/lib_nbgl/doc/nbgl_layout.dox @@ -1,3 +1,4 @@ +#ifdef HAVE_SE_TOUCH /** @page nbgl_layout Complex objects layout API @section nbgl_layout_intro Introduction @@ -743,3 +744,4 @@ objects. */ +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/doc/nbgl_layout_nanos.dox b/lib_nbgl/doc/nbgl_layout_nanos.dox new file mode 100644 index 000000000..7b8b22c46 --- /dev/null +++ b/lib_nbgl/doc/nbgl_layout_nanos.dox @@ -0,0 +1,309 @@ +#ifndef HAVE_SE_TOUCH +/** @page nbgl_layout Complex objects layout API + +@section nbgl_layout_intro Introduction +This chapter describes briefly the mid level API of Advanced BOLOS Graphic Library. + +This layer offers a simplified view of a screen page, using complex (aggregated) objects, like a centered info or a set of navigation arrows. + +A full description of each functions/types can be found in this document + +@section concepts2 Concepts + +This layer uses the low-level API described in @ref nbgl_obj, but all graphic objects are hidden, in favor to abstract complex objects +like a centered info or a set of navigation arrows. + +Moreover, positions of objects in the page are mostly hidden and automatic. + +@subsection example_1 Example + +\image{inline} html layout_nanos_1.png "caption" height=300 + +In this example, 2 "objects" are used and added to the page with dedicated APIs: + +- A centered information area with an icon and a main text +- A set of navigation arrows, indicating that the user can use left/right buttons to navigated across pages + +@section operations Common operations + +@subsection create_layout Getting a new layout + +The first operation is always to get a new layout, with the desired parameters: + +- An action callback used for all controls of the page +- A boolean indicated whether the page is modal or not (on top of existing ones, or in background plane) +- A potential ticker configuration if a ticker is required for the page + +The function to actually create the layout is @ref nbgl_layoutGet() + +For example: + +@code + nbgl_layoutDescription_t layoutDescription = { + .modal = false, // not modal (so on plane 0) + .onActionCallback = &myActionCallback, // generic callback for all controls + .ticker.callback = NULL // no ticker + }; + // create layout + nbgl_layout_t *layout = nbgl_layoutGet(&layoutDescription); +@endcode + +@subsection draw_layout Drawing a populated layout + +Once defined and populated, all objects can be drawn in **framebuffer** +with a simple call to @ref nbgl_layoutDraw(). + +@section add_objects Populating a layout + +Once the layout is defined and retrieved with @ref nbgl_layoutGet(), the page can be filled with complex objects. + +@subsection centered_info Centered info area + +\image{inline} html layout_nanos_centered.png "caption" height=300 + +This object is made of: + +- An optional icon +- An optional main text under the icon +- An optional sub text under the main text + +The whole object is centered horizontally in the page + +It can be either centered vertically or put on top of the page. + +The API to insert such an object is @ref nbgl_layoutAddCenteredInfo(), using @ref nbgl_layoutCenteredInfo_t structure + +The fonts for the texts depends of the \b style field used in @ref nbgl_layoutCenteredInfo_t. + +- if @ref REGULAR_INFO, main text and sub text are in regular case +- if @ref BOLD_TEXT1_INFO, main text is in bold case (and sub text in regular case) + +@subsection navigation Navigation area + +\image{inline} html layout_nanos_nav1.png "caption" height=300 + +or + +\image{inline} html layout_nanos_nav2.png "caption" height=300 + + +This object is made of: + +- 1 or 2 arrows on left and right of the screen + +The arrows are centered vertically in the page + +There are two styles for the arrows: + +- either @ref HORIZONTAL_NAV for navigation between pages +- or @ref VERTICAL_NAV for navigation between menu items + +The API to insert such an object is @ref nbgl_layoutAddNavigation(), using @ref nbgl_layoutNavigation_t structure + +The "direction" and the number of arrows (left, right or both) to use are set in @ref nbgl_layoutNavigation_t. + +@subsection menu_list Menu List area + +\image{inline} html layout_nanos_menu_list.png "caption" height=300 + +On screen, the visible part of his object is made of up to 5 menu item elements (single line, centered horizontally) + +The first and last of the 5 lines are only partially visible (horizontal cut) + +The API to insert such an object is @ref nbgl_layoutAddMenuList(), using @ref nbgl_layoutMenuList_t structure, +which enables to configure: + +- The total number of items in the list. +- The selected item index in the list (that will be highlighted in bold, and always be centered vertically) +- A callback that will be called to get the text of each displayed menu item + +@subsection keyboard_section Keyboard-related objects + +Some rare screens require displaying a keyboard at the bottom of the page, to enter text. + +The text to enter may be a generic string or a word (for example BIP39). + +Here is an example of these pages in Bolos UX: + +\image{inline} html layout_nanos_keyboard1.png "caption" height=300 + +To build such screens, some dedicated APIs are necessary, which will be detailed in the sub-chapters. + +@subsubsection keyboard_sub_section_1 Adding/Updating keyboard + +This object, in the center of screen (with a margin), proposes a rotating keyboard, displaying 3 letters at max, +(from 'a' to 'z' in letters-only). + +The parameters to configure this object are: + +- The mode in which to start the keyboard (letters, digits or special characters) +- A boolean to indicate whether to display only letters, with no space and no shift key to switch between modes +- A boolean to indicate whether to display a backspace key or not. +- A boolean to indicate whether to display a validate key or not. +- A 32 bits mask used to invalidate (remove) some keys on the keyboard (in letters-only mode). +- A function to be called when an active key is pressed + +The API to insert such an object is @ref nbgl_layoutAddKeyboard(), with @ref nbgl_layoutKbd_t structure as parameter. + +This function returns a positive integer (if successful) to be used as an index in @ref nbgl_layoutUpdateKeyboard() function, +used to modify an existing keyboard. + +@note the 32 bits mask works like this: +- If mask[0] bit is 1, the 'a' key is invalid +- If mask[1] bit is 1, the 'b' key is invalid +- And so on in "abcdefghijklmnopqrstuvwxyz" string. +- If mask[26] bit is 1, the backspace key is not used + +@subsubsection keyboard_sub_section_4 Adding/Updating entered text + +This object, displayed under the keyboard consists in a set of 9 placeholders +representing the text entered with the keyboard. + +If text is too long to be displayed (more than 8 characters), the beginning is replaced by ".." + +The only parameter to configure this object is: + +- The \b text to display + +The API to insert such an object is @ref nbgl_layoutAddEnteredText(). + +This function returns a positive integer (if successful) to be used as an index in @ref nbgl_layoutUpdateEnteredText() function, +used to modify the text. + +@subsubsection keyboard_example Example + +Here is the source code to display the example: + +@code +static nbgl_layout_t *layout; +static char textToEnter[10]; +static char headerText[24]; +static int textIndex, keyboardIndex; + +// function called when a key of keyboard is touched +static void keyboardCallback(char touchedKey) { + +} + +void app_keyboard(void) { + nbgl_layoutDescription_t layoutDescription = { + .modal = false, + .onActionCallback = NULL + }; + nbgl_layoutKbd_t kbdInfo = { + .callback = keyboardCallback, + .keyMask = 1<<26, // no masked letter but masked backspace + .lettersOnly = true // only letters are allowed + }; + nbgl_layoutCenteredInfo_t centeredInfo = { + .text1 = descriptionTxt, + .text2 = NULL, + .icon = NULL, + .onTop = true + }; + nbgl_layoutNavigation_t navInfo = { + .direction = HORIZONTAL_NAV, + .indication = LEFT_ARROW | RIGHT_ARROW + }; + int status; + + // create description text + sprintf(headerText,"Enter word #%d",12); + + // get empty layout + layout = nbgl_layoutGet(&layoutDescription); + // add description + nbgl_layoutAddCenteredInfo(layout, ¢eredInfo); + + // add keyboard + status = nbgl_layoutAddKeyboard(layout, &kbdInfo); + if (status < 0) + return; + keyboardIndex = (uint8_t)status; + // add empty entered text + status = nbgl_layoutAddEnteredText(layout, ""); + if (status < 0) + return; + textIndex = (uint8_t)status; + nbgl_layoutAddNavigation(layout, &navInfo); + nbgl_layoutDraw(layout); + nbgl_refresh(); +} +@endcode + +@subsection keypad_section Keypad-related objects + +Some rare screens require displaying a keypad at the bottom of the page, to enter digits. + +The digits to enter are usually a PIN code, to enter or to confirm. + +Here are some example of these pages in Bolos UX: + +\image{inline} html layout_nanos_keypad1.png "caption" height=300 + +To build such screens, some dedicated APIs are necessary, which will be detailed in the sub-chapters. + +@subsubsection keypad_sub_section_1 Adding/Updating keypad + +This object is made of an area at the bottom of the screen, presenting the 10 digits, a backspace and a validate keys, that can be navigated +with left and right buttons and selected with both buttons. And a title at the top of the screen. + +The only parameters to configure this object (at creation time) are: + +- the callback associated with active keypad key selection. +- a boolean to choose between shuffled (selection starts with any key) and regular mode (selection starts at '5' key). +- a single line string to use as title. + +The API to insert such an object is @ref nbgl_layoutAddKeypad(). + +This function returns a positive integer (if successful) to be used as an index in @ref nbgl_layoutUpdateKeypad() function, +used to modify the active keys of an existing keypad (backspace and validate keys). + +@note at creation time, backspace and validate keys are inactive + +@subsubsection keypad_sub_section_2 Adding/Updating hidden digits area + +This object, displayed on top of the keypad, consists in up to 8 discs (plain or empty) corresponding to +hidden entered/not entered digits. + +The parameters to configure this object are: + +- The number of total digits to be displayed (all digits are considered as "not entered") + +The API to insert such an object is @ref nbgl_layoutAddHiddenDigits(). + +This function returns a positive integer (if successful) to be used as an index in @ref nbgl_layoutUpdateHiddenDigits() function, +used to modify the number of entered digits. + +@section refresh_layout Refreshing screen + +After having drawn graphic objects in **framebuffer**, it is necessary to transfer the content of the **framebuffer** on display. +This operation is called a refresh. + +The API to do that is @ref nbgl_refresh() (in nbgl_obj.h) + +It will only refresh the rectangle part of the screen having changed (with objects redrawn) since the last refresh. + +@section callbacks Control actions management + +Some controls, like a touchable bar, or a choice by radio buttons, can be interacted with thanks to the Touchscreen. + +The developer can subscribe to these events by providing an action callback in @ref nbgl_layoutGet(), with @ref nbgl_layoutTouchCallback_t prototype. + +The first parameter (*token*) of this function is a token provided along with the definition of the complex object. + +The second parameter (*index*) is only used for some types of complex objects: + +- **Navigation bar**: in this case, *index* gives the index of the new active page, when navigating. +- **Radio button choices**: in this case, *index* gives the index of the selected choice. +- **Switches**: in this case, if *index* is 0 it means OFF, otherwise it means ON. +- **Choice buttons**: in this case, if *index* is 0, it means top-button (choice 1), otherwise it means bottom-buttom (choice 2) + +@subsection release Releasing a layout + +Before leaving a screen built with a layout, it must be released with a call to @ref nbgl_layoutRelease(). It will free the potentially allocated +objects. + + +*/ +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/doc/nbgl_page.dox b/lib_nbgl/doc/nbgl_page.dox index 86138a9bc..65be3ad9a 100644 --- a/lib_nbgl/doc/nbgl_page.dox +++ b/lib_nbgl/doc/nbgl_page.dox @@ -1,3 +1,4 @@ +#ifdef NBGL_PAGE /** @page nbgl_page Predefined pages API @section nbgl_page_intro Introduction @@ -245,3 +246,4 @@ objects. */ +#endif // NBGL_PAGE diff --git a/lib_nbgl/doc/nbgl_step.dox b/lib_nbgl/doc/nbgl_step.dox new file mode 100644 index 000000000..4b5838878 --- /dev/null +++ b/lib_nbgl/doc/nbgl_step.dox @@ -0,0 +1,130 @@ +#ifdef NBGL_STEP +/** @page nbgl_step Step API + +@section nbgl_step_intro Introduction +This chapter describes briefly the high-level API of Advanced BOLOS Graphic Library. + +This layer offers a simplified view of a screen page (or multi-pages), using predefined models, like a centered info, or a menu list, managing +the internal navigation between the internal pages of a step. + +A full description of each type of steps can be found in this document + +@section nbgl_step_concepts Concepts + +This layer uses the complex-objects API described in @ref nbgl_layout, but all objects are hidden, in favor to fields to configure, for example +texts, icons and callbacks. + +Moreover, positions of objects in the page are hidden and automatic. + +And finally, if a step requires using multiple pages (for example for a long text to display, or a long menu list), the step engine manages the +navigation between these pages. + +@section nbgl_step_operations Operations + +@subsection create_page Draw a step + +The configuration of a step is provided in a single function call, and all predefined pages APIs will do the following operations: + +- Create the page +- Add required complex objects in the page +- Draw the objects in the **framebuffer** +- Refresh the display with **framebuffer** content + +For every types of steps, the navigation inside the step is managed by the step engine, but even for navigation outside it (between steps of +a flow), the navigation arrows are drawned by the engine. + +A few APIs are available to draw typical pages, like: + +- @ref nbgl_stepDrawText() to draw a text and a sub-text on one or several lines/pages, with navigation +- @ref nbgl_stepDrawCenteredInfo() to draw an icon, a text and a sub-text in a single page, with navigation +- @ref nbgl_stepDrawMenuList() to draw a menu list, with navigation + +@subsection step_typical_types Typical step types + +@subsubsection step_text_type Generic Text Step + +This type is intended to draw one or two centered (vertically and horizontally) text(s) in the screen. + +If there is no sub-text and the main-text doesn't fit in a single page (taking wrapping into account), the text is automatically split +into several pages, and the navigation is set accordingly, and manage automatically between these internal pages. See first example. + +\image{inline} html layout_nanos_step_text1.png "caption" height=200 + +If there is a sub-text, the main-text must fit in a single line. The sub-text can be multi-pages, and in this case the main-text is +considered as title, and an indication is automatically added to this "title" to show the current "page" and number of pages. See +second example. + +\image{inline} html layout_nanos_step_text2.png "caption" height=200 + +The API to insert such an object is @ref nbgl_stepDrawText() with: + +- A callback to handle the actions on buttons (left, right or both) +- A potential ticker configuration. +- A potential main text +- A potential sub-text +- The position of the step in a flow (see @subpage step_positioning) +- A boolean to indicate whether this step is modal or not +- The style to use for text and sub-text (@ref REGULAR_INFO or @ref BOLD_TEXT1_INFO) + +@note left or right buttons actions are only notified with the provided callback if on the first page (for left) or on the +last page (right) for a multi-pages step. + +@subsubsection step_centered_info_type Centered Info Step + +This type is intended to draw a centered info, with an icon, a main text and a sub-text in the screen. The texts are optional. + +\image{inline} html layout_nanos_step_centered.png "caption" height=200 + +The API to insert such an object is @ref nbgl_stepDrawCenteredInfo() with: + +- A callback to handle the actions on buttons (left, right or both) +- A potential ticker configuration +- A mandatory icon +- A potential main text +- A potential sub-text +- The position of the step in a flow (see @subpage step_positioning) +- A boolean to indicate whether this step is modal or not +- The style to use for text and sub-text (@ref REGULAR_INFO or @ref BOLD_TEXT1_INFO) + +@subsubsection step_menu_list_type Menu List Step + +This type is intended to draw a menu list, and manage the navigation between the items of the list + +\image{inline} html layout_nanos_step_menu_list.png "caption" height=200 + +The API to insert such an object is @ref nbgl_stepDrawMenuList() with: + +- A callback to handle the selection (press both buttons) of a menu item +- A potential ticker configuration. +- The menu list description structure +- The position of the step in a flow (see @subpage step_positioning) +- A boolean to indicate whether this step is modal or not + +@subsection step_release Releasing a step + +Before leaving a screen built with a layout, it must be released with a call to @ref nbgl_stepRelease(). It will free the allocated +objects. + +Releasing a step has no effect on the display, even if a modal step is released. + +@note Releasing is mandatory for modal step, but if on background, it will be automatically released when a new step will be allocated + +@subsection step_positioning Step Positioning + +Usually, a step is part of a flow (list of steps, to be parsed in forward or backward direction). +To indicate to the end-user that navigation between steps is possible, navigation arrows need to be displayed on left and right sides +of the screen (as < and > 'arrows'). + +The navigation can also loop in some cases (only for Applications), which means that at the end of the last step, when pressing +right button the engine will display the beginning of first step (and vice versa). + +To indicate to step engine which 'flow navigation' to draw, an argument (position) is provided to all API used to create steps. +This argument (of type @ref nbgl_stepPosition_t) can take the following values: + +- @ref SINGLE_STEP if this is a single step flow (in this case, no 'flow navigation' is displayed) +- @ref FIRST_STEP if this is the first step in a multiple steps flow +- @ref LAST_STEP if this is the last step in a multiple steps flow +- @ref NEITHER_FIRST_NOR_LAST_STEP, if this is the neither the first nor the last step in a multiple steps flow + +*/ +#endif // NBGL_STEP diff --git a/lib_nbgl/doc/nbgl_use_case.dox b/lib_nbgl/doc/nbgl_use_case.dox index 0db17abd7..c71cc5662 100644 --- a/lib_nbgl/doc/nbgl_use_case.dox +++ b/lib_nbgl/doc/nbgl_use_case.dox @@ -1,3 +1,4 @@ +#ifdef HAVE_SE_TOUCH /** @page nbgl_app_use_case Predefined Application Use-cases API @section nbgl_use_case_intro Introduction @@ -872,3 +873,4 @@ So no need to call @ref nbgl_refresh(). */ +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/doc/nbgl_use_case_nanos.dox b/lib_nbgl/doc/nbgl_use_case_nanos.dox new file mode 100644 index 000000000..01020dfa7 --- /dev/null +++ b/lib_nbgl/doc/nbgl_use_case_nanos.dox @@ -0,0 +1,497 @@ +#ifndef HAVE_SE_TOUCH +/** @page nbgl_app_use_case_nanos Predefined Application Use-cases API + +@section nbgl_use_case_intro Introduction +This chapter describes the Application Use-cases API of Advanced BOLOS Graphic Library. + +This layer offers a simplified view of some typical use-cases of display in an Application running on Stax. +For example, a use-case can be: + +- Reviewing a transaction/message +- Reviewing details on a given data of a transaction/message +- Displaying pages of settings + +A full description of each predefined use-case can be found in this document + +@section nbgl_use_case_concepts Concepts + +This layer uses the Step API described in @ref nbgl_step, but offers to developer more than a single step. + +The goal is to simplify the usage of NBGL, but also to offer a better homogeneity across applications, by pushing +developers to use common API for common use-cases. + +So that not only the look of the pages but also their transitions look the same. Which should be a real help +for end-users, getting more and more familiar with the user experience of applications. + +@subsection nbgl_use_case_example_1 Example 1: transaction review + +\image{inline} html UseCase-Review1.png "caption" height=300 + +In this example, a transaction review consists in 3 successive pages, and can be seen as a use-case + +@subsection nbgl_use_case_example_2 Example 2: settings pages + +\image{inline} html UseCase-Settings1.png "caption" height=300 + +In this example, a parsing the settings (single level) consists in 2 pages, and can be seen as another use-case. + +@section nbgl_use_cases Use Cases + +A few APIs are available to draw typical Use-Cases, such as: + +- for Home Screen: + - @ref nbgl_useCaseHome() to draw the home screen of an application (see @subpage use_case_home) +- for Settings: + - @ref nbgl_useCaseSettings() to draw a level of settings pages (see @subpage use_case_settings) + - @ref nbgl_useCaseSpinner() to draw an infinite spinner page (see @subpage use_case_spinner) +- for most used reviews: + - @ref nbgl_useCaseStaticReview() to draw the pages of a regular review, when all info are available from the beginning (see @subpage use_case_static_review) + - @ref nbgl_useCaseRegularReview() to draw the pages of a regular review (all pages but the cover one) (see @subpage use_case_regular_review) +- for rare reviews: + - @ref nbgl_useCaseForwardOnlyReview() to draw the pages of a forward-only review (without back key) (see @subpage use_case_forward_only_review) + +@subsection use_case_home Home screen Use Case + +\image{inline} html UseCase-Home.png "caption" height=300 + +Ledger would like all application to have the same home screen, so the @ref nbgl_useCaseHome() function enables to +create such a page, the only configurable parameters being: + +- the application name +- the application icon +- the tagline, a text under app name (if NULL, it will be "This app enables signing transactions on the network.") +- the callbacks when touching *quit* or *top-right* buttons +- the type of top-right button (info or settings) + +@code +extern const nbgl_icon_details_t *myAppIcon; + +void myAppSettings(void) { + // draw settings page here +} +void onQuit(void) { + // exit app here +} +void appMain(void) { + nbgl_useCaseHome("MyApp", + &myAppIcon, + NULL, + true, // with settings button + myAppSettings, + onQuit); +} +@endcode + + +@subsection use_case_settings Settings Use Case + +\image{inline} html UseCase-Settings1.png "caption" height=300 + +Usually settings (or information) of an application consist in a list of pages, each page containing: + +- some radio buttons to make a choice +- some switches for various configuration +- a list of information organized by pairs [info_name, info_value] + +The API to initiate the display of the series of pages is @ref nbgl_useCaseSettings(), providing: + +- the title of the settings series +- the page in which to start +- the number of pages +- a boolean to indicate whether the title is touchable or not (if touchable, it is used to quit the series, +so no Quit button in navigation bar) +- a callback called when the quit button (or touchable title) is touched +- a navigation callback called when navigation arrow buttons are touched (and to fill the initial page), to retrieve +the content of the page +- a last callback called when any of the controls provided in content is touched + +@note All tokens used for the given "settings" must be greater or equal than \ref FIRST_USER_TOKEN + +\image{inline} html UseCase-Settings2.png "caption" height=300 + +Here is the source code to display the first example of settings: + +@code +enum { + SWITCH1_TOKEN = FIRST_USER_TOKEN, + SWITCH2_TOKEN, + SWITCH3_TOKEN +}; + +static const nbgl_layoutSwitch_t switches[] = { + { + .initState = false, + .text = "Blind signing", + .subText = "Enable transaction blind\n" "signing", + .token = SWITCH1_TOKEN, + .tuneId = TUNE_TAP_CASUAL + }, + { + .initState = true, + .text = "Debug", + .subText = "Display contract data details", + .token = SWITCH2_TOKEN, + .tuneId = TUNE_TAP_CASUAL + }, + { + .initState = true, + .text = "Nonce", + .subText = "Display account nonce\n" "in transaction", + .token = SWITCH3_TOKEN, + .tuneId = TUNE_TAP_CASUAL + }, +}; + +static const char* infoTypes[] = { + "Version" +}; + +static const char* infoContents[] = { + "1.9.18" +}; + +static bool navCallback(uint8_t page, nbgl_pageContent_t *content) { + // the first settings page contains 3 switches + if (page == 0) { + content->type = SWITCHES_LIST; + content->switchesList.nbSwitches = 3; + content->switchesList.switches = (nbgl_layoutSwitch_t*)switches; + } + // the second settings page contains only the version of the app + else if (page == 1) { + content->type = INFOS_LIST; + content->infosList.nbInfos = 1; + content->infosList.infoTypes = infoTypes; + content->infosList.infoContents = infoContents; + } + else { + return false; + } + // valid page so return true + return true; +} + +static void controlsCallback(int token, uint8_t index) { + if (token == SWITCH1_TOKEN) { + // First switch touched + } +} + +void myAppSettings(void) { + // draw the settings Use Case (2 pages), starting at page 0 + nbgl_useCaseSettings("Ethereum settings",0,2,false,appMain,navCallback,controlsCallback); +} +@endcode + + +@subsection use_case_regular_review Regular Review Use Case + +\image{inline} html UseCase-Review1.png "caption" height=300 + +Usually transaction/message reviews consist in a sequence of pages, each page containing: + +- one or several tag/value pair or a long press button for the final page, to validate the review +- a footer to reject the review + +To navigate between pages, a back arrow is available on the top-left of the screen, and the whole page is "tappable". + +The API to initiate the display of the series of pages is @ref nbgl_useCaseRegularReview(), providing: + +- the page in which to start (usually 0) +- the number of pages (if unknown, set to 0) +- a "button" callback called when a potential button in the page's content is touched +- a navigation callback called when back key or screen is "tapped" , to retrieve +the content of the previous/next page. It is also called to fill the initial page. +- a callback called when the long press button (with param true) on last page or the footer to reject is used (with param false) + +If the number of pages is unknown at the beginning, no progress indicator will be display on top of the screen. + +Here is the code to display something similar to example picture: + +@code +// 4 pairs of tag/value to display +static nbgl_layoutTagValue_t pairs[4]; + +static void onConfirmAbandon(void) { + // display a status page and go back to main + nbgl_useCaseStatus("Transaction rejected",false,appMain); +} + +// called when long press button on 3rd page is long-touched or when reject footer is touched +static void reviewChoice(bool confirm) { + if (confirm) { + // display a status page and go back to main + nbgl_useCaseStatus("TRANSACTION\nSIGNED",true,appMain); + } + else { + nbgl_useCaseConfirm("Reject transaction?","Yes, Reject","Go back to transaction",onConfirmAbandon); + } +} + +// called to get the content of the given page +static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) { + if (page == 0) { + // the first page contains 3 tag/value pairs + content->type = TAG_VALUE_LIST; + content->tagValueList.nbPairs = 3; + content->tagValueList.pairs = (nbgl_layoutTagValue_t *)pairs; + content->tagValueList.smallCaseForValue = false; + } + else if (page == 1) { + // the second page contains 1 tag/value pair + content->type = TAG_VALUE_LIST; + content->tagValueList.nbPairs = 1; + content->tagValueList.pairs = (nbgl_layoutTagValue_t *)&pairs[3]; + content->tagValueList.smallCaseForValue = false; + } + else if (page == 2) { + // the last page must contain a long press button + content->type = INFO_LONG_PRESS, + content->infoLongPress.icon = &myAppIcon; + content->infoLongPress.text = "Confirm transaction\nMyCoin send"; + content->infoLongPress.longPressText = "Hold to send"; + content->infoLongPress.longPressToken = VALIDATE_TRANSACTION_TOKEN; + } + else { + return false; + } + // valid page so return true + return true; +} + +void reviewContinue(void) { + // review on 3 pages, starting at 0 + nbgl_useCaseRegularReview(0, 3, "Reject transaction", + NULL, // no buttons because no value is too long to fit + displayTransactionPage, reviewChoice); +} +@endcode + +@subsection use_case_forward_only_review Forward only Review Use Case + +\image{inline} html UseCase-ReviewForwardOnly.png "caption" height=500 + +Some message/transaction reviews may be too long to be memorized, so it is only possible to move forward. + +In this case, no back arrow is available on the top-left of the screen. Moreover, these reviews are always done with +an unknown number of pages. +A "Skip" button is added automatically in all pages except the one with Long Press button, +to jump to last page, after an automatic confirmation modal window is displayed. + +The API to initiate the display of the series of forward-only review pages is @ref nbgl_useCaseForwardOnlyReview(), providing: + +- a "button" callback called when a potential button in the page's content is touched +- a navigation callback called when screen is "tapped" , to retrieve +the content of the next page. It is also called to fill the initial page. +- a callback called when the long press button (with param true) on last page or the footer to reject is used (with param false) + +Here is the code to display something similar to example picture: + +@code + +// 5 pairs of tag/value to display +static nbgl_layoutTagValue_t pairs[5]; + +// result of the rejection +static void onConfirmAbandon(void) { + // display a status page and go back to main + nbgl_useCaseStatus("Transaction rejected",false,appMain); +} + +// called when long press button on 3rd page is long-touched or when reject footer is touched +static void reviewChoice(bool confirm) { + if (confirm) { + // display a status page and go back to main + nbgl_useCaseStatus("TRANSACTION\nSIGNED",true,appMain); + } + else { + nbgl_useCaseConfirm("Reject transaction?","Yes, Reject","Go back to transaction",onConfirmAbandon); + } +} + +// called to get the content of the given page +static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) { + if (page == 0) { + // the first page contains 3 tag/value pairs + content->type = TAG_VALUE_LIST; + content->tagValueList.nbPairs = 3; + content->tagValueList.pairs = (nbgl_layoutTagValue_t *)pairs; + content->tagValueList.smallCaseForValue = false; + } + else if (page == 1) { + // the second page contains 2 tag/value pairs + content->type = TAG_VALUE_LIST; + content->tagValueList.nbPairs = 2; + content->tagValueList.pairs = (nbgl_layoutTagValue_t *)&pairs[3]; + content->tagValueList.smallCaseForValue = false; + } + else if (page == 2) { + // the last page must contain a long press button + content->type = INFO_LONG_PRESS, + content->infoLongPress.icon = &myAppIcon; + content->infoLongPress.text = "Confirm transaction\nMyCoin send"; + content->infoLongPress.longPressText = "Hold to send"; + } + else { + return false; + } + // valid page so return true + return true; +} + +void reviewContinue(void) { + nbgl_useCaseForwardOnlyReview("Reject transaction", + NULL, // No details button so no callback needed + displayTransactionPage, reviewChoice); +} +@endcode + +@subsection use_case_static_review Static Review Use Case + +\image{inline} html UseCase-Review1.png "caption" height=300 + +In some cases, the developer may know all tag/value pairs of a transaction when it is submitted. + +In this case, what we call a "static" review can be used. It is similar to a regular review with know number of pages in terms of +presentation and interactions with end-users, but much easier to use for developer. + +Indeed, in this case, NBGL automatically computes the number of pages, and the pairs to draw in each page. +In case of a tag/value pair too long to be fully displayed, the "more" button will be automatically drawn and its handling +automatically performed by NBGL by building a detailed modal view. + +The API to initiate the display of the series of pages is @ref nbgl_useCaseStaticReview(), providing: + +- the list of tag/value pairs (or a callback to get them one by one) +- the texts to use in footer and in last page +- a callback called when the long press button on last page or the footer to reject is used. The callback's param is true for confirmation, false for rejection. + +Here is the code to display something similar to example picture: + +@code +// 4 pairs of tag/value to display +static nbgl_layoutTagValue_t pairs[4]; + +static nbgl_layoutTagValueList_t pairList = { + .nbMaxLinesForValue = 0, + .nbPairs = 4, + .pairs = (nbgl_layoutTagValue_t*)pairs +}; + +// result of the rejection choice +static void onConfirmAbandon(void) { + // display a status page and go back to main + nbgl_useCaseStatus("Transaction rejected",false,appMain); +} + +// called when long press button on 3rd page is long-touched or when reject footer is touched +static void reviewChoice(bool confirm) { + if (confirm) { + // display a status page and go back to main + nbgl_useCaseStatus("TRANSACTION\nSIGNED",true,appMain); + } + else { + // display a confirmation to confirm/cancel rejection + nbgl_useCaseConfirm("Reject transaction?","Yes, Reject","Go back to transaction",onConfirmAbandon); + } +} + +void reviewContinue(void) { + static nbgl_pageInfoLongPress_t infoLongPress = { + .icon = &myAppIcon, + .text = "Confirm transaction\nMyAppCoin send", + .longPressText = "Hold to send" + }; + + // static review, providing the whole list of pairs + nbgl_useCaseStaticReview(&pairList, &infoLongPress, "Reject transaction", reviewChoice); +} +@endcode + +Here is another version of the example code, using a callback mechanism to get tag/value pairs: + +@code +// common tag/value pair to return +static nbgl_layoutTagValue_t pair; + +static nbgl_layoutTagValue_t* getPair(uint8_t index); + +static nbgl_layoutTagValueList_t pairList = { + .nbMaxLinesForValue = 0, + .nbPairs = 4, + .pairs = NULL, // to indicate that callback should be used + .callback = getPair, + .startIndex = 0 +}; + +// result of the rejection choice +static void onConfirmAbandon(void) { + // display a status page and go back to main + nbgl_useCaseStatus("Transaction rejected",false,appMain); +} + +// called when long press button on 3rd page is long-touched or when reject footer is touched +static void reviewChoice(bool confirm) { + if (confirm) { + // display a status page and go back to main + nbgl_useCaseStatus("TRANSACTION\nSIGNED",true,appMain); + } + else { + // display a confirmation to confirm/cancel rejection + nbgl_useCaseConfirm("Reject transaction?","Yes, Reject","Go back to transaction",onConfirmAbandon); + } +} + +// function called by NBGL to get the pair indexed by "index" +static nbgl_layoutTagValue_t* getPair(uint8_t index) { + switch (index) { + case 0: + pair.item = "To"; + pair.value = "0x123456"; + break; + case 1: + pair.item = "From"; + pair.value = "0x654321"; + break; + case 2: + pair.item = "Amount"; + pair.value = "1.2345 BTC"; + break; + case 3: + pair.item = "Fees"; + pair.value = "0.1 BTC"; + break; + } + return &pair; +} + +void reviewContinue(void) { + static nbgl_pageInfoLongPress_t infoLongPress = { + .icon = &myAppIcon, + .text = "Confirm transaction\nMyAppCoin send", + .longPressText = "Hold to send" + }; + + // static review, providing the whole list of pairs + nbgl_useCaseStaticReview(&pairList, &infoLongPress, "Reject transaction", reviewChoice); +} +@endcode + +@subsection use_case_spinner Spinner Use Case + +\image{inline} html UseCase-Spinner.png "caption" height=300 + +When an address needs to be confirmed, it can be displayed in a Address Confirmation Use Case, at first as simple page with +the raw address (as text) and a black button/Footer pair to choose to confirm or reject the address. + +An extra button under the raw address enables to open a modal page to see the address as a QR code. + +The @ref nbgl_useCaseSpinner() function enables to create such a page, with the following parameters: + +@section use_case_refresh_page Refreshing screen + +After having drawn graphic objects in **framebuffer**, all functions of this API automatically refresh the screen. +So no need to call @ref nbgl_refresh(). + + +*/ +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/doc/resources/layout_nanos_1.png b/lib_nbgl/doc/resources/layout_nanos_1.png new file mode 100755 index 000000000..ceceed23e Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_1.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_centered.png b/lib_nbgl/doc/resources/layout_nanos_centered.png new file mode 100755 index 000000000..34786fd34 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_centered.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_flow1.png b/lib_nbgl/doc/resources/layout_nanos_flow1.png new file mode 100755 index 000000000..6e95ba14d Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_flow1.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_keyboard1.png b/lib_nbgl/doc/resources/layout_nanos_keyboard1.png new file mode 100755 index 000000000..c57350061 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_keyboard1.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_keypad1.png b/lib_nbgl/doc/resources/layout_nanos_keypad1.png new file mode 100755 index 000000000..1f322f3d8 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_keypad1.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_menu_list.png b/lib_nbgl/doc/resources/layout_nanos_menu_list.png new file mode 100755 index 000000000..de9ce1137 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_menu_list.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_nav1.png b/lib_nbgl/doc/resources/layout_nanos_nav1.png new file mode 100755 index 000000000..eb19e4a86 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_nav1.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_nav2.png b/lib_nbgl/doc/resources/layout_nanos_nav2.png new file mode 100755 index 000000000..c9444712b Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_nav2.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_step_centered.png b/lib_nbgl/doc/resources/layout_nanos_step_centered.png new file mode 100755 index 000000000..66f721581 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_step_centered.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_step_menu_list.png b/lib_nbgl/doc/resources/layout_nanos_step_menu_list.png new file mode 100755 index 000000000..f9c9636b4 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_step_menu_list.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_step_text1.png b/lib_nbgl/doc/resources/layout_nanos_step_text1.png new file mode 100755 index 000000000..806971698 Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_step_text1.png differ diff --git a/lib_nbgl/doc/resources/layout_nanos_step_text2.png b/lib_nbgl/doc/resources/layout_nanos_step_text2.png new file mode 100755 index 000000000..d73b7102b Binary files /dev/null and b/lib_nbgl/doc/resources/layout_nanos_step_text2.png differ diff --git a/lib_nbgl/fonts/config-open_sans_extrabold_11.ini b/lib_nbgl/fonts/config-open_sans_extrabold_11.ini new file mode 100644 index 000000000..eebde765e --- /dev/null +++ b/lib_nbgl/fonts/config-open_sans_extrabold_11.ini @@ -0,0 +1,14 @@ +[main] +font=open_sans_extrabold.ttf +font_id_name=BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp +# Distance of the baseline from the top of the loaded pictures +loaded_baseline=12 +fontSize=11 +lineSize=14 +firstChar=0x20 +lastChar=0x7E +baseline_offset=0 +crop=true +bpp=1 +kerning=1 +nbgl=true diff --git a/lib_nbgl/fonts/config-open_sans_light_16.ini b/lib_nbgl/fonts/config-open_sans_light_16.ini new file mode 100644 index 000000000..881f122ed --- /dev/null +++ b/lib_nbgl/fonts/config-open_sans_light_16.ini @@ -0,0 +1,14 @@ +[main] +font=open_sans_light.ttf +font_id_name=BAGL_FONT_OPEN_SANS_LIGHT_16px_1bpp +# Distance of the baseline from the top of the loaded pictures +loaded_baseline=16 +fontSize=16 +lineSize=21 +firstChar=0x20 +lastChar=0x7E +firstLine=4 +crop=true +bpp=1 +kerning=2 +nbgl=true diff --git a/lib_nbgl/fonts/config-open_sans_regular_11.ini b/lib_nbgl/fonts/config-open_sans_regular_11.ini new file mode 100644 index 000000000..a8dd26296 --- /dev/null +++ b/lib_nbgl/fonts/config-open_sans_regular_11.ini @@ -0,0 +1,14 @@ +[main] +font=open_sans_regular.ttf +font_id_name=BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp +# Distance of the baseline from the top of the loaded pictures +loaded_baseline=12 +fontSize=11 +lineSize=14 +firstChar=0x20 +lastChar=0x7E +baseline_offset=0 +crop=true +bpp=1 +kerning=1 +nbgl=true diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000020.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000020.gif new file mode 100644 index 000000000..7b0f8a4a6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000020.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000021.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000021.gif new file mode 100644 index 000000000..578ba07f7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000021.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000022.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000022.gif new file mode 100644 index 000000000..62cf48263 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000022.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000023.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000023.gif new file mode 100644 index 000000000..7c09ea608 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000023.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000024.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000024.gif new file mode 100644 index 000000000..3e4716112 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000024.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000025.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000025.gif new file mode 100644 index 000000000..c9db4d0d0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000025.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000026.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000026.gif new file mode 100644 index 000000000..c35dd6bd9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000026.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000027.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000027.gif new file mode 100644 index 000000000..a6ed2c982 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000027.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000028.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000028.gif new file mode 100644 index 000000000..93347e484 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000028.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000029.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000029.gif new file mode 100644 index 000000000..297af3454 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000029.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002A.gif new file mode 100644 index 000000000..0512efae6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002B.gif new file mode 100644 index 000000000..7d4a731b6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002C.gif new file mode 100644 index 000000000..6ab4ce251 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002D.gif new file mode 100644 index 000000000..ea4d72aaf Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002E.gif new file mode 100644 index 000000000..c2cb96ef6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002F.gif new file mode 100644 index 000000000..3c10824b2 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00002F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000030.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000030.gif new file mode 100644 index 000000000..bcecb6fcc Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000030.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000031.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000031.gif new file mode 100644 index 000000000..07abc95fc Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000031.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000032.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000032.gif new file mode 100644 index 000000000..333a45da5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000032.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000033.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000033.gif new file mode 100644 index 000000000..3f532dc94 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000033.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000034.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000034.gif new file mode 100644 index 000000000..a0d108023 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000034.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000035.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000035.gif new file mode 100644 index 000000000..ccb819981 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000035.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000036.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000036.gif new file mode 100644 index 000000000..fa121157c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000036.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000037.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000037.gif new file mode 100644 index 000000000..ff9c75e1a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000037.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000038.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000038.gif new file mode 100644 index 000000000..3f510d106 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000038.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000039.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000039.gif new file mode 100644 index 000000000..237d0bd60 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000039.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003A.gif new file mode 100644 index 000000000..6c6b7fa05 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003B.gif new file mode 100644 index 000000000..76f9246d9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003C.gif new file mode 100644 index 000000000..1928d17c7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003D.gif new file mode 100644 index 000000000..8f6926f6c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003E.gif new file mode 100644 index 000000000..30b2d5161 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003F.gif new file mode 100644 index 000000000..1bdae053d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00003F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000040.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000040.gif new file mode 100644 index 000000000..208527db7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000040.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000041.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000041.gif new file mode 100644 index 000000000..4d0842eed Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000041.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000042.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000042.gif new file mode 100644 index 000000000..d938cbfd8 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000042.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000043.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000043.gif new file mode 100644 index 000000000..8f3d9448f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000043.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000044.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000044.gif new file mode 100644 index 000000000..86e095f3d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000044.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000045.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000045.gif new file mode 100644 index 000000000..fd328824f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000045.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000046.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000046.gif new file mode 100644 index 000000000..9424a382c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000046.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000047.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000047.gif new file mode 100644 index 000000000..4f58a26a3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000047.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000048.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000048.gif new file mode 100644 index 000000000..e8421b626 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000048.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000049.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000049.gif new file mode 100644 index 000000000..7a0cc09e9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000049.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004A.gif new file mode 100644 index 000000000..c9bd9d10a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004B.gif new file mode 100644 index 000000000..222514919 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004C.gif new file mode 100644 index 000000000..250ce6b41 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004D.gif new file mode 100644 index 000000000..bdbd52f59 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004E.gif new file mode 100644 index 000000000..42b9de328 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004F.gif new file mode 100644 index 000000000..9f8d50ee2 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00004F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000050.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000050.gif new file mode 100644 index 000000000..44a46e10e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000050.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000051.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000051.gif new file mode 100644 index 000000000..b70921083 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000051.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000052.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000052.gif new file mode 100644 index 000000000..8d2bbeb93 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000052.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000053.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000053.gif new file mode 100644 index 000000000..35425a1d9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000053.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000054.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000054.gif new file mode 100644 index 000000000..f1aa9dec7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000054.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000055.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000055.gif new file mode 100644 index 000000000..5925a23f1 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000055.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000056.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000056.gif new file mode 100644 index 000000000..4658a25f9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000056.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000057.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000057.gif new file mode 100644 index 000000000..457316544 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000057.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000058.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000058.gif new file mode 100644 index 000000000..01642e93a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000058.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000059.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000059.gif new file mode 100644 index 000000000..dc1d5363b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000059.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005A.gif new file mode 100644 index 000000000..cbde6ea57 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005B.gif new file mode 100644 index 000000000..c29bca2b2 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005C.gif new file mode 100644 index 000000000..2c5170a66 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005D.gif new file mode 100644 index 000000000..62983f01e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005E.gif new file mode 100644 index 000000000..8b2982783 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005F.gif new file mode 100644 index 000000000..9f6b721cd Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00005F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000060.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000060.gif new file mode 100644 index 000000000..b8dc88be9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000060.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000061.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000061.gif new file mode 100644 index 000000000..94b70728d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000061.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000062.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000062.gif new file mode 100644 index 000000000..6ad82e2d7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000062.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000063.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000063.gif new file mode 100644 index 000000000..d60154879 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000063.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000064.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000064.gif new file mode 100644 index 000000000..4417bbd90 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000064.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000065.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000065.gif new file mode 100644 index 000000000..72981a222 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000065.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000066.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000066.gif new file mode 100644 index 000000000..6ad80415b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000066.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000067.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000067.gif new file mode 100644 index 000000000..a9c757d95 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000067.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000068.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000068.gif new file mode 100644 index 000000000..ba6775b5a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000068.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000069.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000069.gif new file mode 100644 index 000000000..da2c2fc37 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000069.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006A.gif new file mode 100644 index 000000000..d8d482e76 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006B.gif new file mode 100644 index 000000000..4221495c3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006C.gif new file mode 100644 index 000000000..7a0cc09e9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006D.gif new file mode 100644 index 000000000..a74df592c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006E.gif new file mode 100644 index 000000000..fb134caef Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006F.gif new file mode 100644 index 000000000..1fa7c82c3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00006F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000070.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000070.gif new file mode 100644 index 000000000..4790bae12 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000070.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000071.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000071.gif new file mode 100644 index 000000000..fcb91d962 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000071.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000072.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000072.gif new file mode 100644 index 000000000..b7a26ca30 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000072.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000073.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000073.gif new file mode 100644 index 000000000..36c919d7b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000073.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000074.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000074.gif new file mode 100644 index 000000000..bb306bb83 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000074.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000075.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000075.gif new file mode 100644 index 000000000..fdad64f30 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000075.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000076.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000076.gif new file mode 100644 index 000000000..ce01d41ad Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000076.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000077.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000077.gif new file mode 100644 index 000000000..c6596d579 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000077.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000078.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000078.gif new file mode 100644 index 000000000..9178a668e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000078.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000079.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000079.gif new file mode 100644 index 000000000..2f6772675 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x000079.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007A.gif new file mode 100644 index 000000000..fc82d8312 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007B.gif new file mode 100644 index 000000000..752cb02da Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007C.gif new file mode 100644 index 000000000..70ba6ffd5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007D.gif new file mode 100644 index 000000000..5aad2c27a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007E.gif new file mode 100644 index 000000000..85eda3653 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007F.gif new file mode 100644 index 000000000..3e6c38b1d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp/nbgl_font_open_sans_extrabold_11px_1bpp_0x00007F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000A1.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000A1.gif new file mode 100644 index 000000000..12a9039a5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000A1.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000BF.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000BF.gif new file mode 100644 index 000000000..03a2e6956 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000BF.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E0.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E0.gif new file mode 100644 index 000000000..d0e52dcfd Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E0.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E2.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E2.gif new file mode 100644 index 000000000..50b2fc957 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E2.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E7.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E7.gif new file mode 100644 index 000000000..180b56fcc Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E7.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E8.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E8.gif new file mode 100644 index 000000000..ed7dd3251 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E8.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E9.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E9.gif new file mode 100644 index 000000000..9ea10de11 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000E9.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EA.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EA.gif new file mode 100644 index 000000000..adab0b5b0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EA.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EB.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EB.gif new file mode 100644 index 000000000..c952ecd16 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EB.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EE.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EE.gif new file mode 100644 index 000000000..cbf7d9736 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EE.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EF.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EF.gif new file mode 100644 index 000000000..744f8784f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000EF.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000F4.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000F4.gif new file mode 100644 index 000000000..f6b832d07 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000F4.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000FB.gif b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000FB.gif new file mode 100644 index 000000000..181801622 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_extrabold_11px_1bpp_unicode/nbgl_font_open_sans_extrabold_11px_1bpp_unicode_0x0000FB.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000020.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000020.gif new file mode 100644 index 000000000..4d3c77654 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000020.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000021.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000021.gif new file mode 100644 index 000000000..7717f998e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000021.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000022.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000022.gif new file mode 100644 index 000000000..33c3bfe3e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000022.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000023.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000023.gif new file mode 100644 index 000000000..3434b029c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000023.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000024.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000024.gif new file mode 100644 index 000000000..985f1fce6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000024.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000025.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000025.gif new file mode 100644 index 000000000..1f56b8f69 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000025.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000026.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000026.gif new file mode 100644 index 000000000..b7d928518 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000026.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000027.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000027.gif new file mode 100644 index 000000000..865ed79ad Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000027.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000028.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000028.gif new file mode 100644 index 000000000..9254b1a42 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000028.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000029.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000029.gif new file mode 100644 index 000000000..684be8873 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000029.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002A.gif new file mode 100644 index 000000000..20772d964 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002B.gif new file mode 100644 index 000000000..11781376d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002C.gif new file mode 100644 index 000000000..86b1f1d02 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002D.gif new file mode 100644 index 000000000..bb1f8c12f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002E.gif new file mode 100644 index 000000000..105f80b1b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002F.gif new file mode 100644 index 000000000..73f1a1396 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00002F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000030.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000030.gif new file mode 100644 index 000000000..ddcac64f7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000030.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000031.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000031.gif new file mode 100644 index 000000000..252545cd0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000031.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000032.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000032.gif new file mode 100644 index 000000000..817d18e6a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000032.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000033.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000033.gif new file mode 100644 index 000000000..b1e0e88c6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000033.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000034.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000034.gif new file mode 100644 index 000000000..c5bcb20e7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000034.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000035.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000035.gif new file mode 100644 index 000000000..2f33ea071 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000035.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000036.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000036.gif new file mode 100644 index 000000000..42ef3bfcc Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000036.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000037.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000037.gif new file mode 100644 index 000000000..74512bce6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000037.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000038.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000038.gif new file mode 100644 index 000000000..7ef15b780 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000038.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000039.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000039.gif new file mode 100644 index 000000000..e8f767e40 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000039.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003A.gif new file mode 100644 index 000000000..b4e781c8d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003B.gif new file mode 100644 index 000000000..9e407ebe0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003C.gif new file mode 100644 index 000000000..0191430c0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003D.gif new file mode 100644 index 000000000..8d480721f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003E.gif new file mode 100644 index 000000000..1856c930d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003F.gif new file mode 100644 index 000000000..ec9f246fd Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00003F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000040.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000040.gif new file mode 100644 index 000000000..5f84d0619 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000040.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000041.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000041.gif new file mode 100644 index 000000000..38da71a05 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000041.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000042.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000042.gif new file mode 100644 index 000000000..4245fbe66 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000042.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000043.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000043.gif new file mode 100644 index 000000000..4f8ce2d2e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000043.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000044.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000044.gif new file mode 100644 index 000000000..ffdbf1ebc Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000044.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000045.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000045.gif new file mode 100644 index 000000000..a206bf23d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000045.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000046.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000046.gif new file mode 100644 index 000000000..22ccbf519 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000046.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000047.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000047.gif new file mode 100644 index 000000000..41354a1b9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000047.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000048.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000048.gif new file mode 100644 index 000000000..ec5b68673 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000048.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000049.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000049.gif new file mode 100644 index 000000000..dc72db190 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000049.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004A.gif new file mode 100644 index 000000000..e58ce4fe7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004B.gif new file mode 100644 index 000000000..d083fd8d3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004C.gif new file mode 100644 index 000000000..bcddc17e4 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004D.gif new file mode 100644 index 000000000..b994ada64 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004E.gif new file mode 100644 index 000000000..aada270d3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004F.gif new file mode 100644 index 000000000..7cf0c182e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00004F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000050.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000050.gif new file mode 100644 index 000000000..a3108a423 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000050.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000051.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000051.gif new file mode 100644 index 000000000..21bd1b6e5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000051.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000052.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000052.gif new file mode 100644 index 000000000..5e7c79da3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000052.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000053.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000053.gif new file mode 100644 index 000000000..6966f7f9c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000053.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000054.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000054.gif new file mode 100644 index 000000000..a53c48b80 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000054.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000055.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000055.gif new file mode 100644 index 000000000..3bb4c397d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000055.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000056.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000056.gif new file mode 100644 index 000000000..e294960ed Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000056.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000057.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000057.gif new file mode 100644 index 000000000..c4278566d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000057.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000058.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000058.gif new file mode 100644 index 000000000..7781e371c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000058.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000059.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000059.gif new file mode 100644 index 000000000..050f211b1 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000059.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005A.gif new file mode 100644 index 000000000..9a4f23bbf Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005B.gif new file mode 100644 index 000000000..9d8fa4a40 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005C.gif new file mode 100644 index 000000000..8700dfaab Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005D.gif new file mode 100644 index 000000000..e5b91d6cf Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005E.gif new file mode 100644 index 000000000..d23f214ee Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005F.gif new file mode 100644 index 000000000..92c21014c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00005F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000060.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000060.gif new file mode 100644 index 000000000..df1a67e4c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000060.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000061.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000061.gif new file mode 100644 index 000000000..2e0183ccf Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000061.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000062.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000062.gif new file mode 100644 index 000000000..d99b79979 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000062.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000063.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000063.gif new file mode 100644 index 000000000..c5672237c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000063.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000064.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000064.gif new file mode 100644 index 000000000..64cf90ccd Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000064.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000065.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000065.gif new file mode 100644 index 000000000..6de8f4c99 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000065.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000066.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000066.gif new file mode 100644 index 000000000..53da4e50d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000066.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000067.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000067.gif new file mode 100644 index 000000000..d71a4374a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000067.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000068.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000068.gif new file mode 100644 index 000000000..f322e1feb Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000068.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000069.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000069.gif new file mode 100644 index 000000000..e01ea7f4b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000069.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006A.gif new file mode 100644 index 000000000..bc8f49ebf Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006B.gif new file mode 100644 index 000000000..2233473db Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006C.gif new file mode 100644 index 000000000..ab21c7735 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006D.gif new file mode 100644 index 000000000..0806fb8fa Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006E.gif new file mode 100644 index 000000000..e8c4cae76 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006F.gif new file mode 100644 index 000000000..0241dd6ac Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00006F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000070.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000070.gif new file mode 100644 index 000000000..018c7f108 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000070.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000071.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000071.gif new file mode 100644 index 000000000..608ae1fd5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000071.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000072.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000072.gif new file mode 100644 index 000000000..d324b4612 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000072.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000073.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000073.gif new file mode 100644 index 000000000..3bfd6531f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000073.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000074.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000074.gif new file mode 100644 index 000000000..bef28ed06 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000074.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000075.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000075.gif new file mode 100644 index 000000000..7880323dd Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000075.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000076.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000076.gif new file mode 100644 index 000000000..25776f9e9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000076.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000077.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000077.gif new file mode 100644 index 000000000..71c4b299a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000077.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000078.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000078.gif new file mode 100644 index 000000000..5eaf90abe Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000078.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000079.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000079.gif new file mode 100644 index 000000000..1972c1a80 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x000079.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007A.gif new file mode 100644 index 000000000..b0c9f805a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007B.gif new file mode 100644 index 000000000..bd51d063a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007C.gif new file mode 100644 index 000000000..60a3c89f8 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007D.gif new file mode 100644 index 000000000..c7125c3fa Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007E.gif new file mode 100644 index 000000000..557548602 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007F.gif new file mode 100644 index 000000000..c7ad1a1c1 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp/nbgl_font_open_sans_light_16px_1bpp_0x00007F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000A1.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000A1.gif new file mode 100644 index 000000000..050dc8f11 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000A1.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000C9.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000C9.gif new file mode 100644 index 000000000..8a7d1d191 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000C9.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E0.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E0.gif new file mode 100644 index 000000000..38e5cf96b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E0.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E2.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E2.gif new file mode 100644 index 000000000..d4cea9b08 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E2.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E8.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E8.gif new file mode 100644 index 000000000..5457ff849 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E8.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E9.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E9.gif new file mode 100644 index 000000000..5d2870a03 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000E9.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EA.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EA.gif new file mode 100644 index 000000000..bb80d6da9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EA.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EB.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EB.gif new file mode 100644 index 000000000..3beb161c7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EB.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EE.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EE.gif new file mode 100644 index 000000000..d0058cf47 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EE.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EF.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EF.gif new file mode 100644 index 000000000..59f3a1af0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000EF.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000F1.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000F1.gif new file mode 100644 index 000000000..7e5363a0f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000F1.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000F9.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000F9.gif new file mode 100644 index 000000000..4be8f7d60 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000F9.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000FB.gif b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000FB.gif new file mode 100644 index 000000000..07bcd45de Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_light_16px_1bpp_unicode/nbgl_font_open_sans_light_16px_1bpp_unicode_0x0000FB.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000020.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000020.gif new file mode 100644 index 000000000..7b0f8a4a6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000020.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000021.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000021.gif new file mode 100644 index 000000000..3e7ee9a98 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000021.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000022.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000022.gif new file mode 100644 index 000000000..71d9a0065 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000022.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000023.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000023.gif new file mode 100644 index 000000000..197f03084 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000023.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000024.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000024.gif new file mode 100644 index 000000000..2ba618a96 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000024.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000025.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000025.gif new file mode 100644 index 000000000..69db0ba6c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000025.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000026.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000026.gif new file mode 100644 index 000000000..a5e4764e0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000026.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000027.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000027.gif new file mode 100644 index 000000000..eafb95322 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000027.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000028.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000028.gif new file mode 100644 index 000000000..080817df5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000028.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000029.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000029.gif new file mode 100644 index 000000000..e55c5be18 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000029.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002A.gif new file mode 100644 index 000000000..186c9ef1b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002B.gif new file mode 100644 index 000000000..618ea80c5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002C.gif new file mode 100644 index 000000000..5a48f88e2 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002D.gif new file mode 100644 index 000000000..a9f5b5175 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002E.gif new file mode 100644 index 000000000..af6662e1c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002F.gif new file mode 100644 index 000000000..14119ab47 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00002F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000030.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000030.gif new file mode 100644 index 000000000..880572445 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000030.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000031.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000031.gif new file mode 100644 index 000000000..9e28bcb4e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000031.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000032.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000032.gif new file mode 100644 index 000000000..99f3dd13b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000032.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000033.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000033.gif new file mode 100644 index 000000000..465367606 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000033.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000034.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000034.gif new file mode 100644 index 000000000..9034940dd Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000034.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000035.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000035.gif new file mode 100644 index 000000000..07158d96b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000035.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000036.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000036.gif new file mode 100644 index 000000000..d97976c8f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000036.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000037.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000037.gif new file mode 100644 index 000000000..47cfa11d8 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000037.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000038.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000038.gif new file mode 100644 index 000000000..0e8d50b27 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000038.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000039.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000039.gif new file mode 100644 index 000000000..f992bdbd9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000039.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003A.gif new file mode 100644 index 000000000..acf6dba80 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003B.gif new file mode 100644 index 000000000..17972af2b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003C.gif new file mode 100644 index 000000000..0705b34c5 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003D.gif new file mode 100644 index 000000000..81547b55f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003E.gif new file mode 100644 index 000000000..13fac8b31 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003F.gif new file mode 100644 index 000000000..6053d7ce8 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00003F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000040.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000040.gif new file mode 100644 index 000000000..3d3cf2d13 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000040.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000041.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000041.gif new file mode 100644 index 000000000..9a88ace96 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000041.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000042.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000042.gif new file mode 100644 index 000000000..3c8d17dfd Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000042.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000043.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000043.gif new file mode 100644 index 000000000..3e16314e1 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000043.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000044.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000044.gif new file mode 100644 index 000000000..5a071c9a9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000044.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000045.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000045.gif new file mode 100644 index 000000000..6d591cf5f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000045.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000046.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000046.gif new file mode 100644 index 000000000..0a5edfe2f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000046.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000047.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000047.gif new file mode 100644 index 000000000..f92d51d10 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000047.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000048.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000048.gif new file mode 100644 index 000000000..50ba02a11 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000048.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000049.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000049.gif new file mode 100644 index 000000000..7e5701cf0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000049.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004A.gif new file mode 100644 index 000000000..1745057d9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004B.gif new file mode 100644 index 000000000..e55f1f7c1 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004C.gif new file mode 100644 index 000000000..3071a82a3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004D.gif new file mode 100644 index 000000000..f8170feb6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004E.gif new file mode 100644 index 000000000..35814b534 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004F.gif new file mode 100644 index 000000000..5b3f9da93 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00004F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000050.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000050.gif new file mode 100644 index 000000000..21e019f5e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000050.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000051.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000051.gif new file mode 100644 index 000000000..edbe4b84b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000051.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000052.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000052.gif new file mode 100644 index 000000000..6420eddeb Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000052.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000053.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000053.gif new file mode 100644 index 000000000..d98d2108b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000053.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000054.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000054.gif new file mode 100644 index 000000000..9a2fc4bac Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000054.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000055.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000055.gif new file mode 100644 index 000000000..a0c8fd16c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000055.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000056.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000056.gif new file mode 100644 index 000000000..cfef27966 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000056.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000057.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000057.gif new file mode 100644 index 000000000..1c315f90b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000057.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000058.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000058.gif new file mode 100644 index 000000000..3d035bd9f Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000058.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000059.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000059.gif new file mode 100644 index 000000000..b02f0dd1c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000059.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005A.gif new file mode 100644 index 000000000..7a0e312c7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005B.gif new file mode 100644 index 000000000..886f43786 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005C.gif new file mode 100644 index 000000000..8bcc5b20c Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005D.gif new file mode 100644 index 000000000..a70c7872e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005E.gif new file mode 100644 index 000000000..f158a69be Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005F.gif new file mode 100644 index 000000000..89777689d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00005F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000060.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000060.gif new file mode 100644 index 000000000..b5388caf7 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000060.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000061.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000061.gif new file mode 100644 index 000000000..6d9fad85b Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000061.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000062.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000062.gif new file mode 100644 index 000000000..a3046baa3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000062.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000063.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000063.gif new file mode 100644 index 000000000..e462b6954 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000063.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000064.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000064.gif new file mode 100644 index 000000000..3e557f951 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000064.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000065.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000065.gif new file mode 100644 index 000000000..b35b49173 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000065.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000066.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000066.gif new file mode 100644 index 000000000..3f2803a03 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000066.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000067.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000067.gif new file mode 100644 index 000000000..6808a4040 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000067.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000068.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000068.gif new file mode 100644 index 000000000..0853582a9 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000068.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000069.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000069.gif new file mode 100644 index 000000000..16a5cecba Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000069.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006A.gif new file mode 100644 index 000000000..2634f2ec1 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006B.gif new file mode 100644 index 000000000..a14913c2a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006C.gif new file mode 100644 index 000000000..7e5701cf0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006D.gif new file mode 100644 index 000000000..99a70f084 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006E.gif new file mode 100644 index 000000000..1a70fca52 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006F.gif new file mode 100644 index 000000000..703e17f7d Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00006F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000070.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000070.gif new file mode 100644 index 000000000..f86a5e942 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000070.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000071.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000071.gif new file mode 100644 index 000000000..89901a5f0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000071.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000072.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000072.gif new file mode 100644 index 000000000..73d42e2f3 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000072.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000073.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000073.gif new file mode 100644 index 000000000..325c1a5e6 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000073.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000074.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000074.gif new file mode 100644 index 000000000..d4b952cb1 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000074.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000075.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000075.gif new file mode 100644 index 000000000..0bc372351 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000075.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000076.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000076.gif new file mode 100644 index 000000000..d91bfd4d0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000076.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000077.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000077.gif new file mode 100644 index 000000000..ac3cb1954 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000077.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000078.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000078.gif new file mode 100644 index 000000000..fd082a208 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000078.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000079.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000079.gif new file mode 100644 index 000000000..44036ac86 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x000079.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007A.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007A.gif new file mode 100644 index 000000000..186a051e0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007A.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007B.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007B.gif new file mode 100644 index 000000000..101c41496 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007B.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007C.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007C.gif new file mode 100644 index 000000000..5a2956b90 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007C.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007D.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007D.gif new file mode 100644 index 000000000..89f2f38a0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007D.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007E.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007E.gif new file mode 100644 index 000000000..9f9b677fc Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007E.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007F.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007F.gif new file mode 100644 index 000000000..e8daaa304 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp/nbgl_font_open_sans_regular_11px_1bpp_0x00007F.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000BF.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000BF.gif new file mode 100644 index 000000000..153220b98 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000BF.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E0.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E0.gif new file mode 100644 index 000000000..bace9e27a Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E0.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E2.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E2.gif new file mode 100644 index 000000000..401a64ea4 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E2.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E8.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E8.gif new file mode 100644 index 000000000..69096ede0 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E8.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E9.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E9.gif new file mode 100644 index 000000000..26794031e Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000E9.gif differ diff --git a/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000EB.gif b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000EB.gif new file mode 100644 index 000000000..25eb9fcd2 Binary files /dev/null and b/lib_nbgl/fonts/nbgl_font_open_sans_regular_11px_1bpp_unicode/nbgl_font_open_sans_regular_11px_1bpp_unicode_0x0000EB.gif differ diff --git a/lib_nbgl/fonts/open_sans_extrabold.ttf b/lib_nbgl/fonts/open_sans_extrabold.ttf new file mode 100644 index 000000000..67fcf0fb2 Binary files /dev/null and b/lib_nbgl/fonts/open_sans_extrabold.ttf differ diff --git a/lib_nbgl/fonts/open_sans_light.ttf b/lib_nbgl/fonts/open_sans_light.ttf new file mode 100644 index 000000000..6580d3a16 Binary files /dev/null and b/lib_nbgl/fonts/open_sans_light.ttf differ diff --git a/lib_nbgl/fonts/open_sans_regular.ttf b/lib_nbgl/fonts/open_sans_regular.ttf new file mode 100644 index 000000000..29bfd35a2 Binary files /dev/null and b/lib_nbgl/fonts/open_sans_regular.ttf differ diff --git a/lib_nbgl/include/nbgl_buttons.h b/lib_nbgl/include/nbgl_buttons.h new file mode 100644 index 000000000..fd008c1e6 --- /dev/null +++ b/lib_nbgl/include/nbgl_buttons.h @@ -0,0 +1,47 @@ +/** + * @file nbgl_buttons.h + * Buttons management of NBGL + * + */ + +#ifndef NBGL_BUTTONS_H +#define NBGL_BUTTONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "nbgl_types.h" +#include "nbgl_obj.h" + +/********************* + * DEFINES + *********************/ +///< Time after the beginning of continuous press on button(s) after which "continuous press" event +///< start to be sent (in 100ms) +#define CONTINOUS_PRESS_THRESHOLD 8 +///< Periodicity of "continuous press" events (in 100ms) +#define CONTINUOUS_PRESS_PERIOD 3 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void nbgl_buttonsHandler(uint8_t buttonState, uint32_t currentTimeMs); +void nbgl_buttonsReset(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* NBGL_BUTTONS_H */ diff --git a/lib_nbgl/include/nbgl_debug.h b/lib_nbgl/include/nbgl_debug.h index 7bc812796..e0a69a887 100644 --- a/lib_nbgl/include/nbgl_debug.h +++ b/lib_nbgl/include/nbgl_debug.h @@ -35,7 +35,9 @@ enum { TOUCH_LOGGER, APP_LOGGER, UX_LOGGER, - MISC_LOGGER + MISC_LOGGER, + STEP_LOGGER, + FLOW_LOGGER }; /********************** * TYPEDEFS diff --git a/lib_nbgl/include/nbgl_draw.h b/lib_nbgl/include/nbgl_draw.h index 0d2792f52..2c52b0b11 100644 --- a/lib_nbgl/include/nbgl_draw.h +++ b/lib_nbgl/include/nbgl_draw.h @@ -39,15 +39,15 @@ void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area, 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); -void nbgl_drawQrCode(const nbgl_area_t *area, - uint8_t version, - const char *text, - color_t backgroundColor); +nbgl_font_id_e nbgl_drawText(const nbgl_area_t *area, + const char *text, + uint16_t textLen, + nbgl_font_id_e fontId, + color_t fontColor); +void nbgl_drawQrCode(const nbgl_area_t *area, + uint8_t version, + const char *text, + color_t backgroundColor); /********************** * MACROS diff --git a/lib_nbgl/include/nbgl_flow.h b/lib_nbgl/include/nbgl_flow.h new file mode 100644 index 000000000..f12c1ae0c --- /dev/null +++ b/lib_nbgl/include/nbgl_flow.h @@ -0,0 +1,86 @@ +/** + * @file nbgl_flow.h + * @brief Flow construction API of NBGL + * + */ + +#ifndef NBGL_FLOW_H +#define NBGL_FLOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "nbgl_step.h" +#include "nbgl_obj.h" +#include "nbgl_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +/** + * @brief type shared externally + * + */ +typedef void *nbgl_flow_t; + +/** + * @brief prototype of function to be called when a step is using a callback on "double-key" action + */ +typedef void (*nbgl_stepCallback_t)(void); + +/** + * @brief Structure containing all specific information when creating a NBGL step. + */ +typedef struct nbgl_stepDesc_s { + nbgl_stepCallback_t init; ///< if not NULL, function to be called when the step is entered + nbgl_stepCallback_t callback; ///< if not NULL, function to be called on "double-key" action + const char *text; ///< text to display in step (can be multi-pages if icon == NULL) + const char *subText; ///< sub-text to display in step (NULL most of the time) + const nbgl_icon_details_t *icon; ///< icon to display in step (text must be single-page) +#ifdef HAVE_LANGUAGE_PACK + UX_LOC_STRINGS_INDEX textId; ///< text Id to display in step (if text field is NULL) +#endif // HAVE_LANGUAGE_PACK +} nbgl_stepDesc_t; + +typedef nbgl_stepDesc_t nbgl_pageContent_t; + +/** + * @brief This structure contains data to build a centered info + long press button page content + */ +typedef struct nbgl_pageInfoLongPress_s { + const char *text; ///< centered text in large case + const nbgl_icon_details_t *icon; ///< a buffer containing the 1BPP icon + const char *longPressText; ///< text of the long press button + uint8_t longPressToken; ///< the token used as argument of the onActionCallback when button is + ///< long pressed +} nbgl_pageInfoLongPress_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +nbgl_flow_t nbgl_flowDraw(const nbgl_stepDesc_t *steps, + uint8_t nbSteps, + uint8_t initStep, + bool loop, + bool modal); +void nbgl_flowRelease(nbgl_flow_t flow); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* NBGL_FLOW_H */ diff --git a/lib_nbgl/include/nbgl_font_hmalpha_mono_medium_32.inc b/lib_nbgl/include/nbgl_font_hmalpha_mono_medium_32.inc index 2e6ed7a9b..305684155 100644 --- a/lib_nbgl/include/nbgl_font_hmalpha_mono_medium_32.inc +++ b/lib_nbgl/include/nbgl_font_hmalpha_mono_medium_32.inc @@ -933,6 +933,7 @@ __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontHMALPHAMONO_MED (uint8_t) NBGL_BPP_4, // bpp 44, // height of all characters in pixels 40, // line height in pixels + 0, // kerning 1, // crop enabled (1) or not (0) 8, // Most top Y coordinate of any char 0x20, // first character diff --git a/lib_nbgl/include/nbgl_font_inter_medium_32.inc b/lib_nbgl/include/nbgl_font_inter_medium_32.inc index 798378859..0e66f0110 100644 --- a/lib_nbgl/include/nbgl_font_inter_medium_32.inc +++ b/lib_nbgl/include/nbgl_font_inter_medium_32.inc @@ -1506,6 +1506,7 @@ __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontINTER_MEDIUM_32 (uint8_t) NBGL_BPP_4, // bpp 40, // height of all characters in pixels 40, // line height in pixels + 0, // kerning 1, // crop enabled (1) or not (0) 8, // Most top Y coordinate of any char 0x20, // first character diff --git a/lib_nbgl/include/nbgl_font_inter_medium_32_1bpp.inc b/lib_nbgl/include/nbgl_font_inter_medium_32_1bpp.inc index e843940ea..530fb7f7d 100644 --- a/lib_nbgl/include/nbgl_font_inter_medium_32_1bpp.inc +++ b/lib_nbgl/include/nbgl_font_inter_medium_32_1bpp.inc @@ -582,6 +582,7 @@ __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontINTER_MEDIUM_32 (uint8_t) NBGL_BPP_1, // bpp 40, // height of all characters in pixels 40, // line height in pixels + 0, // kerning 1, // crop enabled (1) or not (0) 4, // Most top Y coordinate of any char 0x20, // first character diff --git a/lib_nbgl/include/nbgl_font_inter_regular_24.inc b/lib_nbgl/include/nbgl_font_inter_regular_24.inc index 2e3948798..5f5d1ab08 100644 --- a/lib_nbgl/include/nbgl_font_inter_regular_24.inc +++ b/lib_nbgl/include/nbgl_font_inter_regular_24.inc @@ -1070,6 +1070,7 @@ __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontINTER_REGULAR_2 (uint8_t) NBGL_BPP_4, // bpp 32, // height of all characters in pixels 32, // line height in pixels + 0, // kerning 1, // crop enabled (1) or not (0) 4, // Most top Y coordinate of any char 0x20, // first character diff --git a/lib_nbgl/include/nbgl_font_inter_regular_24_1bpp.inc b/lib_nbgl/include/nbgl_font_inter_regular_24_1bpp.inc index 1323997ab..f34ceb190 100644 --- a/lib_nbgl/include/nbgl_font_inter_regular_24_1bpp.inc +++ b/lib_nbgl/include/nbgl_font_inter_regular_24_1bpp.inc @@ -472,6 +472,7 @@ __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontINTER_REGULAR_2 (uint8_t) NBGL_BPP_1, // bpp 32, // height of all characters in pixels 32, // line height in pixels + 0, // kerning 1, // crop enabled (1) or not (0) 4, // Most top Y coordinate of any char 0x20, // first character diff --git a/lib_nbgl/include/nbgl_font_inter_semibold_24.inc b/lib_nbgl/include/nbgl_font_inter_semibold_24.inc index 4530da91a..786340de6 100644 --- a/lib_nbgl/include/nbgl_font_inter_semibold_24.inc +++ b/lib_nbgl/include/nbgl_font_inter_semibold_24.inc @@ -1169,6 +1169,7 @@ __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontINTER_SEMIBOLD_ (uint8_t) NBGL_BPP_4, // bpp 32, // height of all characters in pixels 32, // line height in pixels + 0, // kerning 1, // crop enabled (1) or not (0) 4, // Most top Y coordinate of any char 0x20, // first character diff --git a/lib_nbgl/include/nbgl_font_inter_semibold_24_1bpp.inc b/lib_nbgl/include/nbgl_font_inter_semibold_24_1bpp.inc index f746a4664..5ef864b26 100644 --- a/lib_nbgl/include/nbgl_font_inter_semibold_24_1bpp.inc +++ b/lib_nbgl/include/nbgl_font_inter_semibold_24_1bpp.inc @@ -547,6 +547,7 @@ __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontINTER_SEMIBOLD_ (uint8_t) NBGL_BPP_1, // bpp 32, // height of all characters in pixels 32, // line height in pixels + 0, // kerning 0, // crop enabled (1) or not (0) 0, // Most top Y coordinate of any char 0x20, // first character diff --git a/lib_nbgl/include/nbgl_font_open_sans_extrabold_11.inc b/lib_nbgl/include/nbgl_font_open_sans_extrabold_11.inc new file mode 100644 index 000000000..ac9186a3f --- /dev/null +++ b/lib_nbgl/include/nbgl_font_open_sans_extrabold_11.inc @@ -0,0 +1,333 @@ +#include "nbgl_fonts.h" + +__attribute__ ((section("._nbgl_fonts_"))) const unsigned char bitmapOPEN_SANS_EXTRABOLD_11PX_1BPP[] = { +//ascii 0x0020 +//ascii 0x0021 + 0x05, 0x17, 0x12, +//ascii 0x0022 + 0x01, 0x33, 0x51, 0x33, 0x50, +//ascii 0x0023 + 0x21, 0x11, 0x33, 0x11, 0x56, 0x21, 0x11, 0x35, + 0x51, 0x14, 0x41, 0x30, +//ascii 0x0024 + 0x92, 0x91, 0x31, 0x21, 0x7A, 0x71, 0x22, 0x21, + 0x84, 0x31, 0x92, 0x32, 0x40, +//ascii 0x0025 + 0x43, 0x45, 0x31, 0x33, 0x15, 0x14, 0x64, 0x19, + 0x31, 0x35, 0x43, 0x40, +//ascii 0x0026 + 0x71, 0x44, 0x43, 0x13, 0x2C, 0x22, 0x29, 0x12, + 0x14, 0x51, 0x20, +//ascii 0x0027 + 0x01, 0x33, 0x10, +//ascii 0x0028 + 0x03, 0x43, 0x38, 0x64, 0x10, +//ascii 0x0029 + 0x34, 0x68, 0x33, 0x43, 0x60, +//ascii 0x002A + 0x12, 0x73, 0x35, 0x35, 0x53, 0x42, 0x50, +//ascii 0x002B + 0x31, 0x71, 0x55, 0x35, 0x51, 0x71, 0x40, +//ascii 0x002C + 0x21, 0x73, 0x71, 0x30, +//ascii 0x002D + 0x02, 0x22, 0x22, 0x22, 0x20, +//ascii 0x002E + 0x22, 0x22, +//ascii 0x002F + 0x01, 0x74, 0x64, 0x64, 0x71, +//ascii 0x0030 + 0x16, 0x19, 0x62, 0x69, 0x16, 0x10, +//ascii 0x0031 + 0x0F, 0x01, 0x12, 0x71, 0x50, +//ascii 0x0032 + 0x13, 0x37, 0x12, 0x36, 0x33, 0x11, 0x51, +//ascii 0x0033 + 0x12, 0x13, 0x19, 0x21, 0x32, 0x21, 0x32, 0x61, +//ascii 0x0034 + 0x51, 0x2F, 0x01, 0x12, 0x21, 0x53, 0x71, 0x20, +//ascii 0x0035 + 0x01, 0x26, 0x29, 0x35, 0x31, +//ascii 0x0036 + 0x43, 0x11, 0x26, 0x21, 0x33, 0x11, 0x31, 0x17, + 0x34, 0x10, +//ascii 0x0037 + 0x04, 0x47, 0x11, 0x35, 0x62, 0x70, +//ascii 0x0038 + 0x12, 0x13, 0x19, 0x21, 0x32, 0x21, 0x39, 0x12, + 0x13, 0x10, +//ascii 0x0039 + 0x15, 0x27, 0x11, 0x31, 0x13, 0x31, 0x26, 0x21, + 0x13, 0x40, +//ascii 0x003A + 0x22, 0x22, 0x22, 0x22, +//ascii 0x003B + 0x22, 0x21, 0x72, 0x23, 0xB1, 0x70, +//ascii 0x003C + 0x11, 0x51, 0x12, 0x32, 0x22, 0x12, 0x43, 0x61, + 0x30, +//ascii 0x003D + 0x31, 0x11, 0x51, 0x11, 0x51, 0x11, 0x51, 0x11, + 0x51, 0x11, 0x51, 0x11, 0x20, +//ascii 0x003E + 0x41, 0x63, 0x42, 0x12, 0x22, 0x32, 0x11, 0x51, +//ascii 0x003F + 0x12, 0x54, 0x41, 0x22, 0x13, 0x22, 0x13, 0x70, +//ascii 0x0040 + 0x24, 0x76, 0x11, 0x32, 0x41, 0x11, 0x31, 0x15, + 0x11, 0x31, 0x11, 0x22, 0x11, 0x31, 0x12, 0x21, + 0x11, 0x32, 0x14, 0x11, 0x42, 0x41, 0x66, 0x74, + 0x50, +//ascii 0x0041 + 0x62, 0x35, 0x16, 0x14, 0x11, 0x24, 0x11, 0x36, + 0x45, 0x62, +//ascii 0x0042 + 0x03, 0x1D, 0x21, 0x3F, 0x02, +//ascii 0x0043 + 0x01, 0x62, 0x62, 0x69, 0x16, 0x10, +//ascii 0x0044 + 0x16, 0x19, 0x62, 0x6F, 0x02, +//ascii 0x0045 + 0x01, 0x21, 0x32, 0x21, 0x3F, 0x02, +//ascii 0x0046 + 0x01, 0x71, 0x21, 0x41, 0x21, 0x4F, 0x01, +//ascii 0x0047 + 0x01, 0x26, 0x26, 0x21, 0x32, 0x69, 0x16, 0x10, +//ascii 0x0048 + 0x0F, 0x01, 0x31, 0x71, 0x4F, 0x01, +//ascii 0x0049 + 0x0F, 0x01, +//ascii 0x004A + 0x0A, 0x2B, 0xB1, 0xB1, 0x10, +//ascii 0x004B + 0x01, 0x63, 0x45, 0x14, 0x24, 0x52, 0x3F, 0x01, +//ascii 0x004C + 0x71, 0x71, 0x7F, 0x02, +//ascii 0x004D + 0x0F, 0x06, 0x56, 0x62, 0x2B, 0x3F, 0x01, +//ascii 0x004E + 0x0F, 0x01, 0x44, 0x24, 0x24, 0x4F, 0x01, +//ascii 0x004F + 0x16, 0x19, 0x62, 0x62, 0x69, 0x16, 0x10, +//ascii 0x0050 + 0x05, 0x35, 0x31, 0x31, 0x3F, 0x01, +//ascii 0x0051 + 0x16, 0x21, 0x2A, 0x21, 0x62, 0x31, 0x61, 0x41, + 0x61, 0x48, 0x56, 0x10, +//ascii 0x0052 + 0x71, 0x13, 0x1A, 0x11, 0x31, 0x3F, 0x01, +//ascii 0x0053 + 0x01, 0x42, 0x11, 0x35, 0x2A, 0x21, 0x13, 0x31, +//ascii 0x0054 + 0x01, 0x71, 0x7F, 0x02, 0x71, 0x70, +//ascii 0x0055 + 0x07, 0x18, 0x71, 0x7F, 0x01, 0x10, +//ascii 0x0056 + 0x04, 0x47, 0x54, 0x4B, 0x14, 0x40, +//ascii 0x0057 + 0x01, 0x75, 0x46, 0x6E, 0x58, 0x53, 0x16, 0x15, + 0x31, 0x70, +//ascii 0x0058 + 0x01, 0x63, 0x42, 0x16, 0x34, 0x44, 0x36, 0x12, + 0x43, 0x61, +//ascii 0x0059 + 0x01, 0x73, 0x67, 0x35, 0x13, 0x43, 0x51, 0x70, +//ascii 0x005A + 0x01, 0x64, 0x45, 0x32, 0x14, 0x12, 0x35, 0x44, + 0x61, +//ascii 0x005B + 0x01, 0x81, 0x21, 0x81, 0x2A, 0x2A, 0x20, +//ascii 0x005C + 0x71, 0x44, 0x24, 0x24, 0x41, 0x70, +//ascii 0x005D + 0x0A, 0x2A, 0x21, 0x81, 0x21, 0x81, 0x20, +//ascii 0x005E + 0x41, 0x53, 0x33, 0x53, 0x73, 0x71, 0x30, +//ascii 0x005F + 0x11, 0x31, 0x31, 0x31, 0x31, 0x31, 0x20, +//ascii 0x0060 + 0x41, 0x62, 0x61, 0x40, +//ascii 0x0061 + 0x35, 0x26, 0x21, 0x11, 0x21, 0x21, 0x11, 0x21, + 0x21, 0x14, 0x52, 0x10, +//ascii 0x0062 + 0x42, 0x46, 0x26, 0x21, 0x4F, 0x02, +//ascii 0x0063 + 0x21, 0x41, 0x21, 0x41, 0x21, 0x41, 0x26, 0x34, + 0x52, 0x20, +//ascii 0x0064 + 0x0F, 0x01, 0x21, 0x41, 0x26, 0x34, 0x52, 0x20, +//ascii 0x0065 + 0x32, 0x53, 0x21, 0x21, 0x11, 0x21, 0x21, 0x11, + 0x21, 0x26, 0x34, 0x52, 0x20, +//ascii 0x0066 + 0x01, 0x11, 0x51, 0x11, 0x58, 0x17, 0x21, 0x50, +//ascii 0x0067 + 0x21, 0x52, 0x43, 0x24, 0x34, 0x11, 0x21, 0x31, + 0x21, 0x11, 0x21, 0x36, 0x21, 0x39, 0x92, 0x60, +//ascii 0x0068 + 0x26, 0x26, 0x21, 0x5F, 0x01, +//ascii 0x0069 + 0x01, 0x17, 0x16, +//ascii 0x006A + 0x01, 0x18, 0x21, 0x19, 0xB1, 0xB1, 0x10, +//ascii 0x006B + 0x71, 0x22, 0x22, 0x26, 0x33, 0x2F, 0x01, +//ascii 0x006C + 0x0F, 0x01, +//ascii 0x006D + 0x26, 0x26, 0x21, 0x85, 0x26, 0x21, 0x85, 0x26, +//ascii 0x006E + 0x26, 0x26, 0x21, 0x85, 0x26, +//ascii 0x006F + 0x42, 0x54, 0x36, 0x21, 0x41, 0x26, 0x34, 0x52, + 0x20, +//ascii 0x0070 + 0x42, 0x86, 0x66, 0x61, 0x41, 0x69, 0x39, 0x10, +//ascii 0x0071 + 0x29, 0x39, 0x31, 0x41, 0x66, 0x66, 0x82, 0x60, +//ascii 0x0072 + 0x22, 0x62, 0x75, 0x26, +//ascii 0x0073 + 0x52, 0x31, 0x14, 0x21, 0x12, 0x11, 0x24, 0x11, + 0x23, 0x21, +//ascii 0x0074 + 0x21, 0x41, 0x21, 0x41, 0x17, 0x16, 0x31, 0x50, +//ascii 0x0075 + 0x26, 0x25, 0x81, 0x26, 0x26, +//ascii 0x0076 + 0x21, 0x74, 0x55, 0x62, 0x35, 0x24, 0x41, 0x50, +//ascii 0x0077 + 0x21, 0x74, 0x55, 0x44, 0x24, 0x44, 0x64, 0x35, + 0x24, 0x41, 0x50, +//ascii 0x0078 + 0x21, 0x41, 0x22, 0x22, 0x26, 0x42, 0x46, 0x22, + 0x22, 0x21, 0x41, +//ascii 0x0079 + 0x21, 0xB4, 0x95, 0xA4, 0x58, 0x33, 0x51, 0x31, + 0x50, +//ascii 0x007A + 0x21, 0x41, 0x22, 0x31, 0x24, 0x11, 0x21, 0x14, + 0x21, 0x32, 0x21, 0x41, +//ascii 0x007B + 0x01, 0x81, 0x24, 0x24, 0x2A, 0x62, 0xA2, 0x20, +//ascii 0x007C + 0x0B, 0x1B, 0x10, +//ascii 0x007D + 0x42, 0xA2, 0x6A, 0x24, 0x24, 0x21, 0x81, 0x60, +//ascii 0x007E + 0x32, 0x71, 0x62, 0x62, 0x61, 0x72, 0x30, +}; + + __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_character_t charactersOPEN_SANS_EXTRABOLD_11PX_1BPP[95] = { + { 0, 0, 4,0, 0, 0, 0 }, //asciii 0x0020 + { 1, 0, 4,2, 1, 0, 1 }, //asciii 0x0021 + { 1, 3, 7,2, 1, 0, 2 }, //asciii 0x0022 + { 1, 8, 8,1, 1, 0, 1 }, //asciii 0x0023 + { 1, 20, 7,1, 0, 0, 0 }, //asciii 0x0024 + { 1, 33, 12,1, 1, 1, 1 }, //asciii 0x0025 + { 1, 45, 10,1, 1, 0, 1 }, //asciii 0x0026 + { 1, 56, 4,2, 1, 0, 2 }, //asciii 0x0027 + { 1, 59, 5,1, 1, 1, 0 }, //asciii 0x0028 + { 1, 64, 5,2, 1, 0, 0 }, //asciii 0x0029 + { 1, 69, 7,1, 1, 0, 1 }, //asciii 0x002A + { 1, 76, 7,1, 1, 0, 1 }, //asciii 0x002B + { 1, 83, 4,1, 2, 0, 0 }, //asciii 0x002C + { 1, 87, 5,1, 2, 0, 1 }, //asciii 0x002D + { 1, 92, 4,2, 2, 0, 1 }, //asciii 0x002E + { 1, 94, 6,1, 1, 0, 1 }, //asciii 0x002F + { 1, 99, 9,2, 1, 1, 1 }, //asciii 0x0030 + { 1, 105, 7,2, 1, 1, 1 }, //asciii 0x0031 + { 1, 110, 8,2, 1, 1, 1 }, //asciii 0x0032 + { 1, 117, 8,2, 1, 1, 1 }, //asciii 0x0033 + { 1, 125, 9,2, 1, 1, 1 }, //asciii 0x0034 + { 1, 133, 7,2, 1, 1, 1 }, //asciii 0x0035 + { 1, 138, 9,2, 1, 1, 1 }, //asciii 0x0036 + { 1, 148, 8,2, 1, 1, 1 }, //asciii 0x0037 + { 1, 154, 9,2, 1, 1, 1 }, //asciii 0x0038 + { 1, 164, 9,2, 1, 1, 1 }, //asciii 0x0039 + { 1, 174, 4,2, 1, 0, 1 }, //asciii 0x003A + { 1, 178, 4,1, 1, 0, 0 }, //asciii 0x003B + { 1, 184, 6,1, 1, 0, 1 }, //asciii 0x003C + { 1, 193, 7,1, 1, 0, 1 }, //asciii 0x003D + { 1, 206, 6,1, 1, 0, 1 }, //asciii 0x003E + { 1, 214, 7,1, 1, 1, 1 }, //asciii 0x003F + { 1, 222, 11,1, 1, 0, 0 }, //asciii 0x0040 + { 1, 247, 9,1, 1, 0, 1 }, //asciii 0x0041 + { 1, 257, 8,2, 1, 1, 1 }, //asciii 0x0042 + { 1, 262, 8,2, 1, 1, 1 }, //asciii 0x0043 + { 1, 268, 9,2, 1, 1, 1 }, //asciii 0x0044 + { 1, 273, 7,2, 1, 1, 1 }, //asciii 0x0045 + { 1, 279, 7,2, 1, 0, 1 }, //asciii 0x0046 + { 1, 286, 9,2, 1, 1, 1 }, //asciii 0x0047 + { 1, 294, 9,2, 1, 1, 1 }, //asciii 0x0048 + { 1, 300, 5,2, 1, 1, 1 }, //asciii 0x0049 + { 1, 302, 5,0, 1, 1, 0 }, //asciii 0x004A + { 1, 307, 9,2, 1, 0, 1 }, //asciii 0x004B + { 1, 315, 7,2, 1, 0, 1 }, //asciii 0x004C + { 1, 319, 12,2, 1, 1, 1 }, //asciii 0x004D + { 1, 326, 10,2, 1, 1, 1 }, //asciii 0x004E + { 1, 333, 10,2, 1, 1, 1 }, //asciii 0x004F + { 1, 340, 8,2, 1, 1, 1 }, //asciii 0x0050 + { 1, 346, 10,2, 1, 1, 0 }, //asciii 0x0051 + { 1, 358, 9,2, 1, 1, 1 }, //asciii 0x0052 + { 1, 365, 7,2, 1, 0, 1 }, //asciii 0x0053 + { 1, 373, 7,1, 1, 0, 1 }, //asciii 0x0054 + { 1, 379, 9,2, 1, 1, 1 }, //asciii 0x0055 + { 1, 385, 7,1, 1, 0, 1 }, //asciii 0x0056 + { 1, 391, 12,1, 1, 0, 1 }, //asciii 0x0057 + { 1, 401, 9,1, 1, 0, 1 }, //asciii 0x0058 + { 1, 411, 8,1, 1, 0, 1 }, //asciii 0x0059 + { 1, 419, 8,1, 1, 0, 1 }, //asciii 0x005A + { 1, 428, 6,2, 1, 0, 0 }, //asciii 0x005B + { 1, 435, 6,1, 1, 0, 1 }, //asciii 0x005C + { 1, 441, 6,1, 1, 1, 0 }, //asciii 0x005D + { 1, 448, 7,0, 1, 1, 1 }, //asciii 0x005E + { 1, 455, 7,0, 3, 1, 0 }, //asciii 0x005F + { 1, 462, 8,3, 0, 2, 2 }, //asciii 0x0060 + { 1, 466, 8,1, 1, 1, 1 }, //asciii 0x0061 + { 1, 478, 8,2, 1, 0, 1 }, //asciii 0x0062 + { 1, 484, 7,1, 1, 0, 1 }, //asciii 0x0063 + { 1, 494, 8,1, 1, 1, 1 }, //asciii 0x0064 + { 1, 502, 8,1, 1, 0, 1 }, //asciii 0x0065 + { 1, 515, 7,1, 1, 1, 1 }, //asciii 0x0066 + { 1, 523, 8,1, 1, 0, 0 }, //asciii 0x0067 + { 1, 539, 8,2, 1, 1, 1 }, //asciii 0x0068 + { 1, 544, 5,2, 1, 1, 1 }, //asciii 0x0069 + { 1, 547, 5,0, 1, 1, 0 }, //asciii 0x006A + { 1, 554, 8,2, 1, 0, 1 }, //asciii 0x006B + { 1, 561, 5,2, 1, 1, 1 }, //asciii 0x006C + { 1, 563, 11,2, 1, 1, 1 }, //asciii 0x006D + { 1, 571, 8,2, 1, 1, 1 }, //asciii 0x006E + { 1, 576, 8,1, 1, 0, 1 }, //asciii 0x006F + { 1, 585, 8,2, 1, 0, 0 }, //asciii 0x0070 + { 1, 593, 8,1, 1, 1, 0 }, //asciii 0x0071 + { 1, 601, 6,2, 1, 0, 1 }, //asciii 0x0072 + { 1, 605, 7,2, 1, 0, 1 }, //asciii 0x0073 + { 1, 615, 6,1, 1, 0, 1 }, //asciii 0x0074 + { 1, 623, 8,2, 1, 1, 1 }, //asciii 0x0075 + { 1, 628, 8,1, 1, 0, 1 }, //asciii 0x0076 + { 1, 636, 11,1, 1, 0, 1 }, //asciii 0x0077 + { 1, 647, 8,1, 1, 0, 1 }, //asciii 0x0078 + { 1, 658, 8,1, 1, 0, 0 }, //asciii 0x0079 + { 1, 667, 7,1, 1, 0, 1 }, //asciii 0x007A + { 1, 679, 6,1, 1, 0, 0 }, //asciii 0x007B + { 1, 687, 7,3, 1, 2, 0 }, //asciii 0x007C + { 1, 690, 6,1, 1, 0, 0 }, //asciii 0x007D + { 1, 698, 7,1, 1, 0, 1 }, //asciii 0x007E +}; + +__attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontOPEN_SANS_EXTRABOLD_11PX_1BPP= { + 705, // bitmap len + BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp, // font id + (uint8_t) NBGL_BPP_1, // bpp + 16, // height of all characters in pixels + 14, // line height in pixels + 1, // kerning + 1, // crop enabled (1) or not (0) + 0, // Most top Y coordinate of any char + 0x20, // first character + 0x7E, // last character + charactersOPEN_SANS_EXTRABOLD_11PX_1BPP, + bitmapOPEN_SANS_EXTRABOLD_11PX_1BPP +}; diff --git a/lib_nbgl/include/nbgl_font_open_sans_light_16.inc b/lib_nbgl/include/nbgl_font_open_sans_light_16.inc new file mode 100644 index 000000000..ce5959b37 --- /dev/null +++ b/lib_nbgl/include/nbgl_font_open_sans_light_16.inc @@ -0,0 +1,375 @@ +#include "nbgl_fonts.h" + +__attribute__ ((section("._nbgl_fonts_"))) const unsigned char bitmapOPEN_SANS_LIGHT_16PX_1BPP[] = { +//ascii 0x0020 +//ascii 0x0021 + 0x08, 0x22, 0x40, +//ascii 0x0022 + 0x04, 0x84, +//ascii 0x0023 + 0x41, 0xB1, 0x21, 0x45, 0x21, 0x86, 0x61, 0x21, + 0x24, 0x21, 0x21, 0x66, 0x81, 0x25, 0x41, 0x21, + 0xB1, 0x40, +//ascii 0x0024 + 0x82, 0x71, 0x51, 0x21, 0x61, 0x42, 0x31, 0x4D, + 0x41, 0x41, 0x41, 0x61, 0x21, 0x51, 0x72, 0x51, + 0x50, +//ascii 0x0025 + 0x65, 0x61, 0x52, 0x41, 0x51, 0x12, 0x35, 0x42, + 0xC2, 0xC2, 0x45, 0x32, 0x11, 0x51, 0x42, 0x51, + 0x65, 0x20, +//ascii 0x0026 + 0x63, 0x21, 0x92, 0x91, 0x11, 0x23, 0x31, 0x32, + 0x31, 0x11, 0x42, 0x41, 0x52, 0x32, 0x51, 0x13, + 0x21, 0x32, 0x74, 0x50, +//ascii 0x0027 + 0x04, 0x40, +//ascii 0x0028 + 0x02, 0xB2, 0x3B, 0x30, +//ascii 0x0029 + 0x2B, 0x32, 0xB2, 0x10, +//ascii 0x002A + 0x61, 0xB1, 0x21, 0x83, 0x64, 0xB3, 0x91, 0x21, + 0x81, 0x10, +//ascii 0x002B + 0x41, 0x71, 0x71, 0x47, 0x41, 0x71, 0x71, 0x30, +//ascii 0x002C + 0x23, 0x81, 0x20, +//ascii 0x002D + 0x31, 0x31, 0x31, 0x40, +//ascii 0x002E + 0x22, 0x22, +//ascii 0x002F + 0x01, 0xC3, 0xC4, 0xC3, 0xC1, 0x40, +//ascii 0x0030 + 0x28, 0x31, 0x81, 0x11, 0xA2, 0xA2, 0xA1, 0x11, + 0x81, 0x38, 0x60, +//ascii 0x0031 + 0xCC, 0x11, 0xC1, 0x10, +//ascii 0x0032 + 0xB1, 0x15, 0x52, 0x51, 0x42, 0x61, 0x32, 0x71, + 0x22, 0x81, 0x11, 0x11, 0x82, 0x40, +//ascii 0x0033 + 0x21, 0x43, 0x31, 0x12, 0x11, 0x31, 0x11, 0x32, + 0x52, 0x41, 0x52, 0x41, 0x52, 0x41, 0x51, 0x11, + 0x91, 0x40, +//ascii 0x0034 + 0x81, 0xB1, 0x3C, 0x11, 0x61, 0x51, 0x51, 0x62, + 0x31, 0x81, 0x21, 0x93, 0xB1, 0x70, +//ascii 0x0035 + 0x64, 0x21, 0x51, 0x31, 0x11, 0x41, 0x52, 0x41, + 0x52, 0x41, 0x55, 0x11, 0x51, 0x42, 0x41, 0x50, +//ascii 0x0036 + 0x65, 0x11, 0x41, 0x52, 0x41, 0x52, 0x41, 0x51, + 0x11, 0x31, 0x51, 0x12, 0x31, 0x31, 0x47, 0x60, +//ascii 0x0037 + 0x02, 0xA1, 0x13, 0x71, 0x42, 0x51, 0x63, 0x21, + 0x93, 0xB1, 0x70, +//ascii 0x0038 + 0x22, 0x34, 0x21, 0x21, 0x11, 0x42, 0x41, 0x52, + 0x41, 0x52, 0x41, 0x51, 0x11, 0x21, 0x11, 0x41, + 0x22, 0x34, 0x50, +//ascii 0x0039 + 0x27, 0x41, 0x31, 0x32, 0x11, 0x51, 0x31, 0x11, + 0x51, 0x42, 0x51, 0x42, 0x51, 0x41, 0x15, 0x20, +//ascii 0x003A + 0x32, 0x52, 0x32, 0x52, +//ascii 0x003B + 0x32, 0xE2, 0x53, 0x30, +//ascii 0x003C + 0x21, 0x51, 0x61, 0x31, 0x71, 0x31, 0x81, 0x11, + 0x91, 0x11, 0xA1, 0xB1, 0x20, +//ascii 0x003D + 0x01, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, + 0x40, +//ascii 0x003E + 0x51, 0xB1, 0xA1, 0x11, 0x91, 0x11, 0x81, 0x31, + 0x71, 0x31, 0x61, 0x51, 0x70, +//ascii 0x003F + 0x14, 0x71, 0x41, 0x61, 0x51, 0x51, 0x62, 0x13, + 0x70, +//ascii 0x0040 + 0x36, 0x91, 0x61, 0x71, 0x71, 0x61, 0x27, 0x61, + 0x21, 0x41, 0x41, 0x21, 0x21, 0x51, 0x31, 0x21, + 0x21, 0x51, 0x31, 0x21, 0x31, 0x41, 0x31, 0x31, + 0x34, 0x41, 0x31, 0xA1, 0x52, 0x71, 0x87, 0x50, +//ascii 0x0041 + 0xB1, 0x83, 0x72, 0x73, 0x11, 0x43, 0x41, 0x43, + 0x41, 0x73, 0x11, 0xA2, 0xC3, 0xC1, +//ascii 0x0042 + 0x22, 0x33, 0x31, 0x21, 0x11, 0x31, 0x11, 0x41, + 0x52, 0x41, 0x52, 0x41, 0x52, 0x41, 0x5D, 0x40, +//ascii 0x0043 + 0x01, 0xA2, 0xA2, 0xA2, 0xA2, 0xA1, 0x11, 0x81, + 0x31, 0x61, 0x56, 0x30, +//ascii 0x0044 + 0x36, 0x51, 0x61, 0x31, 0x81, 0x11, 0xA2, 0xA2, + 0xA2, 0xAD, +//ascii 0x0045 + 0x01, 0x41, 0x52, 0x41, 0x52, 0x41, 0x52, 0x41, + 0x52, 0x41, 0x5D, +//ascii 0x0046 + 0x01, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, + 0x51, 0x51, 0x5C, +//ascii 0x0047 + 0x65, 0x11, 0x51, 0x42, 0x51, 0x42, 0x51, 0x42, + 0x51, 0x42, 0xA2, 0xA1, 0x11, 0x81, 0x31, 0x61, + 0x56, 0x30, +//ascii 0x0048 + 0x0C, 0x51, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0x6C, +//ascii 0x0049 + 0x0C, 0x40, +//ascii 0x004A + 0x0E, 0xF0, 0x11, 0xF1, 0x10, +//ascii 0x004B + 0x01, 0xA1, 0x11, 0x81, 0x31, 0x52, 0x51, 0x31, + 0x81, 0x11, 0xA1, 0x6C, 0x40, +//ascii 0x004C + 0xB1, 0xB1, 0xB1, 0xB1, 0xBD, +//ascii 0x004D + 0x0C, 0x13, 0xC3, 0xC2, 0xC2, 0xA2, 0x82, 0x73, + 0x72, 0x8C, +//ascii 0x004E + 0x0C, 0x92, 0x91, 0x92, 0x91, 0x92, 0x82, 0x9C, +//ascii 0x004F + 0x36, 0x51, 0x61, 0x31, 0x81, 0x11, 0xA2, 0xA2, + 0xA2, 0xA1, 0x11, 0x81, 0x31, 0x61, 0x56, 0x30, +//ascii 0x0050 + 0x15, 0x61, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, + 0x51, 0x5C, +//ascii 0x0051 + 0x36, 0x91, 0x61, 0x41, 0x21, 0x81, 0x22, 0x11, + 0xA2, 0x31, 0xA1, 0x41, 0xA1, 0x41, 0xA1, 0x51, + 0x81, 0x71, 0x61, 0x96, 0x70, +//ascii 0x0052 + 0x23, 0x52, 0x11, 0x31, 0x31, 0x21, 0x53, 0x31, + 0x51, 0x51, 0x51, 0x51, 0x51, 0x5C, 0x40, +//ascii 0x0053 + 0x11, 0x54, 0x11, 0x51, 0x42, 0x51, 0x42, 0x41, + 0x52, 0x41, 0x52, 0x41, 0x51, 0x14, 0x61, 0x40, +//ascii 0x0054 + 0x01, 0xB1, 0xB1, 0xBD, 0xB1, 0xB1, 0x70, +//ascii 0x0055 + 0x0A, 0xC1, 0xC1, 0xB1, 0xB1, 0xB1, 0xA1, 0x1A, + 0x20, +//ascii 0x0056 + 0x02, 0xC3, 0xC3, 0xC2, 0xC2, 0x82, 0x73, 0x63, + 0x72, 0x60, +//ascii 0x0057 + 0x01, 0xC4, 0xC4, 0xC3, 0x74, 0x44, 0x53, 0x93, + 0xC4, 0xC4, 0xA3, 0x54, 0x44, 0x71, 0x30, +//ascii 0x0058 + 0xB3, 0x81, 0x32, 0x42, 0x61, 0x12, 0x91, 0x92, + 0x12, 0x61, 0x52, 0x22, 0x81, 0xC1, 0x40, +//ascii 0x0059 + 0x01, 0xC2, 0xC2, 0xC7, 0x52, 0x82, 0x82, 0x91, + 0x30, +//ascii 0x005A + 0x02, 0x92, 0x12, 0x72, 0x31, 0x62, 0x42, 0x42, + 0x61, 0x32, 0x72, 0x12, 0x92, 0x40, +//ascii 0x005B + 0x01, 0xD1, 0x11, 0xD1, 0x11, 0xD1, 0x1F, 0x10, +//ascii 0x005C + 0xB1, 0x83, 0x54, 0x53, 0x81, 0x70, +//ascii 0x005D + 0x0F, 0x11, 0xD1, 0x11, 0xD1, 0x11, 0xD1, 0x10, +//ascii 0x005E + 0x52, 0x42, 0x42, 0x51, 0x82, 0x82, 0x82, 0x10, +//ascii 0x005F + 0x11, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x60, +//ascii 0x0060 + 0x51, 0x61, 0x61, 0x40, +//ascii 0x0061 + 0x48, 0x31, 0x31, 0x21, 0x41, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x83, 0x10, +//ascii 0x0062 + 0x95, 0xA1, 0x51, 0x81, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x81, 0x51, 0x4D, +//ascii 0x0063 + 0x31, 0x71, 0x31, 0x71, 0x31, 0x71, 0x31, 0x71, + 0x41, 0x51, 0x65, 0x20, +//ascii 0x0064 + 0x3D, 0x81, 0x51, 0x81, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x81, 0x51, 0xA5, 0x20, +//ascii 0x0065 + 0x53, 0x21, 0x51, 0x21, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x41, 0x21, + 0x21, 0x65, 0x60, +//ascii 0x0066 + 0x31, 0xF1, 0x31, 0xB1, 0x31, 0xCC, 0x71, 0xF1, +//ascii 0x0067 + 0x31, 0x91, 0x51, 0x12, 0x42, 0x11, 0x42, 0x22, + 0x21, 0x31, 0x31, 0x41, 0x21, 0x31, 0x31, 0x41, + 0x21, 0x31, 0x31, 0x42, 0x11, 0x31, 0x44, 0x21, + 0x11, 0x12, 0xD2, 0x10, +//ascii 0x0068 + 0x97, 0x81, 0xE1, 0xF1, 0xF1, 0xF0, 0x11, 0xAD, +//ascii 0x0069 + 0x11, 0x28, 0x40, +//ascii 0x006A + 0x11, 0x2C, 0xF1, 0xF1, +//ascii 0x006B + 0xF1, 0x71, 0x61, 0x91, 0x41, 0xB1, 0x21, 0xD2, + 0xF0, 0x11, 0x6D, +//ascii 0x006C + 0x3D, +//ascii 0x006D + 0x57, 0x41, 0xA1, 0xB1, 0xB1, 0xC8, 0x41, 0xA1, + 0xB1, 0xB1, 0xC1, 0xA9, +//ascii 0x006E + 0x57, 0x41, 0xA1, 0xB1, 0xB1, 0xC1, 0xA9, 0x40, +//ascii 0x006F + 0x55, 0x61, 0x51, 0x41, 0x71, 0x31, 0x71, 0x31, + 0x71, 0x41, 0x51, 0x65, 0x60, +//ascii 0x0070 + 0x55, 0xA1, 0x51, 0x81, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x81, 0x51, 0x8D, +//ascii 0x0071 + 0x3D, 0x41, 0x51, 0x81, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x81, 0x51, 0xA5, 0x60, +//ascii 0x0072 + 0x31, 0xB1, 0xB1, 0xC1, 0xA9, 0x40, +//ascii 0x0073 + 0x31, 0x43, 0x41, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x21, 0x41, 0x43, 0x41, 0x40, +//ascii 0x0074 + 0xB1, 0x31, 0x71, 0x31, 0x71, 0x29, 0x41, 0x40, +//ascii 0x0075 + 0x39, 0xA1, 0xC1, 0xB1, 0xB1, 0xA2, 0x37, 0x60, +//ascii 0x0076 + 0x32, 0xC3, 0xC3, 0xC1, 0x83, 0x63, 0x72, 0x30, +//ascii 0x0077 + 0x31, 0xC4, 0xC2, 0xB3, 0x63, 0x63, 0x93, 0xC3, + 0xC3, 0x82, 0x64, 0x71, +//ascii 0x0078 + 0x32, 0x52, 0x51, 0x31, 0x83, 0x93, 0x81, 0x31, + 0x52, 0x52, +//ascii 0x0079 + 0x32, 0xF0, 0x13, 0xF0, 0x13, 0xF0, 0x12, 0xB3, + 0x22, 0x63, 0x71, 0x32, 0xA1, +//ascii 0x007A + 0x32, 0x61, 0x31, 0x12, 0x41, 0x31, 0x31, 0x31, + 0x31, 0x42, 0x11, 0x31, 0x62, 0x40, +//ascii 0x007B + 0x01, 0xD1, 0x11, 0xD1, 0x26, 0x16, 0x91, 0xF1, +//ascii 0x007C + 0xF0, 0x8F, 0x02, +//ascii 0x007D + 0x71, 0xF1, 0xA5, 0x15, 0x32, 0xB2, 0x11, 0xD1, + 0x10, +//ascii 0x007E + 0x21, 0x31, 0x31, 0x31, 0x21, 0x31, 0x31, 0x60, +}; + + __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_character_t charactersOPEN_SANS_LIGHT_16PX_1BPP[95] = { + { 0, 0, 6,0, 0, 0, 0 }, //asciii 0x0020 + { 1, 0, 5,3, 1, 1, 1 }, //asciii 0x0021 + { 1, 3, 8,3, 1, 1, 3 }, //asciii 0x0022 + { 1, 5, 12,2, 1, 0, 1 }, //asciii 0x0023 + { 1, 23, 11,3, 1, 1, 0 }, //asciii 0x0024 + { 1, 40, 15,3, 1, 1, 1 }, //asciii 0x0025 + { 1, 58, 13,3, 1, 1, 1 }, //asciii 0x0026 + { 1, 78, 5,3, 1, 1, 3 }, //asciii 0x0027 + { 1, 80, 6,3, 1, 1, 0 }, //asciii 0x0028 + { 1, 84, 6,3, 1, 1, 0 }, //asciii 0x0029 + { 1, 88, 11,3, 0, 1, 2 }, //asciii 0x002A + { 1, 98, 11,3, 1, 1, 2 }, //asciii 0x002B + { 1, 106, 5,2, 3, 1, 0 }, //asciii 0x002C + { 1, 109, 7,3, 2, 1, 2 }, //asciii 0x002D + { 1, 113, 6,3, 3, 1, 1 }, //asciii 0x002E + { 1, 115, 8,2, 1, 1, 1 }, //asciii 0x002F + { 1, 121, 11,3, 1, 1, 1 }, //asciii 0x0030 + { 1, 132, 11,4, 1, 3, 1 }, //asciii 0x0031 + { 1, 136, 11,3, 1, 1, 1 }, //asciii 0x0032 + { 1, 150, 11,3, 1, 1, 1 }, //asciii 0x0033 + { 1, 168, 11,2, 1, 0, 1 }, //asciii 0x0034 + { 1, 182, 11,3, 1, 1, 1 }, //asciii 0x0035 + { 1, 198, 11,3, 1, 1, 1 }, //asciii 0x0036 + { 1, 214, 11,3, 1, 1, 1 }, //asciii 0x0037 + { 1, 225, 11,3, 1, 1, 1 }, //asciii 0x0038 + { 1, 244, 11,3, 1, 1, 1 }, //asciii 0x0039 + { 1, 260, 6,3, 1, 1, 1 }, //asciii 0x003A + { 1, 264, 6,3, 1, 1, 0 }, //asciii 0x003B + { 1, 268, 11,3, 1, 1, 1 }, //asciii 0x003C + { 1, 281, 11,3, 2, 1, 2 }, //asciii 0x003D + { 1, 290, 11,3, 1, 1, 1 }, //asciii 0x003E + { 1, 303, 9,3, 1, 1, 1 }, //asciii 0x003F + { 1, 312, 13,0, 1, 1, 0 }, //asciii 0x0040 + { 1, 344, 12,2, 1, 0, 1 }, //asciii 0x0041 + { 1, 358, 12,4, 1, 1, 1 }, //asciii 0x0042 + { 1, 374, 12,3, 1, 1, 1 }, //asciii 0x0043 + { 1, 386, 13,4, 1, 1, 1 }, //asciii 0x0044 + { 1, 396, 11,4, 1, 1, 1 }, //asciii 0x0045 + { 1, 407, 10,4, 1, 0, 1 }, //asciii 0x0046 + { 1, 418, 14,3, 1, 1, 1 }, //asciii 0x0047 + { 1, 436, 14,4, 1, 2, 1 }, //asciii 0x0048 + { 1, 444, 6,4, 1, 1, 1 }, //asciii 0x0049 + { 1, 446, 6,0, 1, 3, 0 }, //asciii 0x004A + { 1, 451, 11,4, 1, 0, 1 }, //asciii 0x004B + { 1, 464, 10,4, 1, 0, 1 }, //asciii 0x004C + { 1, 469, 14,2, 1, 2, 1 }, //asciii 0x004D + { 1, 479, 14,4, 1, 2, 1 }, //asciii 0x004E + { 1, 487, 14,3, 1, 1, 1 }, //asciii 0x004F + { 1, 503, 11,4, 1, 1, 1 }, //asciii 0x0050 + { 1, 513, 14,3, 1, 1, 0 }, //asciii 0x0051 + { 1, 534, 12,4, 1, 1, 1 }, //asciii 0x0052 + { 1, 549, 11,3, 1, 1, 1 }, //asciii 0x0053 + { 1, 565, 9,2, 1, 0, 1 }, //asciii 0x0054 + { 1, 572, 14,4, 1, 2, 1 }, //asciii 0x0055 + { 1, 581, 12,2, 1, 1, 1 }, //asciii 0x0056 + { 1, 591, 15,1, 1, 0, 1 }, //asciii 0x0057 + { 1, 606, 11,2, 1, 0, 1 }, //asciii 0x0058 + { 1, 621, 11,2, 1, 1, 1 }, //asciii 0x0059 + { 1, 630, 11,3, 1, 1, 1 }, //asciii 0x005A + { 1, 644, 7,3, 1, 0, 0 }, //asciii 0x005B + { 1, 652, 8,2, 1, 1, 1 }, //asciii 0x005C + { 1, 658, 7,2, 1, 1, 0 }, //asciii 0x005D + { 1, 666, 11,3, 1, 1, 2 }, //asciii 0x005E + { 1, 674, 9,1, 4, 1, 0 }, //asciii 0x005F + { 1, 682, 11,5, 0, 3, 3 }, //asciii 0x0060 + { 1, 686, 10,3, 1, 1, 1 }, //asciii 0x0061 + { 1, 701, 12,3, 0, 1, 1 }, //asciii 0x0062 + { 1, 715, 10,3, 1, 1, 1 }, //asciii 0x0063 + { 1, 727, 12,3, 0, 1, 1 }, //asciii 0x0064 + { 1, 742, 11,3, 1, 1, 1 }, //asciii 0x0065 + { 1, 761, 8,2, 0, 0, 1 }, //asciii 0x0066 + { 1, 769, 10,2, 1, 0, 0 }, //asciii 0x0067 + { 1, 797, 11,3, 0, 1, 1 }, //asciii 0x0068 + { 1, 805, 6,3, 1, 2, 1 }, //asciii 0x0069 + { 1, 808, 7,2, 1, 2, 0 }, //asciii 0x006A + { 1, 812, 10,3, 0, 0, 1 }, //asciii 0x006B + { 1, 823, 6,3, 0, 2, 1 }, //asciii 0x006C + { 1, 824, 14,1, 1, 1, 1 }, //asciii 0x006D + { 1, 836, 11,3, 1, 1, 1 }, //asciii 0x006E + { 1, 844, 11,3, 1, 1, 1 }, //asciii 0x006F + { 1, 857, 12,3, 1, 1, 0 }, //asciii 0x0070 + { 1, 871, 12,3, 1, 1, 0 }, //asciii 0x0071 + { 1, 886, 8,3, 1, 0, 1 }, //asciii 0x0072 + { 1, 892, 9,3, 1, 1, 1 }, //asciii 0x0073 + { 1, 906, 7,2, 1, 0, 1 }, //asciii 0x0074 + { 1, 914, 11,3, 1, 1, 1 }, //asciii 0x0075 + { 1, 922, 10,2, 1, 1, 1 }, //asciii 0x0076 + { 1, 930, 14,2, 1, 0, 1 }, //asciii 0x0077 + { 1, 942, 10,3, 1, 1, 1 }, //asciii 0x0078 + { 1, 952, 10,2, 1, 1, 0 }, //asciii 0x0079 + { 1, 965, 9,3, 1, 1, 1 }, //asciii 0x007A + { 1, 979, 8,2, 1, 1, 0 }, //asciii 0x007B + { 1, 987, 8,3, 0, 3, 0 }, //asciii 0x007C + { 1, 990, 8,3, 1, 0, 0 }, //asciii 0x007D + { 1, 999, 11,3, 2, 1, 2 }, //asciii 0x007E +}; + +__attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontOPEN_SANS_LIGHT_16PX_1BPP= { + 1007, // bitmap len + BAGL_FONT_OPEN_SANS_LIGHT_16px_1bpp, // font id + (uint8_t) NBGL_BPP_1, // bpp + 24, // height of all characters in pixels + 21, // line height in pixels + 2, // kerning + 1, // crop enabled (1) or not (0) + 4, // Most top Y coordinate of any char + 0x20, // first character + 0x7E, // last character + charactersOPEN_SANS_LIGHT_16PX_1BPP, + bitmapOPEN_SANS_LIGHT_16PX_1BPP +}; diff --git a/lib_nbgl/include/nbgl_font_open_sans_regular_11.inc b/lib_nbgl/include/nbgl_font_open_sans_regular_11.inc new file mode 100644 index 000000000..e369f52c9 --- /dev/null +++ b/lib_nbgl/include/nbgl_font_open_sans_regular_11.inc @@ -0,0 +1,336 @@ +#include "nbgl_fonts.h" + +__attribute__ ((section("._nbgl_fonts_"))) const unsigned char bitmapOPEN_SANS_REGULAR_11PX_1BPP[] = { +//ascii 0x0020 +//ascii 0x0021 + 0x06, 0x11, +//ascii 0x0022 + 0x02, 0x22, 0x20, +//ascii 0x0023 + 0x21, 0x53, 0x21, 0x45, 0x31, 0x21, 0x35, 0x41, + 0x23, 0x51, 0x20, +//ascii 0x0024 + 0x11, 0x33, 0x17, 0x11, 0x21, 0x21, 0x13, 0x31, +//ascii 0x0025 + 0x36, 0x21, 0x31, 0x12, 0x13, 0x42, 0x43, 0x12, + 0x11, 0x31, 0x26, 0x30, +//ascii 0x0026 + 0x42, 0x11, 0x61, 0x13, 0x21, 0x12, 0x22, 0x22, + 0x21, 0x31, 0x12, 0x14, +//ascii 0x0027 + 0x02, 0x60, +//ascii 0x0028 + 0x03, 0x43, 0x54, 0x50, +//ascii 0x0029 + 0x34, 0x53, 0x43, 0x20, +//ascii 0x002A + 0x21, 0x71, 0x11, 0x52, 0x44, 0x61, 0x11, 0x51, + 0x50, +//ascii 0x002B + 0x41, 0x71, 0x63, 0x61, 0x71, 0x71, 0x30, +//ascii 0x002C + 0x32, 0x81, 0x20, +//ascii 0x002D + 0x11, 0x31, 0x20, +//ascii 0x002E + 0x31, 0x40, +//ascii 0x002F + 0x01, 0x83, 0x83, 0x81, +//ascii 0x0030 + 0x16, 0x11, 0x62, 0x61, 0x16, 0x10, +//ascii 0x0031 + 0x09, 0x81, 0x60, +//ascii 0x0032 + 0x13, 0x32, 0x31, 0x22, 0x41, 0x12, 0x52, +//ascii 0x0033 + 0x12, 0x13, 0x11, 0x21, 0x32, 0x21, 0x32, 0x61, +//ascii 0x0034 + 0x51, 0x28, 0x11, 0x31, 0x41, 0x21, 0x53, 0x71, + 0x20, +//ascii 0x0035 + 0x01, 0x24, 0x11, 0x21, 0x32, 0x21, 0x35, 0x31, +//ascii 0x0036 + 0x01, 0x24, 0x11, 0x21, 0x32, 0x21, 0x31, 0x16, + 0x10, +//ascii 0x0037 + 0x03, 0x51, 0x22, 0x31, 0x44, 0x70, +//ascii 0x0038 + 0x12, 0x13, 0x11, 0x21, 0x32, 0x21, 0x31, 0x12, + 0x13, 0x10, +//ascii 0x0039 + 0x16, 0x11, 0x31, 0x22, 0x31, 0x21, 0x14, 0x21, +//ascii 0x003A + 0x21, 0x41, +//ascii 0x003B + 0x21, 0x42, 0xC1, 0x20, +//ascii 0x003C + 0x11, 0x41, 0x31, 0x21, 0x52, 0x62, 0x30, +//ascii 0x003D + 0x31, 0x11, 0x51, 0x11, 0x51, 0x11, 0x51, 0x11, + 0x20, +//ascii 0x003E + 0x32, 0x62, 0x51, 0x21, 0x31, 0x41, 0x10, +//ascii 0x003F + 0x12, 0x51, 0x21, 0x41, 0x32, 0x12, 0x70, +//ascii 0x0040 + 0x16, 0x51, 0x51, 0x51, 0x15, 0x11, 0x31, 0x11, + 0x31, 0x11, 0x31, 0x11, 0x31, 0x11, 0x31, 0x24, + 0x11, 0x41, 0x61, 0x56, 0x40, +//ascii 0x0041 + 0x71, 0x43, 0x23, 0x11, 0x21, 0x41, 0x33, 0x11, + 0x63, 0x81, +//ascii 0x0042 + 0x03, 0x15, 0x21, 0x32, 0x21, 0x32, 0x21, 0x39, +//ascii 0x0043 + 0x01, 0x62, 0x62, 0x63, 0x42, 0x16, 0x10, +//ascii 0x0044 + 0x16, 0x11, 0x62, 0x62, 0x62, 0x69, +//ascii 0x0045 + 0x01, 0x21, 0x32, 0x21, 0x32, 0x21, 0x39, +//ascii 0x0046 + 0x01, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x38, +//ascii 0x0047 + 0x01, 0x35, 0x31, 0x22, 0x62, 0x62, 0x61, 0x16, + 0x10, +//ascii 0x0048 + 0x08, 0x31, 0x71, 0x71, 0x71, 0x48, +//ascii 0x0049 + 0x08, +//ascii 0x004A + 0x09, 0xC1, 0xB1, 0x60, +//ascii 0x004B + 0x72, 0x51, 0x21, 0x31, 0x41, 0x11, 0x61, 0x48, +//ascii 0x004C + 0x71, 0x71, 0x71, 0x79, +//ascii 0x004D + 0x0B, 0x82, 0x83, 0x53, 0x32, 0x33, 0x58, +//ascii 0x004E + 0x08, 0x61, 0x52, 0x42, 0x51, 0x68, +//ascii 0x004F + 0x16, 0x11, 0x62, 0x62, 0x62, 0x62, 0x61, 0x16, + 0x10, +//ascii 0x0050 + 0x13, 0x41, 0x31, 0x31, 0x31, 0x31, 0x31, 0x38, +//ascii 0x0051 + 0x16, 0x51, 0x61, 0x11, 0x21, 0x62, 0x31, 0x61, + 0x41, 0x61, 0x41, 0x61, 0x56, 0x10, +//ascii 0x0052 + 0x13, 0x23, 0x32, 0x21, 0x31, 0x31, 0x31, 0x38, +//ascii 0x0053 + 0x01, 0x33, 0x11, 0x31, 0x22, 0x21, 0x31, 0x13, + 0x31, +//ascii 0x0054 + 0x01, 0x71, 0x79, 0x71, 0x70, +//ascii 0x0055 + 0x07, 0x81, 0x71, 0x71, 0x78, 0x10, +//ascii 0x0056 + 0x01, 0x83, 0x83, 0x81, 0x43, 0x23, 0x41, 0x70, +//ascii 0x0057 + 0x01, 0x85, 0x82, 0x33, 0x23, 0x53, 0x83, 0x82, + 0x15, 0x21, 0x70, +//ascii 0x0058 + 0x01, 0x61, 0x11, 0x32, 0x33, 0x53, 0x41, 0x32, + 0x11, 0x61, +//ascii 0x0059 + 0x01, 0x82, 0x85, 0x31, 0x52, 0x51, 0x70, +//ascii 0x005A + 0x02, 0x52, 0x12, 0x32, 0x31, 0x22, 0x43, +//ascii 0x005B + 0x01, 0x81, 0x21, 0x81, 0x2A, 0x60, +//ascii 0x005C + 0x71, 0x43, 0x23, 0x41, 0x70, +//ascii 0x005D + 0x0A, 0x21, 0x81, 0x21, 0x81, 0x60, +//ascii 0x005E + 0x41, 0x52, 0x42, 0x62, 0x82, 0x81, 0x30, +//ascii 0x005F + 0x11, 0x31, 0x31, 0x31, 0x31, 0x60, +//ascii 0x0060 + 0x41, 0x61, 0x40, +//ascii 0x0061 + 0x26, 0x21, 0x11, 0x21, 0x21, 0x11, 0x21, 0x21, + 0x14, +//ascii 0x0062 + 0x34, 0x31, 0x41, 0x21, 0x41, 0x21, 0x49, +//ascii 0x0063 + 0x21, 0x41, 0x21, 0x41, 0x21, 0x41, 0x34, 0x10, +//ascii 0x0064 + 0x08, 0x21, 0x41, 0x21, 0x41, 0x21, 0x41, 0x34, + 0x10, +//ascii 0x0065 + 0x23, 0x21, 0x21, 0x11, 0x21, 0x21, 0x11, 0x21, + 0x34, 0x10, +//ascii 0x0066 + 0x01, 0x11, 0x51, 0x11, 0x67, 0x21, 0x50, +//ascii 0x0067 + 0x21, 0x52, 0x43, 0x21, 0x21, 0x31, 0x21, 0x11, + 0x21, 0x31, 0x21, 0x11, 0x21, 0x36, 0x21, 0x92, + 0x20, +//ascii 0x0068 + 0x35, 0x21, 0x71, 0x71, 0x58, +//ascii 0x0069 + 0x01, 0x16, +//ascii 0x006A + 0x01, 0x19, 0xB1, 0xB1, 0x50, +//ascii 0x006B + 0x21, 0x32, 0x31, 0x11, 0x61, 0x38, +//ascii 0x006C + 0x08, +//ascii 0x006D + 0x26, 0x21, 0x71, 0x85, 0x21, 0x71, 0x71, 0x76, +//ascii 0x006E + 0x35, 0x21, 0x71, 0x71, 0x76, +//ascii 0x006F + 0x34, 0x31, 0x41, 0x21, 0x41, 0x21, 0x41, 0x34, + 0x10, +//ascii 0x0070 + 0x34, 0x71, 0x41, 0x61, 0x41, 0x61, 0x41, 0x69, + 0x50, +//ascii 0x0071 + 0x29, 0x31, 0x41, 0x61, 0x41, 0x61, 0x41, 0x74, + 0x10, +//ascii 0x0072 + 0x21, 0x71, 0x76, +//ascii 0x0073 + 0x61, 0x31, 0x21, 0x11, 0x21, 0x11, 0x21, 0x23, + 0x21, +//ascii 0x0074 + 0x21, 0x41, 0x21, 0x41, 0x17, 0x21, 0x50, +//ascii 0x0075 + 0x26, 0x71, 0x71, 0x71, 0x26, +//ascii 0x0076 + 0x21, 0x83, 0x82, 0x62, 0x33, 0x41, 0x50, +//ascii 0x0077 + 0x21, 0x83, 0x82, 0x33, 0x41, 0x83, 0x82, 0x33, + 0x41, 0x50, +//ascii 0x0078 + 0x22, 0x22, 0x42, 0x62, 0x42, 0x22, +//ascii 0x0079 + 0x21, 0xC3, 0xC2, 0xA4, 0x53, 0x41, 0x31, 0x71, + 0x10, +//ascii 0x007A + 0x21, 0x41, 0x22, 0x31, 0x21, 0x12, 0x11, 0x21, + 0x32, 0x21, 0x41, +//ascii 0x007B + 0x01, 0x81, 0x24, 0x24, 0x62, 0x20, +//ascii 0x007C + 0x0B, 0x50, +//ascii 0x007D + 0x42, 0x64, 0x24, 0x21, 0x81, 0x60, +//ascii 0x007E + 0x41, 0x71, 0x61, 0x71, 0x40, +}; + + __attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_character_t charactersOPEN_SANS_REGULAR_11PX_1BPP[95] = { + { 0, 0, 4,0, 0, 0, 0 }, //asciii 0x0020 + { 1, 0, 4,2, 1, 1, 1 }, //asciii 0x0021 + { 1, 2, 5,2, 1, 1, 2 }, //asciii 0x0022 + { 1, 5, 8,1, 1, 0, 1 }, //asciii 0x0023 + { 1, 16, 7,2, 1, 1, 1 }, //asciii 0x0024 + { 1, 24, 10,2, 1, 1, 1 }, //asciii 0x0025 + { 1, 36, 10,2, 1, 2, 1 }, //asciii 0x0026 + { 1, 48, 3,2, 1, 0, 2 }, //asciii 0x0027 + { 1, 50, 4,1, 1, 1, 0 }, //asciii 0x0028 + { 1, 54, 4,2, 1, 0, 0 }, //asciii 0x0029 + { 1, 58, 7,1, 1, 0, 1 }, //asciii 0x002A + { 1, 67, 7,1, 1, 0, 1 }, //asciii 0x002B + { 1, 74, 4,1, 2, 1, 0 }, //asciii 0x002C + { 1, 77, 5,2, 2, 1, 1 }, //asciii 0x002D + { 1, 80, 4,2, 2, 1, 1 }, //asciii 0x002E + { 1, 82, 5,1, 1, 0, 1 }, //asciii 0x002F + { 1, 86, 7,2, 1, 1, 1 }, //asciii 0x0030 + { 1, 92, 7,2, 1, 2, 1 }, //asciii 0x0031 + { 1, 95, 7,2, 1, 1, 1 }, //asciii 0x0032 + { 1, 102, 7,2, 1, 1, 1 }, //asciii 0x0033 + { 1, 110, 9,2, 1, 1, 1 }, //asciii 0x0034 + { 1, 119, 7,2, 1, 1, 1 }, //asciii 0x0035 + { 1, 127, 7,2, 1, 1, 1 }, //asciii 0x0036 + { 1, 136, 7,2, 1, 1, 1 }, //asciii 0x0037 + { 1, 142, 7,2, 1, 1, 1 }, //asciii 0x0038 + { 1, 152, 7,2, 1, 1, 1 }, //asciii 0x0039 + { 1, 160, 4,2, 1, 1, 1 }, //asciii 0x003A + { 1, 162, 4,1, 1, 1, 0 }, //asciii 0x003B + { 1, 166, 7,2, 1, 1, 1 }, //asciii 0x003C + { 1, 173, 7,2, 1, 1, 1 }, //asciii 0x003D + { 1, 182, 7,2, 1, 1, 1 }, //asciii 0x003E + { 1, 189, 6,2, 1, 0, 1 }, //asciii 0x003F + { 1, 196, 11,2, 1, 1, 0 }, //asciii 0x0040 + { 1, 217, 8,1, 1, 0, 1 }, //asciii 0x0041 + { 1, 227, 8,2, 1, 1, 1 }, //asciii 0x0042 + { 1, 235, 8,2, 1, 1, 1 }, //asciii 0x0043 + { 1, 242, 9,2, 1, 1, 1 }, //asciii 0x0044 + { 1, 248, 7,2, 1, 1, 1 }, //asciii 0x0045 + { 1, 255, 7,2, 1, 0, 1 }, //asciii 0x0046 + { 1, 264, 9,2, 1, 1, 1 }, //asciii 0x0047 + { 1, 273, 9,2, 1, 1, 1 }, //asciii 0x0048 + { 1, 279, 4,2, 1, 1, 1 }, //asciii 0x0049 + { 1, 280, 4,0, 1, 1, 0 }, //asciii 0x004A + { 1, 284, 8,2, 1, 0, 1 }, //asciii 0x004B + { 1, 292, 7,2, 1, 0, 1 }, //asciii 0x004C + { 1, 296, 11,2, 1, 1, 1 }, //asciii 0x004D + { 1, 303, 9,2, 1, 1, 1 }, //asciii 0x004E + { 1, 309, 10,2, 1, 1, 1 }, //asciii 0x004F + { 1, 318, 8,2, 1, 1, 1 }, //asciii 0x0050 + { 1, 326, 10,2, 1, 1, 0 }, //asciii 0x0051 + { 1, 340, 8,2, 1, 1, 1 }, //asciii 0x0052 + { 1, 348, 7,2, 1, 1, 1 }, //asciii 0x0053 + { 1, 357, 8,2, 1, 1, 1 }, //asciii 0x0054 + { 1, 362, 9,2, 1, 1, 1 }, //asciii 0x0055 + { 1, 368, 8,1, 1, 0, 1 }, //asciii 0x0056 + { 1, 376, 11,1, 1, 0, 1 }, //asciii 0x0057 + { 1, 387, 8,1, 1, 1, 1 }, //asciii 0x0058 + { 1, 397, 7,1, 1, 0, 1 }, //asciii 0x0059 + { 1, 404, 7,2, 1, 1, 1 }, //asciii 0x005A + { 1, 411, 5,2, 1, 0, 0 }, //asciii 0x005B + { 1, 417, 5,1, 1, 0, 1 }, //asciii 0x005C + { 1, 422, 5,1, 1, 1, 0 }, //asciii 0x005D + { 1, 428, 7,1, 1, 0, 1 }, //asciii 0x005E + { 1, 435, 6,0, 3, 1, 0 }, //asciii 0x005F + { 1, 441, 7,3, 0, 2, 2 }, //asciii 0x0060 + { 1, 444, 7,2, 1, 1, 1 }, //asciii 0x0061 + { 1, 453, 8,2, 1, 1, 1 }, //asciii 0x0062 + { 1, 460, 6,2, 1, 0, 1 }, //asciii 0x0063 + { 1, 468, 8,2, 1, 1, 1 }, //asciii 0x0064 + { 1, 477, 7,2, 1, 1, 1 }, //asciii 0x0065 + { 1, 487, 6,1, 1, 1, 1 }, //asciii 0x0066 + { 1, 494, 7,1, 1, 0, 0 }, //asciii 0x0067 + { 1, 511, 8,2, 1, 1, 1 }, //asciii 0x0068 + { 1, 516, 4,2, 1, 1, 1 }, //asciii 0x0069 + { 1, 518, 4,0, 1, 1, 0 }, //asciii 0x006A + { 1, 523, 7,2, 1, 1, 1 }, //asciii 0x006B + { 1, 529, 4,2, 1, 1, 1 }, //asciii 0x006C + { 1, 530, 11,2, 1, 1, 1 }, //asciii 0x006D + { 1, 538, 8,2, 1, 1, 1 }, //asciii 0x006E + { 1, 543, 8,2, 1, 1, 1 }, //asciii 0x006F + { 1, 552, 8,2, 1, 1, 0 }, //asciii 0x0070 + { 1, 561, 8,2, 1, 1, 0 }, //asciii 0x0071 + { 1, 570, 5,2, 1, 0, 1 }, //asciii 0x0072 + { 1, 573, 6,2, 1, 0, 1 }, //asciii 0x0073 + { 1, 582, 5,1, 1, 0, 1 }, //asciii 0x0074 + { 1, 589, 8,2, 1, 1, 1 }, //asciii 0x0075 + { 1, 594, 7,1, 1, 0, 1 }, //asciii 0x0076 + { 1, 601, 10,1, 1, 0, 1 }, //asciii 0x0077 + { 1, 611, 7,2, 1, 1, 1 }, //asciii 0x0078 + { 1, 617, 7,1, 1, 0, 0 }, //asciii 0x0079 + { 1, 626, 6,1, 1, 0, 1 }, //asciii 0x007A + { 1, 637, 5,2, 1, 0, 0 }, //asciii 0x007B + { 1, 643, 7,4, 1, 2, 0 }, //asciii 0x007C + { 1, 645, 5,1, 1, 1, 0 }, //asciii 0x007D + { 1, 651, 7,2, 1, 1, 1 }, //asciii 0x007E +}; + +__attribute__ ((section("._nbgl_fonts_"))) const nbgl_font_t fontOPEN_SANS_REGULAR_11PX_1BPP= { + 656, // bitmap len + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, // font id + (uint8_t) NBGL_BPP_1, // bpp + 16, // height of all characters in pixels + 14, // line height in pixels + 1, // kerning + 1, // crop enabled (1) or not (0) + 0, // Most top Y coordinate of any char + 0x20, // first character + 0x7E, // last character + charactersOPEN_SANS_REGULAR_11PX_1BPP, + bitmapOPEN_SANS_REGULAR_11PX_1BPP +}; diff --git a/lib_nbgl/include/nbgl_font_rom.inc b/lib_nbgl/include/nbgl_font_rom.inc index 58982a502..b330f4f26 100644 --- a/lib_nbgl/include/nbgl_font_rom.inc +++ b/lib_nbgl/include/nbgl_font_rom.inc @@ -16,6 +16,7 @@ * limitations under the License. ********************************************************************************/ +#ifdef HAVE_SE_TOUCH #include "nbgl_font_hmalpha_mono_medium_32.inc" #include "nbgl_font_inter_regular_24.inc" #include "nbgl_font_inter_semibold_24.inc" @@ -23,6 +24,11 @@ #include "nbgl_font_inter_regular_24_1bpp.inc" #include "nbgl_font_inter_semibold_24_1bpp.inc" #include "nbgl_font_inter_medium_32_1bpp.inc" +#else // HAVE_SE_TOUCH +#include "nbgl_font_open_sans_extrabold_11.inc" +#include "nbgl_font_open_sans_regular_11.inc" +#include "nbgl_font_open_sans_light_16.inc" +#endif // HAVE_SE_TOUCH #if (defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP)) #if !defined(HAVE_LANGUAGE_PACK) #if (OS_LANGUAGE==LANG_ENGLISH) diff --git a/lib_nbgl/include/nbgl_font_rom_struct.inc b/lib_nbgl/include/nbgl_font_rom_struct.inc index 3d039dedd..cc2680f3c 100644 --- a/lib_nbgl/include/nbgl_font_rom_struct.inc +++ b/lib_nbgl/include/nbgl_font_rom_struct.inc @@ -43,3 +43,15 @@ #ifdef HAVE_BAGL_FONT_INTER_MEDIUM_32PX &fontINTER_MEDIUM_32PX_1BPP, #endif // HAVE_BAGL_FONT_INTER_MEDIUM_32PX + +#ifdef HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX + &fontOPEN_SANS_EXTRABOLD_11PX_1BPP, +#endif // HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX + +#ifdef HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX + &fontOPEN_SANS_LIGHT_16PX_1BPP, +#endif // HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX + +#ifdef HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX + &fontOPEN_SANS_REGULAR_11PX_1BPP, +#endif // HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX diff --git a/lib_nbgl/include/nbgl_fonts.h b/lib_nbgl/include/nbgl_fonts.h index 240bd5498..f79e9b3d1 100644 --- a/lib_nbgl/include/nbgl_fonts.h +++ b/lib_nbgl/include/nbgl_fonts.h @@ -47,13 +47,14 @@ typedef struct { * */ typedef struct { - uint32_t bitmap_len; ///< Size in bytes of the associated bitmap - uint8_t font_id; ///< ID of the font, from @ref nbgl_font_id_e - uint8_t bpp; ///< number of bits per pixels - uint8_t height; ///< height of all characters in pixels - uint8_t line_height; ///< height of a line for all characters in pixels - uint8_t crop; ///< If false, x_min_offset+y_min_offset=bytes to skip - uint8_t y_min; ///< Most top Y coordinate of any char in the font + uint32_t bitmap_len; ///< Size in bytes of the associated bitmap + uint8_t font_id; ///< ID of the font, from @ref nbgl_font_id_e + uint8_t bpp; ///< number of bits per pixels + uint8_t height; ///< height of all characters in pixels + uint8_t line_height; ///< height of a line for all characters in pixels + uint8_t char_kerning; ///< kerning for the font + uint8_t crop; ///< If false, x_min_offset+y_min_offset=bytes to skip + uint8_t y_min; ///< Most top Y coordinate of any char in the font uint8_t first_char; ///< ASCII code of the first character in \b bitmap and in \b characters fields uint8_t @@ -88,13 +89,15 @@ typedef struct { * */ typedef struct { - uint16_t bitmap_len; ///< Size in bytes of all characters bitmaps - uint8_t font_id; ///< ID of the font, from @ref nbgl_font_id_e - uint8_t bpp; ///< Number of bits per pixels, (interpreted as nbgl_bpp_t) - uint8_t height; ///< height of all characters in pixels - uint8_t line_height; ///< height of a line for all characters in pixels - uint8_t crop; ///< If false, x_min_offset+y_min_offset=bytes to skip - uint8_t y_min; ///< Most top Y coordinate of any char in the font + uint16_t bitmap_len; ///< Size in bytes of all characters bitmaps + uint8_t font_id; ///< ID of the font, from @ref nbgl_font_id_e + uint8_t bpp; ///< Number of bits per pixels, (interpreted as nbgl_bpp_t) + uint8_t height; ///< height of all characters in pixels + uint8_t line_height; ///< height of a line for all characters in pixels + uint8_t char_kerning; ///< kerning for the font + uint8_t crop; ///< If false, x_min_offset+y_min_offset=bytes to skip + uint8_t y_min; ///< Most top Y coordinate of any char in the font + uint8_t unused[3]; ///< for alignment #if !defined(HAVE_LANGUAGE_PACK) // When using language packs, those 2 pointers does not exists const nbgl_font_unicode_character_t @@ -111,6 +114,9 @@ typedef enum { BAGL_FONT_INTER_REGULAR_24px_1bpp, BAGL_FONT_INTER_SEMIBOLD_24px_1bpp, BAGL_FONT_INTER_MEDIUM_32px_1bpp, + BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp = 8u, // validated on nano s + BAGL_FONT_OPEN_SANS_LIGHT_16px_1bpp = 9u, // validated on nano s + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp = 10u, // validated on nano s, BAGL_FONT_LAST // MUST ALWAYS BE THE LAST, FOR AUTOMATED INVALID VALUE CHECKS } nbgl_font_id_e; @@ -158,8 +164,13 @@ bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t maxNbLines, - uint16_t *len); + uint16_t *len, + bool wrapping); void nbgl_textWrapOnNbLines(nbgl_font_id_e fontId, char *text, uint16_t maxWidth, uint8_t nbLines); +uint8_t nbgl_getTextNbPagesInWidth(nbgl_font_id_e fontId, + const char *text, + uint8_t nbLinesPerPage, + uint16_t maxWidth); uint32_t nbgl_popUnicodeChar(const uint8_t **text, uint16_t *text_length, bool *is_unicode); #ifdef HAVE_UNICODE_SUPPORT diff --git a/lib_nbgl/include/nbgl_layout.h b/lib_nbgl/include/nbgl_layout.h index a77bed124..0c72d990d 100644 --- a/lib_nbgl/include/nbgl_layout.h +++ b/lib_nbgl/include/nbgl_layout.h @@ -28,12 +28,28 @@ extern "C" { #define NB_MAX_SUGGESTION_BUTTONS 4 +#ifdef HAVE_SE_TOUCH +#define AVAILABLE_WIDTH (SCREEN_WIDTH - 2 * BORDER_MARGIN) +#else // HAVE_SE_TOUCH +// 7 pixels on each side +#define AVAILABLE_WIDTH (SCREEN_WIDTH - 2 * 7) +// maximum number of lines in screen +#define NB_MAX_LINES 4 + +#endif // HAVE_SE_TOUCH + /********************** * TYPEDEFS **********************/ /** - * @brief prototype of function to be called an object is touched + * @brief type shared externally + * + */ +typedef void *nbgl_layout_t; + +/** + * @brief prototype of function to be called when an object is touched * @param token integer passed when registering callback * @param index when the object touched is a list of radio buttons, gives the index of the activated * button @@ -41,10 +57,11 @@ extern "C" { typedef void (*nbgl_layoutTouchCallback_t)(int token, uint8_t index); /** - * @brief type shared externally - * + * @brief prototype of function to be called when buttons are touched on a screen + * @param layout layout concerned by the event + * @param event type of button event */ -typedef void *nbgl_layout_t; +typedef void (*nbgl_layoutButtonCallback_t)(nbgl_layout_t *layout, nbgl_buttonEvent_t event); /** * @brief This structure contains info to build a navigation bar at the bottom of the screen @@ -59,9 +76,40 @@ typedef struct { ///< navigation keys or in the center if no navigation bool withSeparationLine; ///< if set to true, an horizontal line is drawn on top of bar in ///< light gray +#ifdef HAVE_PIEZO_SOUND tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when pressing keys) +#endif // HAVE_PIEZO_SOUND } nbgl_layoutNavigationBar_t; +/** + * @brief possible directions for Navigation arrows + * + */ +typedef enum { + HORIZONTAL_NAV, ///< '<' and '>' are displayed, to navigate between pages and steps + VERTICAL_NAV ///< '\/' and '/\' are displayed, to navigate in a list (vertical scrolling) +} nbgl_layoutNavDirection_t; + +/** + * @brief possible styles for Navigation arrows (it's a bit field) + * + */ +typedef enum { + NO_ARROWS = 0, + LEFT_ARROW, ///< left arrow is used + RIGHT_ARROW, ///< right arrow is used +} nbgl_layoutNavIndication_t; + +/** + * @brief This structure contains info to build a navigation bar at the bottom of the screen + * @note this widget is incompatible with a footer. + * + */ +typedef struct { + nbgl_layoutNavDirection_t direction; ///< vertical or horizontal navigation + nbgl_layoutNavIndication_t indication; ///< specifies which arrows to use (left or right) +} nbgl_layoutNavigation_t; + /** * @brief Structure containing all information when creating a layout. This structure must be passed * as argument to @ref nbgl_layoutGet @@ -71,15 +119,22 @@ typedef struct { typedef struct nbgl_layoutDescription_s { bool modal; ///< if true, puts the layout on top of screen stack (modal). Otherwise puts on ///< background (for apps) +#ifdef HAVE_SE_TOUCH bool withLeftBorder; ///< if true, draws a light gray left border on the whole height of the ///< screen const char *tapActionText; ///< Light gray text used when main container is "tapable" uint8_t tapActionToken; ///< the token that will be used as argument of the onActionCallback ///< when main container is "tapped" - tune_index_e tapTuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when tapping on - ///< main container +#ifdef HAVE_PIEZO_SOUND + tune_index_e tapTuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when tapping on + ///< main container +#endif // HAVE_PIEZO_SOUND nbgl_layoutTouchCallback_t onActionCallback; ///< the callback to be called on any action on the layout +#else // HAVE_SE_TOUCH + nbgl_layoutButtonCallback_t + onActionCallback; ///< the callback to be called on any action on the layout +#endif // HAVE_SE_TOUCH nbgl_screenTickerConfiguration_t ticker; // configuration of ticker (timeout) } nbgl_layoutDescription_t; @@ -93,11 +148,13 @@ typedef struct { const char *text; ///< text (can be NULL) const nbgl_icon_details_t *iconRight; ///< a buffer containing the 1BPP icon for icon 2 (can be ///< NULL). Dimensions must be the same as iconLeft - const char *subText; ///< sub text (can be NULL) - uint8_t token; ///< the token that will be used as argument of the callback - bool inactive; ///< if set to true, the bar is grayed-out and cannot be touched - bool centered; ///< if set to true, the text is centered horizontaly in the bar - tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played + const char *subText; ///< sub text (can be NULL) + uint8_t token; ///< the token that will be used as argument of the callback + bool inactive; ///< if set to true, the bar is grayed-out and cannot be touched + bool centered; ///< if set to true, the text is centered horizontaly in the bar +#ifdef HAVE_PIEZO_SOUND + tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played +#endif // HAVE_PIEZO_SOUND } nbgl_layoutBar_t; /** @@ -111,7 +168,9 @@ typedef struct { *subText; ///< description under main text (NULL terminated, single line, may be null) nbgl_state_t initState; ///< initial state of the switch uint8_t token; ///< the token that will be used as argument of the callback - tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played +#ifdef HAVE_PIEZO_SOUND + tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played +#endif // HAVE_PIEZO_SOUND } nbgl_layoutSwitch_t; /** @@ -130,12 +189,31 @@ typedef struct { uint8_t nbChoices; ///< number of choices uint8_t initChoice; ///< index of the current choice uint8_t token; ///< the token that will be used as argument of the callback +#ifdef HAVE_PIEZO_SOUND tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when selecting a radio button) +#endif // HAVE_PIEZO_SOUND } nbgl_layoutRadioChoice_t; /** - * @brief This structure contains a [tag,value] pair + * @brief prototype of menu list item retrieval callback + * @param choiceIndex index of the menu list item to retrieve (from 0 (to nbChoices-1)) + * @return a pointer on a string + */ +typedef const char *(*nbgl_menuListCallback_t)(uint8_t choiceIndex); + +/** + * @brief This structure contains a list of names to build a menu list on Nanos, with for each item + * a description (names array) + */ +typedef struct { + nbgl_menuListCallback_t callback; ///< function to call to retrieve a menu list item text + uint8_t nbChoices; ///< total number of choices in the menu list + uint8_t selectedChoice; ///< index of the selected choice (centered, in bold) +} nbgl_layoutMenuList_t; + +/** + * @brief This structure contains a [tag,value] pair */ typedef struct { const char *item; ///< string giving the tag name @@ -175,6 +253,7 @@ typedef struct { * */ typedef enum { +#ifdef HAVE_SE_TOUCH LARGE_CASE_INFO, ///< text in BLACK and large case (INTER 32px), subText in black in Inter24px LARGE_CASE_BOLD_INFO, ///< text in BLACK and large case (INTER 32px), subText in black bold ///< Inter24px, text3 in black Inter24px @@ -184,6 +263,10 @@ typedef enum { PLUGIN_INFO ///< A potential text in black 32px, a potential text in black (24px) under it, a ///< small horizontal line under it, a potential icon under it, a potential text in ///< black (24px) under it +#else // HAVE_SE_TOUCH + REGULAR_INFO = 0, ///< both texts regular (but '\\b' can switch to bold) + BOLD_TEXT1_INFO ///< bold is used for text1 (but '\\b' can switch to regular) +#endif // HAVE_SE_TOUCH } nbgl_centeredInfoStyle_t; /** @@ -192,13 +275,17 @@ typedef enum { * */ typedef struct { - const char *text1; ///< first text (can be null) - const char *text2; ///< second text (can be null) - const char *text3; ///< third text (can be null) + const char *text1; ///< first text (can be null) + const char *text2; ///< second text (can be null) +#ifdef HAVE_SE_TOUCH + const char *text3; ///< third text (can be null) +#endif // HAVE_SE_TOUCH const nbgl_icon_details_t *icon; ///< a buffer containing the 1BPP icon bool onTop; ///< if set to true, align only horizontaly nbgl_centeredInfoStyle_t style; ///< style to apply to this info +#ifdef HAVE_SE_TOUCH int16_t offsetY; ///< vertical shift to apply to this info (if >0, shift to bottom) +#endif // HAVE_SE_TOUCH } nbgl_layoutCenteredInfo_t; /** @@ -234,8 +321,10 @@ typedef struct { const char *topText; ///< up-button text (index 0) const char *bottomText; ///< bottom-button text (index 1) uint8_t token; ///< the token that will be used as argument of the callback - nbgl_layoutChoiceButtonsStyle_t style; ///< the style of the pair - tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played + nbgl_layoutChoiceButtonsStyle_t style; ///< the style of the pair +#ifdef HAVE_PIEZO_SOUND + tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played +#endif // HAVE_PIEZO_SOUND } nbgl_layoutChoiceButtons_t; /** @@ -261,7 +350,9 @@ typedef struct { bool fittingContent; ///< if set to true, fit the width of button to text, otherwise full width bool onBottom; ///< if set to true, align on bottom of page, otherwise put on bottom of ///< previous object +#ifdef HAVE_PIEZO_SOUND tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played +#endif // HAVE_PIEZO_SOUND } nbgl_layoutButton_t; /** @@ -280,20 +371,29 @@ typedef struct { * */ typedef struct { - bool lettersOnly; ///< if true, only display letter keys and Backspace - keyboardCase_t casing; ///< keyboard casing mode (lower, upper once or upper locked) - keyboardMode_t mode; ///< keyboard mode to start with uint32_t keyMask; ///< mask used to disable some keys in letters only mod. The 26 LSB bits of ///< mask are used, for the 26 letters of a QWERTY keyboard. Bit[0] for Q, ///< Bit[1] for W and so on - keyboardCallback_t callback; ///< function called when an active key is pressed + keyboardCallback_t callback; ///< function called when an active key is pressed + bool lettersOnly; ///< if true, only display letter keys and Backspace + keyboardMode_t mode; ///< keyboard mode to start with +#ifdef HAVE_SE_TOUCH + keyboardCase_t casing; ///< keyboard casing mode (lower, upper once or upper locked) +#else // HAVE_SE_TOUCH + bool enableBackspace; ///< if true, Backspace key is enabled + bool enableValidate; ///< if true, Validate key is enabled + uint8_t selectedCharIndex; +#endif // HAVE_SE_TOUCH } nbgl_layoutKbd_t; /********************** * GLOBAL PROTOTYPES **********************/ nbgl_layout_t *nbgl_layoutGet(const nbgl_layoutDescription_t *description); +int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredInfo_t *info); +int nbgl_layoutAddProgressBar(nbgl_layout_t *layout, const nbgl_layoutProgressBar_t *barLayout); +#ifdef HAVE_SE_TOUCH int nbgl_layoutAddTopRightButton(nbgl_layout_t *layout, const nbgl_icon_details_t *icon, uint8_t token, @@ -302,11 +402,9 @@ int nbgl_layoutAddTouchableBar(nbgl_layout_t *layout, const nbgl_layoutBar_t *ba int nbgl_layoutAddSwitch(nbgl_layout_t *layout, const nbgl_layoutSwitch_t *switchLayout); int nbgl_layoutAddText(nbgl_layout_t *layout, const char *text, const char *subText); int nbgl_layoutAddRadioChoice(nbgl_layout_t *layout, const nbgl_layoutRadioChoice_t *choices); -int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredInfo_t *info); int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info); int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceButtons_t *info); int nbgl_layoutAddTagValueList(nbgl_layout_t *layout, const nbgl_layoutTagValueList_t *list); -int nbgl_layoutAddProgressBar(nbgl_layout_t *layout, const nbgl_layoutProgressBar_t *barLayout); int nbgl_layoutAddLargeCaseText(nbgl_layout_t *layout, const char *text); int nbgl_layoutAddSeparationLine(nbgl_layout_t *layout); @@ -338,10 +436,19 @@ int nbgl_layoutAddProgressIndicator(nbgl_layout_t *layout, uint8_t backToken, tune_index_e tuneId); int nbgl_layoutAddSpinner(nbgl_layout_t *layout, const char *text, bool fixed); +#else // HAVE_SE_TOUCH +int nbgl_layoutAddText(nbgl_layout_t *layout, + const char *text, + const char *subText, + nbgl_centeredInfoStyle_t style); +int nbgl_layoutAddNavigation(nbgl_layout_t *layout, nbgl_layoutNavigation_t *info); +int nbgl_layoutAddMenuList(nbgl_layout_t *layout, nbgl_layoutMenuList_t *list); +#endif // HAVE_SE_TOUCH #ifdef NBGL_KEYBOARD /* layout objects for page with keyboard */ -int nbgl_layoutAddKeyboard(nbgl_layout_t *layout, const nbgl_layoutKbd_t *kbdInfo); +int nbgl_layoutAddKeyboard(nbgl_layout_t *layout, const nbgl_layoutKbd_t *kbdInfo); +#ifdef HAVE_SE_TOUCH int nbgl_layoutUpdateKeyboard(nbgl_layout_t *layout, uint8_t index, uint32_t keyMask, @@ -379,10 +486,16 @@ int nbgl_layoutUpdateConfirmationButton(nbgl_layout_t *layout, uint8_t index, bool active, const char *text); +#else // HAVE_SE_TOUCH +int nbgl_layoutUpdateKeyboard(nbgl_layout_t *layout, uint8_t index, uint32_t keyMask); +int nbgl_layoutAddEnteredText(nbgl_layout_t *layout, const char *text, bool lettersOnly); +int nbgl_layoutUpdateEnteredText(nbgl_layout_t *layout, uint8_t index, const char *text); +#endif // HAVE_SE_TOUCH #endif // NBGL_KEYBOARD #ifdef NBGL_KEYPAD -/* layout objects for page with keypad */ +#ifdef HAVE_SE_TOUCH +/* layout objects for page with keypad (Stax) */ int nbgl_layoutAddKeypad(nbgl_layout_t *layout, keyboardCallback_t callback, bool shuffled); int nbgl_layoutUpdateKeypad(nbgl_layout_t *layout, uint8_t index, @@ -391,6 +504,19 @@ int nbgl_layoutUpdateKeypad(nbgl_layout_t *layout, bool enableDigits); int nbgl_layoutAddHiddenDigits(nbgl_layout_t *layout, uint8_t nbDigits); int nbgl_layoutUpdateHiddenDigits(nbgl_layout_t *layout, uint8_t index, uint8_t nbActive); +#else // HAVE_SE_TOUCH +/* layout objects for pages with keypad (nanos) */ +int nbgl_layoutAddKeypad(nbgl_layout_t *layout, + keyboardCallback_t callback, + const char *text, + bool shuffled); +int nbgl_layoutUpdateKeypad(nbgl_layout_t *layout, + uint8_t index, + bool enableValidate, + bool enableBackspace); +int nbgl_layoutAddHiddenDigits(nbgl_layout_t *layout, uint8_t nbDigits); +int nbgl_layoutUpdateHiddenDigits(nbgl_layout_t *layout, uint8_t index, uint8_t nbActive); +#endif // HAVE_SE_TOUCH #endif // NBGL_KEYPAD /* generic functions */ diff --git a/lib_nbgl/include/nbgl_obj.h b/lib_nbgl/include/nbgl_obj.h index a9937adff..47de900cc 100644 --- a/lib_nbgl/include/nbgl_obj.h +++ b/lib_nbgl/include/nbgl_obj.h @@ -27,11 +27,23 @@ extern "C" { #define VALIDATE_KEY '\r' // for Keyboard +#ifdef HAVE_SE_TOUCH #define KEYBOARD_KEY_HEIGHT 60 +#else // HAVE_SE_TOUCH +#define KEYBOARD_KEY_WIDTH 14 +#define KEYBOARD_KEY_HEIGHT 14 +#define KEYBOARD_WIDTH (5 * KEYBOARD_KEY_WIDTH) +#endif // HAVE_SE_TOUCH // for Keypad +#ifdef HAVE_SE_TOUCH #define KEYPAD_KEY_HEIGHT 104 +#else // HAVE_SE_TOUCH +#define KEYPAD_WIDTH 114 +#define KEYPAD_HEIGHT 18 +#endif // HAVE_SE_TOUCH +#ifdef HAVE_SE_TOUCH ///< special code used by given callback of @ref nbgl_navigationPopulate to inform when Exit key is ///< pressed #define EXIT_PAGE 0xFF @@ -45,6 +57,7 @@ extern "C" { // common dimensions for buttons #define BUTTON_RADIUS RADIUS_40_PIXELS #define BUTTON_DIAMETER 80 +#endif // HAVE_SE_TOUCH /********************** * TYPEDEFS @@ -57,7 +70,7 @@ extern "C" { typedef enum { SCREEN, ///< Main screen CONTAINER, ///< Empty container - IMAGE, ///< Bitmap (x and width must be multiple of 4) + IMAGE, ///< Bitmap (y and height must be multiple of 4 on Stax) LINE, ///< Vertical or Horizontal line TEXT_AREA, ///< Area to contain text line(s) BUTTON, ///< Rounded rectangle button with icon and/or text @@ -69,7 +82,8 @@ typedef enum { KEYBOARD, ///< Keyboard KEYPAD, ///< Keypad SPINNER, ///< Spinner - IMAGE_FILE ///< Image file (with Ledger compression) + IMAGE_FILE, ///< Image file (with Ledger compression) + TEXT_ENTRY ///< area for entered text, only for Nanos } nbgl_obj_type_t; /** @@ -115,8 +129,9 @@ typedef enum { * */ typedef enum { - NO_STYLE, ///< no border - LEDGER_BORDER ///< Ledger style border, only for @ref TEXT_AREA + NO_STYLE, ///< no border + LEDGER_BORDER, ///< Ledger style border, only for @ref TEXT_AREA + INVERTED_COLORS ///< Inverted background and rounded corners, only for @ref TEXT_AREA } nbgl_style_t; /** @@ -158,13 +173,36 @@ typedef enum { } nbgl_touchType_t; /** - * @brief The different styles of panels (temporary) + * @brief The different pressed buttons * */ +#define LEFT_BUTTON 0x01 ///< Left button event +#define RIGHT_BUTTON 0x02 ///< Right button event +#define BOTH_BUTTONS 0x03 ///< Both buttons event +#define RELEASED_MASK 0x80 ///< released (see LSB bits to know what buttons are released) +#define CONTINUOUS_MASK \ + 0x40 ///< if set, means that the button(s) is continuously pressed (this event is sent every + ///< 300ms after the first 800ms) + typedef enum { - PLAIN_COLOR_PANEL = 0, - ROUNDED_BORDER_PANEL ///< with a thin border in borderColor, with rounded corners -} nbgl_panelStyle_t; + BUTTON_LEFT_PRESSED = 0, ///< Sent when Left button is released + BUTTON_RIGHT_PRESSED, ///< Send when Right button is released + BUTTON_LEFT_CONTINUOUS_PRESSED, ///< Send when Left button is continuouly pressed (sent every + ///< 300ms after the first 800ms) + BUTTON_RIGHT_CONTINUOUS_PRESSED, ///< Send when Left button is continuouly pressed (sent every + ///< 300ms after the first 800ms) + BUTTON_BOTH_PRESSED, ///< Sent when both buttons are released + BUTTON_BOTH_TOUCHED, ///< Sent when both buttons are touched + INVALID_BUTTON_EVENT +} nbgl_buttonEvent_t; + +/** + * @brief prototype of function to be called when a button event is received by an object (TODO: + * change to screen?) + * @param obj the concerned object + * @param buttonState event on buttons + */ +typedef void (*nbgl_buttonCallback_t)(void *obj, nbgl_buttonEvent_t buttonEvent); /** * @brief The low level Touchscreen event, coming from driver @@ -379,6 +417,7 @@ typedef struct PACKED__ nbgl_text_area_s { uint8_t nbMaxLines; ///< if >0, replace end (3 last chars) of line (nbMaxLines-1) by "..." and ///< stop display here const char *text; ///< ASCII text to draw (NULL terminated). Can be NULL. + uint16_t len; ///< number of bytes to write (if 0, max number of chars or strlen is used) #if defined(HAVE_LANGUAGE_PACK) UX_LOC_STRINGS_INDEX textId; ///< id of the UTF-8 text #endif // HAVE_LANGUAGE_PACK @@ -387,6 +426,17 @@ typedef struct PACKED__ nbgl_text_area_s { uint8_t token; ///< token to use as param of onDrawCallback } nbgl_text_area_t; +/** + * @brief struct to represent a text entry area (@ref TEXT_ENTRY type) + * + */ +typedef struct PACKED__ nbgl_text_entry_s { + nbgl_obj_t obj; ///< common part + nbgl_font_id_e fontId; ///< id of the font to use + uint8_t nbChars; ///< number of char placeholders to display (8 or 9 chars). + const char *text; ///< text to display (up to nbChars chars). +} nbgl_text_entry_t; + /** * @brief struct to represent a "spinner", represented by the Ledger corners, in gray, with one of * the corners in black (@ref SPINNER type) @@ -410,9 +460,16 @@ typedef void (*keyboardCallback_t)(char touchedKey); * */ typedef enum { +#ifdef HAVE_SE_TOUCH MODE_LETTERS = 0, ///< letters mode MODE_DIGITS, ///< digits and some special characters mode MODE_SPECIAL ///< extended special characters mode +#else // HAVE_SE_TOUCH + MODE_LOWER_LETTERS, ///< lower case letters mode + MODE_UPPER_LETTERS, ///< upper case letters mode + MODE_DIGITS_AND_SPECIALS, ///< digits and some special characters mode + MODE_NONE ///< no mode defined (only for Nanos) +#endif // HAVE_SE_TOUCH } keyboardMode_t; /** @@ -434,8 +491,14 @@ typedef struct PACKED__ nbgl_keyboard_s { color_t textColor; ///< color set to letters. color_t borderColor; ///< color set to key borders bool lettersOnly; ///< if true, only display letter keys and Backspace +#ifdef HAVE_SE_TOUCH bool needsRefresh; ///< if true, means that the keyboard has been redrawn and needs a refresh keyboardCase_t casing; ///< keyboard casing mode (lower, upper once or upper locked) +#else // HAVE_SE_TOUCH + bool enableBackspace; ///< if true, Backspace key is enabled + bool enableValidate; ///< if true, Validate key is enabled + uint8_t selectedCharIndex; +#endif // HAVE_SE_TOUCH keyboardMode_t mode; ///< keyboard mode to start with uint32_t keyMask; ///< mask used to disable some keys in letters only mod. The 26 LSB bits of ///< mask are used, for the 26 letters of a QWERTY keyboard. Bit[0] for Q, @@ -448,14 +511,18 @@ typedef struct PACKED__ nbgl_keyboard_s { * */ typedef struct PACKED__ nbgl_keypad_s { - nbgl_obj_t obj; ///< common part - color_t textColor; ///< color set to digits. - color_t borderColor; ///< color set to key borders + nbgl_obj_t obj; ///< common part +#ifdef HAVE_SE_TOUCH + color_t textColor; ///< color set to digits. + color_t borderColor; ///< color set to key borders + bool enableDigits; ///< if true, Digit keys are enabled + uint8_t digitIndexes[5]; ///< array of digits indexes, 4 bits per digit +#else // HAVE_SE_TOUCH + uint8_t selectedKey; ///< selected key position +#endif // HAVE_SE_TOUCH bool enableBackspace; ///< if true, Backspace key is enabled bool enableValidate; ///< if true, Validate key is enabled - bool enableDigits; ///< if true, Digit keys are enabled bool shuffled; ///< if true, Digit keys are shuffled - uint8_t digitIndexes[5]; ///< array of digits indexes, 4 bits per digit keyboardCallback_t callback; ///< function called when an active key is pressed } nbgl_keypad_t; @@ -508,6 +575,7 @@ void nbgl_containerPoolRelease(uint8_t layer); nbgl_obj_t **nbgl_containerPoolGet(uint8_t nbObjs, uint8_t layer); uint8_t nbgl_containerPoolGetNbUsed(uint8_t layer); +#ifdef HAVE_SE_TOUCH nbgl_container_t *nbgl_navigationPopulate(uint8_t nbPages, uint8_t activePage, bool withExitKey, @@ -516,15 +584,21 @@ bool nbgl_navigationCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType, uint8_t nbPages, uint8_t *activePage); +#endif // HAVE_SE_TOUCH // for internal use void nbgl_objDrawKeyboard(nbgl_keyboard_t *kbd); void nbgl_objDrawKeypad(nbgl_keypad_t *kbd); +#ifdef HAVE_SE_TOUCH void nbgl_keyboardTouchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType); void nbgl_keypadTouchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType); bool nbgl_keyboardGetPosition(nbgl_keyboard_t *kbd, char index, uint16_t *x, uint16_t *y); bool nbgl_keypadGetPosition(nbgl_keypad_t *kbd, char index, uint16_t *x, uint16_t *y); +#else // HAVE_SE_TOUCH +void nbgl_keyboardCallback(nbgl_obj_t *obj, nbgl_buttonEvent_t buttonEvent); +void nbgl_keypadCallback(nbgl_obj_t *obj, nbgl_buttonEvent_t buttonEvent); +#endif // HAVE_SE_TOUCH /********************** * MACROS diff --git a/lib_nbgl/include/nbgl_screen.h b/lib_nbgl/include/nbgl_screen.h index 09d023623..77fee9edf 100644 --- a/lib_nbgl/include/nbgl_screen.h +++ b/lib_nbgl/include/nbgl_screen.h @@ -53,18 +53,22 @@ typedef struct PACKED__ nbgl_screenTickerConfiguration_s { typedef struct PACKED__ nbgl_screen_s { nbgl_container_t container; ///< common part nbgl_screenTickerConfiguration_t ticker; ///< ticker configuration - nbgl_touchCallback_t touchCallback; ///< function to be called on events defined in touchMask - ///< field in each sub-object +#ifdef HAVE_SE_TOUCH + nbgl_touchCallback_t + touchCallback; ///< function to be called on events defined in touchMask of each objects +#else // HAVE_SE_TOUCH + nbgl_buttonCallback_t buttonCallback; +#endif // HAVE_SE_TOUCH struct nbgl_screen_s *next; ///< pointer to screen on top of this one (or NULL is this screen is top of stack) struct nbgl_screen_s *previous; ///< pointer to screen on bottom of this one (or NULL is this ///< screen is bottom of stack) + uint8_t index; ///< index in screenStack array } nbgl_screen_t; /********************** * GLOBAL PROTOTYPES **********************/ - unsigned int nbgl_screen_reinit(void); #ifdef HAVE_DISPLAY_FAST_MODE @@ -79,23 +83,38 @@ void nbgl_screenRedraw(void); nbgl_obj_t *nbgl_screenGetTop(void); uint8_t nbgl_screenGetCurrentStackSize(void); bool nbgl_screenContainsObj(nbgl_obj_t *obj); +nbgl_obj_t *nbgl_screenContainsObjType(nbgl_screen_t *screen, nbgl_obj_type_t type); +#ifdef HAVE_SE_TOUCH int nbgl_screenSet(nbgl_obj_t ***elements, uint8_t nbElements, const nbgl_screenTickerConfiguration_t *ticker, nbgl_touchCallback_t touchCallback); +#else // HAVE_SE_TOUCH +int nbgl_screenSet(nbgl_obj_t ***elements, + uint8_t nbElements, + const nbgl_screenTickerConfiguration_t *ticker, + nbgl_buttonCallback_t buttonCallback); +#endif // HAVE_SE_TOUCH int nbgl_screenUpdateNbElements(uint8_t screenIndex, uint8_t nbElements); int nbgl_screenUpdateBackgroundColor(uint8_t screenIndex, color_t color); int nbgl_screenUpdateTicker(uint8_t screenIndex, const nbgl_screenTickerConfiguration_t *ticker); nbgl_obj_t **nbgl_screenGetElements(uint8_t screenIndex); int nbgl_screenRelease(void); -int nbgl_screenPush(nbgl_obj_t ***elements, - uint8_t nbElements, - const nbgl_screenTickerConfiguration_t *ticker, - nbgl_touchCallback_t touchCallback); -int nbgl_screenPop(uint8_t screenIndex); -int nbgl_screenReset(void); -void nbgl_screenHandler(uint32_t intervaleMs); +#ifdef HAVE_SE_TOUCH +int nbgl_screenPush(nbgl_obj_t ***elements, + uint8_t nbElements, + const nbgl_screenTickerConfiguration_t *ticker, + nbgl_touchCallback_t touchCallback); +#else // HAVE_SE_TOUCH +int nbgl_screenPush(nbgl_obj_t ***elements, + uint8_t nbElements, + const nbgl_screenTickerConfiguration_t *ticker, + nbgl_buttonCallback_t buttonCallback); +#endif // HAVE_SE_TOUCH +int nbgl_screenPop(uint8_t screenIndex); +int nbgl_screenReset(void); +void nbgl_screenHandler(uint32_t intervaleMs); /********************** * MACROS diff --git a/lib_nbgl/include/nbgl_step.h b/lib_nbgl/include/nbgl_step.h new file mode 100644 index 000000000..a4ed419e1 --- /dev/null +++ b/lib_nbgl/include/nbgl_step.h @@ -0,0 +1,115 @@ +/** + * @file nbgl_step.h + * @brief Step construction API of NBGL + * + */ + +#ifndef NBGL_STEP_H +#define NBGL_STEP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "nbgl_layout.h" +#include "nbgl_obj.h" +#include "nbgl_types.h" +#ifdef HAVE_LANGUAGE_PACK +#include "bolos_ux_loc_strings.h" +#endif // HAVE_LANGUAGE_PACK + +/********************* + * DEFINES + *********************/ +/** + * get the "position" of a step within a flow of several steps + * @param _step step index from which to get the position + * @param _nb_steps number of steps in the flow + */ +#define GET_POS_OF_STEP(_step, _nb_steps) \ + (_nb_steps < 2) \ + ? SINGLE_STEP \ + : ((_step == 0) ? FIRST_STEP \ + : ((_step == (_nb_steps - 1)) ? LAST_STEP : NEITHER_FIRST_NOR_LAST_STEP)) + +/********************** + * TYPEDEFS + **********************/ + +/** + * @brief type shared externally + * + */ +typedef void *nbgl_step_t; + +/** + * @brief prototype of chosen menu list item callback + * @param choiceIndex index of the menu list item + */ +typedef void (*nbgl_stepMenuListCallback_t)(uint8_t choiceIndex); + +/** + * @brief prototype of function to be called when buttons are touched on a screen + * @param event type of button event + */ +typedef void (*nbgl_stepButtonCallback_t)(nbgl_step_t stepCtx, nbgl_buttonEvent_t event); + +/** + * @brief possible position for a step in a flow + * + */ +enum { + SINGLE_STEP, ///< single step flow + FIRST_STEP, ///< first in a multiple steps flow + LAST_STEP, ///< last in a multiple steps flow + NEITHER_FIRST_NOR_LAST_STEP, ///< neither first nor last in a multiple steps flow +}; + +///< When the flow is navigated from first to last step +#define FORWARD_DIRECTION 0x00 +///< When the flow is navigated from last to first step +#define BACKWARD_DIRECTION 0x08 + +/** + * @brief this type contains nbgl_layoutNavIndication_t in its LSBs + * and direction in its MSB (using @ref FORWARD_DIRECTION and @ref BACKWARD_DIRECTION) + * + */ +typedef uint8_t nbgl_stepPosition_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +nbgl_step_t nbgl_stepDrawText(nbgl_stepPosition_t pos, + nbgl_stepButtonCallback_t onActionCallback, + nbgl_screenTickerConfiguration_t *ticker, + const char *text, + const char *subText, + nbgl_centeredInfoStyle_t style, + bool modal); +nbgl_step_t nbgl_stepDrawCenteredInfo(nbgl_stepPosition_t pos, + nbgl_stepButtonCallback_t onActionCallback, + nbgl_screenTickerConfiguration_t *ticker, + nbgl_layoutCenteredInfo_t *info, + bool modal); +nbgl_step_t nbgl_stepDrawMenuList(nbgl_stepMenuListCallback_t onActionCallback, + nbgl_screenTickerConfiguration_t *ticker, + nbgl_layoutMenuList_t *list, + bool modal); +uint8_t nbgl_stepGetMenuListCurrent(nbgl_step_t step); +int nbgl_stepRelease(nbgl_step_t step); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* NBGL_STEP_H */ diff --git a/lib_nbgl/include/nbgl_types.h b/lib_nbgl/include/nbgl_types.h index 3d6f79e44..389e4f342 100644 --- a/lib_nbgl/include/nbgl_types.h +++ b/lib_nbgl/include/nbgl_types.h @@ -24,12 +24,20 @@ extern "C" { /** * Width of the front screen in pixels */ +#ifndef BAGL_WIDTH #define SCREEN_WIDTH 400 +#else // HAVE_SE_TOUCH +#define SCREEN_WIDTH BAGL_WIDTH +#endif // HAVE_SE_TOUCH /** * Height of the front screen in pixels */ +#ifndef BAGL_HEIGHT #define SCREEN_HEIGHT 672 +#else // HAVE_SE_TOUCH +#define SCREEN_HEIGHT BAGL_HEIGHT +#endif // HAVE_SE_TOUCH /** * No transformation @@ -134,8 +142,10 @@ typedef enum { * */ typedef struct PACKED__ nbgl_area_s { - uint16_t x0; ///< horizontal position of the upper left point of the area - uint16_t y0; ///< vertical position of the upper left point of the area + int16_t x0; ///< horizontal position of the upper left point of the area (signed int allow for + ///< out of screen rendering) + int16_t y0; ///< vertical position of the upper left point of the area (signed int allow for + ///< out of screen rendering) uint16_t width; ///< width of the area, in pixels uint16_t height; ///< height of the area, in pixels color_t backgroundColor; ///< color (usually background) to be applied @@ -173,14 +183,16 @@ typedef enum nbgl_post_refresh_t { * */ typedef enum { - RADIUS_4_PIXELS = 0, ///< 4 pixels + RADIUS_3_PIXELS = 0, ///< 3 pixels (not on Stax) + RADIUS_4_PIXELS, ///< 4 pixels RADIUS_8_PIXELS, ///< 8 pixels RADIUS_16_PIXELS, ///< 16 pixels RADIUS_20_PIXELS, ///< 20 pixels RADIUS_24_PIXELS, ///< 24 pixels RADIUS_32_PIXELS, ///< 32 pixels RADIUS_40_PIXELS, ///< 40 pixels - RADIUS_48_PIXELS, ///< 40 pixels + RADIUS_48_PIXELS, ///< 48 pixels + RADIUS_1_PIXEL, ///< 1 pixel (not on Stax) RADIUS_0_PIXELS = 0xFF, ///< no radius (square angle) } nbgl_radius_t; diff --git a/lib_nbgl/include/nbgl_use_case.h b/lib_nbgl/include/nbgl_use_case.h index 8f641db34..a04214908 100644 --- a/lib_nbgl/include/nbgl_use_case.h +++ b/lib_nbgl/include/nbgl_use_case.h @@ -15,7 +15,11 @@ extern "C" { * INCLUDES *********************/ +#ifdef NBGL_PAGE #include "nbgl_page.h" +#else // NBGL_PAGE +#include "nbgl_flow.h" +#endif // NBGL_PAGE /********************* * DEFINES @@ -97,10 +101,17 @@ typedef bool (*nbgl_navCallback_t)(uint8_t page, nbgl_pageContent_t *content); */ typedef void (*nbgl_choiceCallback_t)(bool confirm); +/** + * @brief prototype of function to be called when an page of settings is double-pressed + * @param page page index (0->(nb_pages-1)) + */ +typedef void (*nbgl_actionCallback_t)(uint8_t page); + /********************** * GLOBAL PROTOTYPES **********************/ +#ifdef HAVE_SE_TOUCH // utils uint8_t nbgl_useCaseGetNbTagValuesInPage(uint8_t nbPairs, const nbgl_layoutTagValueList_t *tagValueList, @@ -131,6 +142,15 @@ void nbgl_useCasePlugInHome(const char *plugInName, bool withSettings, nbgl_callback_t topRightCallback, nbgl_callback_t quitCallback); +#else // TARGET_STAX +void nbgl_useCaseHome(const char *appName, + const nbgl_icon_details_t *appIcon, + const char *appVersion, + const char *tagline, + nbgl_callback_t aboutCallback, + nbgl_callback_t quitCallback); +#endif // TARGET_STAX +#ifdef TARGET_STAX void nbgl_useCaseSettings(const char *settingsTitle, uint8_t initPage, uint8_t nbPages, @@ -138,6 +158,14 @@ void nbgl_useCaseSettings(const char *settingsTitle, nbgl_callback_t quitCallback, nbgl_navCallback_t navCallback, nbgl_layoutTouchCallback_t controlsCallback); +#else // TARGET_STAX +void nbgl_useCaseSettings(uint8_t initPage, + uint8_t nbPages, + nbgl_callback_t quitCallback, + nbgl_navCallback_t navCallback, + nbgl_actionCallback_t actionCallback); +#endif // TARGET_STAX +#ifdef TARGET_STAX void nbgl_useCaseChoice(const nbgl_icon_details_t *icon, const char *message, const char *subMessage, @@ -179,8 +207,28 @@ void nbgl_useCaseAddressConfirmation(const char *address, nbgl_choiceCallback_t void nbgl_useCaseAddressConfirmationExt(const char *address, nbgl_choiceCallback_t callback, const nbgl_layoutTagValueList_t *tagValueList); +#else // HAVE_SE_TOUCH +void nbgl_useCaseHome(const char *appName, + const nbgl_icon_details_t *appIcon, + const char *appVersion, + const char *tagline, + nbgl_callback_t aboutCallback, + nbgl_callback_t quitCallback); +void nbgl_useCaseSettings(uint8_t initPage, + uint8_t nbPages, + nbgl_callback_t quitCallback, + nbgl_navCallback_t navCallback, + nbgl_actionCallback_t actionCallback); +void nbgl_useCaseRegularReview(uint8_t initPage, uint8_t nbPages, nbgl_navCallback_t navCallback); +void nbgl_useCaseForwardOnlyReview(nbgl_navCallback_t navCallback); +void nbgl_useCaseStaticReview(nbgl_layoutTagValueList_t *tagValueList, + const nbgl_icon_details_t *icon, + const char *reviewTitle, + const char *acceptText, + const char *rejectText, + nbgl_choiceCallback_t callback); +#endif // HAVE_SE_TOUCH void nbgl_useCaseSpinner(const char *text); - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/lib_nbgl/serialization/Makefile b/lib_nbgl/serialization/Makefile index eaffd2b8d..e284e90dd 100644 --- a/lib_nbgl/serialization/Makefile +++ b/lib_nbgl/serialization/Makefile @@ -2,8 +2,15 @@ INC := -I . -I ../include DEFINES := -DLINUX_SIMU -DHAVE_LANGUAGE_PACK -DNBGL_GENERATE_DATA_TEST +ifdef TARGET_STAX +DEFINES += -DHAVE_SE_TOUCH +else +DEFINES += -DBAGL_HEIGHT=64 -DBAGL_WIDTH=128 + +endif + default: generate_data_test.c - gcc $(INC) generate_data_test.c $(DEFINES) ../src/nbgl_serialize.c ../src/nbgl_obj_pool.c -o generate_data_test + gcc $(INC) generate_data_test.c $(DEFINES) ../src/nbgl_serialize.c -o generate_data_test run_test: default ./generate_data_test > data_test.txt diff --git a/lib_nbgl/serialization/generate_data_test.c b/lib_nbgl/serialization/generate_data_test.c index a76e473fb..0c06fe952 100644 --- a/lib_nbgl/serialization/generate_data_test.c +++ b/lib_nbgl/serialization/generate_data_test.c @@ -16,6 +16,11 @@ static uint8_t const C_leftArrow32px_bitmap[] = { }; const nbgl_icon_details_t C_leftArrow32px = {32, 32, NBGL_BPP_1, true, C_leftArrow32px_bitmap}; +uint8_t nbgl_objPoolGetId(nbgl_obj_t *obj) +{ + return 0; +} + void print_hex(const char *name, uint8_t *buffer, size_t len) { printf("%s,", name); @@ -253,9 +258,13 @@ void test_draw_nbgl_keyboard() .textColor = WHITE, .borderColor = BLACK, .lettersOnly = true, - .casing = 0, - .mode = MODE_DIGITS, - .keyMask = 0x12345678, +#ifdef HAVE_SE_TOUCH + .casing = 0, + .mode = MODE_DIGITS, +#else // HAVE_SE_TOUCH + .mode = MODE_UPPER_LETTERS, +#endif // HAVE_SE_TOUCH + .keyMask = 0x12345678, }; SERIALIZE_AND_PRINT(&keyboard, NBGL_DRAW_OBJ); @@ -272,12 +281,16 @@ void test_draw_nbgl_keypad() .obj.area.x0 = 3, .obj.area.y0 = 4, - .textColor = WHITE, - .borderColor = BLACK, +#ifdef HAVE_SE_TOUCH + .textColor = WHITE, + .borderColor = BLACK, +#endif // HAVE_SE_TOUCH .enableBackspace = true, .enableValidate = false, - .enableDigits = true, - .shuffled = false}; +#ifdef HAVE_SE_TOUCH + .enableDigits = true, +#endif // HAVE_SE_TOUCH + .shuffled = false}; SERIALIZE_AND_PRINT(&keypad, NBGL_DRAW_OBJ); } @@ -330,20 +343,33 @@ void test_refresh_area() int main() { +#ifdef HAVE_SE_TOUCH + printf("stax\n"); +#else // HAVE_SE_TOUCH + printf("nano\n"); +#endif // HAVE_SE_TOUCH test_draw_nbgl_screen(); test_draw_nbgl_container(); +#ifdef HAVE_SE_TOUCH test_draw_nbgl_line(); +#endif // HAVE_SE_TOUCH test_draw_nbgl_text_area(); +#ifdef HAVE_SE_TOUCH test_draw_nbgl_qr_code(); test_draw_nbgl_radio(); test_draw_nbgl_switch(); +#endif // HAVE_SE_TOUCH test_draw_nbgl_progress_bar(); +#ifdef HAVE_SE_TOUCH test_draw_nbgl_page_indicator(); test_draw_nbgl_button(); +#endif // HAVE_SE_TOUCH test_draw_nbgl_image(); test_draw_nbgl_keyboard(); test_draw_nbgl_keypad(); +#ifdef HAVE_SE_TOUCH test_draw_nbgl_spinner(); +#endif // HAVE_SE_TOUCH test_draw_nbgl_image_file(); test_refresh_area(); } diff --git a/lib_nbgl/serialization/nbgl_lib.py b/lib_nbgl/serialization/nbgl_lib.py index a69e55fc4..624cfa7a5 100644 --- a/lib_nbgl/serialization/nbgl_lib.py +++ b/lib_nbgl/serialization/nbgl_lib.py @@ -48,9 +48,10 @@ class NbglRadius(IntEnum): class NbglKeyboardMode(IntEnum): - MODE_LETTERS = 0 + MODE_LETTERS = 0, MODE_DIGITS = 1, - MODE_SPECIAL = 2 + MODE_SPECIAL = 2, + MODE_NONE = 3 class NbglObjType(IntEnum): @@ -97,30 +98,35 @@ class NbglFontId(IntEnum): BAGL_FONT_INTER_REGULAR_24px_1bpp = 4 BAGL_FONT_INTER_SEMIBOLD_24px_1bpp = 5 BAGL_FONT_INTER_MEDIUM_32px_1bpp = 6 + BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp = 8 + BAGL_FONT_OPEN_SANS_LIGHT_16px_1bpp = 9 + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp = 10 class NbglStyle(IntEnum): NO_STYLE = 0, - LEDGER_BORDER = 1 + LEDGER_BORDER = 1, + INVERTED_COLORS = 2 -def parse_str(data: bytes) -> Tuple[str, int]: +def parse_str(data: bytes) -> str: """ Utility function to parse a NULL terminated string from input bytes. If the string is not terminated by NULL, take the truncated string instead. - Returns the string and its size. + Returns the string """ - result = "" size = 0 for b in data: size += 1 if b == 0: break - else: - result += chr(b) - return result, size + + if size > 0: + return data[:size-1].decode() + + return "" class NbglGenericJsonSerializable(ABC): @@ -160,7 +166,7 @@ def from_json_dict(cls, data: Dict): return cls(**fields) @abstractclassmethod - def from_bytes(cls, data: bytes): + def from_bytes(cls, is_stax : bool, data: bytes): """ Get an instance of the class, from raw bytes. """ @@ -183,7 +189,7 @@ class NbglArea(NbglObj): bpp: NbglBpp @classmethod - def from_bytes(cls, data: bytes): + def from_bytes(cls, is_stax : bool, data: bytes): x0, y0, width, height, color_n, bpp_n = struct.unpack('>HHHHBB', data[:10]) color = NbglColor(color_n) bpp = NbglBpp(bpp_n) @@ -199,8 +205,8 @@ class NbglScreen(NbglObj): area: NbglArea @classmethod - def from_bytes(cls, data: bytes): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data: bytes): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) return cls( area=area ) @@ -214,8 +220,8 @@ class NbglContainer(NbglObj): force_clean: bool @classmethod - def from_bytes(cls, data: bytes): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data: bytes): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) layout, nb_children, force_clean = struct.unpack( '>BB?', data[NbglArea.size():]) return cls( @@ -235,8 +241,8 @@ class NbglLine(NbglObj): offset: int @classmethod - def from_bytes(cls, data: bytes): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data: bytes): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) direction, line_color, thickness, offset = struct.unpack( '>BBBB', data[NbglArea.size():]) return cls( @@ -255,8 +261,8 @@ class NbglRadioButton(NbglObj): state: NbglState @classmethod - def from_bytes(cls, data): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) active_color, border_color, state = struct.unpack( '>BBB', data[NbglArea.size():]) return cls( @@ -275,8 +281,8 @@ class NbglSwitch(NbglObj): state: NbglState @classmethod - def from_bytes(cls, data): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) on_color, off_color, state = struct.unpack( '>BBB', data[NbglArea.size():]) return cls( @@ -294,8 +300,8 @@ class NbglProgressBar(NbglObj): state: int @classmethod - def from_bytes(cls, data): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) with_border, state = struct.unpack( '>?B', data[NbglArea.size():]) return cls( @@ -312,8 +318,8 @@ class NbglPageIndicator(NbglObj): nb_pages: int @classmethod - def from_bytes(cls, data): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) active_page, nb_pages = \ struct.unpack('>BB', data[NbglArea.size():]) return cls( @@ -335,9 +341,9 @@ class NbglButton(NbglObj): text: str @classmethod - def from_bytes(cls, data): + def from_bytes(cls, is_stax : bool, data): cnt = NbglArea.size() - area = NbglArea.from_bytes(data[0:cnt]) + area = NbglArea.from_bytes(is_stax, data[0:cnt]) params_template = '>BBBBB?' params_size = struct.calcsize(params_template) inner_color, border_color, \ @@ -346,7 +352,7 @@ def from_bytes(cls, data): params_template, data[cnt:cnt+params_size]) cnt += params_size - text, _ = parse_str(data[cnt:]) + text = parse_str(data[cnt:]) return cls( area=area, @@ -368,24 +374,25 @@ class NbglTextArea(NbglObj): font_id: NbglFontId localized: bool auto_hide_long_line: bool + len: int text: str @classmethod - def from_bytes(cls, data: bytes): + def from_bytes(cls, is_stax : bool, data: bytes): # Parse area - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) cnt = NbglArea.size() # Parse pattern - params_pattern = '>BBBB??' + params_pattern = '>BBBB??H' params_size = struct.calcsize(params_pattern) - text_color, alignment, style, font_id, localized, auto_hide_long_line = struct.unpack( + text_color, alignment, style, font_id, localized, auto_hide_long_line, len = struct.unpack( params_pattern, data[cnt:cnt+params_size] ) cnt += params_size # Parse text - text, _ = parse_str(data[cnt:]) + text = parse_str(data[cnt:]) return cls( area=area, text_color=NbglColor(text_color), @@ -394,6 +401,7 @@ def from_bytes(cls, data: bytes): font_id=NbglFontId(font_id), localized=localized, auto_hide_long_line=auto_hide_long_line, + len=len, text=text ) @@ -404,8 +412,8 @@ class NbglSpinner(NbglObj): position: int @classmethod - def from_bytes(cls, data: bytes): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + def from_bytes(cls, is_stax : bool, data: bytes): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) position, = struct.unpack( '>B', data[NbglArea.size():] ) @@ -425,9 +433,9 @@ class NbglImage(NbglObj): foreground_color: NbglColor @classmethod - def from_bytes(cls, data): + def from_bytes(cls, is_stax : bool, data): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) width,height,bpp,isFile,size, = struct.unpack('>HHBBI', data[NbglArea.size():NbglArea.size()+10]) foreground_color, = struct.unpack('>B', data[NbglArea.size()+10:]) @@ -446,8 +454,8 @@ class NbglImageFile(NbglObj): area: NbglArea @classmethod - def from_bytes(cls, data: bytes): - area = NbglArea.from_bytes(data[0:]) + def from_bytes(cls, is_stax : bool, data: bytes): + area = NbglArea.from_bytes(is_stax, data[0:]) return cls(area) @@ -459,9 +467,9 @@ class NbglQrCode(NbglObj): text: str @classmethod - def from_bytes(cls, data: bytes): + def from_bytes(cls, is_stax : bool, data: bytes): # Parse area - area = NbglArea.from_bytes(data[0:NbglArea.size()]) + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) cnt = NbglArea.size() # Parse QR code color and version @@ -469,7 +477,7 @@ def from_bytes(cls, data: bytes): cnt += 2 # Parse text - text, _ = parse_str(data[cnt:]) + text = parse_str(data[cnt:]) # Return return cls( @@ -488,12 +496,20 @@ class NbglKeyboard(NbglObj): upper_case: bool mode: NbglKeyboardMode key_mask: int + selected_char_index: int @classmethod - def from_bytes(cls, data: bytes): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) - text_color, border_color, letters_only, upper_case, mode, key_mask = struct.unpack( - '>BBBBBI', data[NbglArea.size():]) + def from_bytes(cls, is_stax : bool, data: bytes): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) + if is_stax: + selected_char_index = 0 + text_color, border_color, letters_only, upper_case, mode, key_mask = struct.unpack( + '>BBBBBI', data[NbglArea.size():]) + else: + upper_case = False + text_color, border_color, letters_only, selected_char_index, mode, key_mask = struct.unpack( + '>BBBBBI', data[NbglArea.size():]) + return cls( area=area, text_color=NbglColor(text_color), @@ -501,7 +517,8 @@ def from_bytes(cls, data: bytes): letters_only=letters_only, upper_case=upper_case, mode=NbglKeyboardMode(mode), - key_mask=key_mask + key_mask=key_mask, + selected_char_index=selected_char_index ) @@ -514,12 +531,21 @@ class NbglKeypad(NbglObj): enable_validate: bool enable_digits: bool shuffled:bool + selectedKey: int @classmethod - def from_bytes(cls, data: bytes): - area = NbglArea.from_bytes(data[0:NbglArea.size()]) - text_color, border_color, enable_backspace, enable_validate, enable_digits, shuffled = \ - struct.unpack('>BBBBBB', data[NbglArea.size():NbglArea.size()+6]) + def from_bytes(cls, is_stax : bool, data: bytes): + area = NbglArea.from_bytes(is_stax, data[0:NbglArea.size()]) + if is_stax: + text_color, border_color, enable_backspace, enable_validate, enable_digits, shuffled = \ + struct.unpack('>BBBBBB', data[NbglArea.size():NbglArea.size()+6]) + selectedKey = 0 # unused on Stax + else: + text_color = NbglColor.WHITE + border_color = NbglColor.BLACK + enable_digits = True + enable_backspace, enable_validate, shuffled, selectedKey = \ + struct.unpack('>BBBB', data[NbglArea.size():NbglArea.size()+4]) return cls( area=area, text_color=NbglColor(text_color), @@ -527,7 +553,8 @@ def from_bytes(cls, data: bytes): enable_backspace=enable_backspace, enable_validate=enable_validate, enable_digits=enable_digits, - shuffled=shuffled + shuffled=shuffled, + selectedKey=selectedKey ) @@ -566,25 +593,28 @@ class NbglRefreshAreaEvent(NbglGenericJsonSerializable): area: NbglArea @classmethod - def from_bytes(cls, data: bytes): + def from_bytes(cls, is_stax : bool, data: bytes): return cls( - area=NbglArea.from_bytes(data) + area=NbglArea.from_bytes(is_stax, data) ) @dataclass class NbglDrawObjectEvent(NbglGenericJsonSerializable): obj: NbglObj + id: int @classmethod - def from_bytes(cls, data: bytes): + def from_bytes(cls, is_stax: bool, data: bytes): # the first byte is the object id # the second one is the object type + id = int(data[0]) obj_type = NbglObjType(data[1]) class_type = NBGL_OBJ_TYPES[obj_type] return cls( - obj=class_type.from_bytes(data[2:]) + obj=class_type.from_bytes(is_stax, data[2:]), + id=id ) def to_json_dict(self) -> Dict: @@ -594,18 +624,21 @@ def to_json_dict(self) -> Dict: 'obj': { 'type': obj_type.name, 'content': self.obj.to_json_dict() - } + }, + 'id': self.id } # Object not serializable return None @classmethod def from_json_dict(cls, data: Dict): + obj_id = data['id'] obj_data = data['obj'] obj_type = NBGL_OBJ_TYPES[NbglObjType[obj_data['type']]] return cls( - obj=obj_type.from_json_dict(obj_data['content']) + obj=obj_type.from_json_dict(obj_data['content']), + id=obj_id ) # Public functions @@ -617,7 +650,7 @@ def from_json_dict(cls, data: Dict): ] -def deserialize_nbgl_bytes(data: bytes) -> NbglEvent: +def deserialize_nbgl_bytes(is_stax: bool, data: bytes) -> NbglEvent: """ Return a NbglRefreshAreaEvent or a NbglDrawObjectEvent, from input bytes. @@ -625,9 +658,9 @@ def deserialize_nbgl_bytes(data: bytes) -> NbglEvent: event_type = NbglEventType(int(data[0])) if event_type == NbglEventType.NBGL_DRAW_OBJ: - return NbglDrawObjectEvent.from_bytes(data[1:]) + return NbglDrawObjectEvent.from_bytes(is_stax, data[1:]) elif event_type == NbglEventType.NBGL_REFRESH_AREA: - return NbglRefreshAreaEvent.from_bytes(data[1:]) + return NbglRefreshAreaEvent.from_bytes(is_stax, data[1:]) def deserialize_nbgl_json(data: Dict) -> NbglEvent: diff --git a/lib_nbgl/serialization/test_bytes_deserialize.py b/lib_nbgl/serialization/test_bytes_deserialize.py index 28fb8b831..970c52fee 100644 --- a/lib_nbgl/serialization/test_bytes_deserialize.py +++ b/lib_nbgl/serialization/test_bytes_deserialize.py @@ -6,19 +6,25 @@ def data_test(): with open("data_test.txt", "r") as data_test_file: data_test = data_test_file.readlines() - data_test = list(map(lambda s: s.rstrip().split(','), data_test)) + # first line is giving the HW: stax or nano + if data_test[0] == 'stax\n': + is_stax = True + else: + is_stax = False + data_test = list(map(lambda s: s.rstrip().split(','), data_test[1:])) data_test = {el[0]: el[1] for el in data_test} - return data_test + return (is_stax,data_test) -def run_deserialize_nbgl(hex_str: str): +def run_deserialize_nbgl(is_stax: bool, hex_str: str): bytes_in = bytes.fromhex(hex_str) - return deserialize_nbgl_bytes(bytes_in) + return deserialize_nbgl_bytes(is_stax, bytes_in) def test_draw_nbgl_screen(data_test): - serialized = data_test["test_draw_nbgl_screen"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_screen"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglDrawObjectEvent( obj=NbglScreen( @@ -30,15 +36,17 @@ def test_draw_nbgl_screen(data_test): x0=0, y0=0 ) - ) + ), + id=0 ) assert deserialized == expected def test_draw_nbgl_container(data_test): - serialized = data_test["test_draw_nbgl_container"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_container"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglDrawObjectEvent( obj=NbglContainer( @@ -53,15 +61,17 @@ def test_draw_nbgl_container(data_test): layout=NbglDirection.VERTICAL, nb_children=4, force_clean=True - ) + ), + id=1 ) assert deserialized == expected def test_draw_nbgl_text_area(data_test): - serialized = data_test["test_draw_nbgl_text_area"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_text_area"] + deserialized = run_deserialize_nbgl(is_stax, serialized) excepted = \ NbglDrawObjectEvent( obj=NbglTextArea( @@ -80,103 +90,123 @@ def test_draw_nbgl_text_area(data_test): font_id=NbglFontId.BAGL_FONT_INTER_MEDIUM_32px, localized=False, auto_hide_long_line=True, + len=0, text="arthur" - ) + ), + id=1 ) assert deserialized == excepted def test_draw_nbgl_line(data_test): - serialized = data_test["test_draw_nbgl_line"] - deserialized = run_deserialize_nbgl(serialized) - expected = \ - NbglDrawObjectEvent( - obj=NbglLine( - area=NbglArea( - bpp=NbglBpp.BPP_1, - width=36, - height=267, - x0=0, - y0=42, - background_color=NbglColor.WHITE, + is_stax = data_test[0] + if is_stax: + serialized = data_test[1]["test_draw_nbgl_line"] + deserialized = run_deserialize_nbgl(is_stax, serialized) + expected = \ + NbglDrawObjectEvent( + obj=NbglLine( + area=NbglArea( + bpp=NbglBpp.BPP_1, + width=36, + height=267, + x0=0, + y0=42, + background_color=NbglColor.WHITE, + ), + direction=NbglDirection.HORIZONTAL, + line_color=NbglColor.DARK_GRAY, + thickness=4, + offset=2 ), - direction=NbglDirection.HORIZONTAL, - line_color=NbglColor.DARK_GRAY, - thickness=4, - offset=2 + id=1 ) - ) - assert deserialized == expected + assert deserialized == expected + assert True def test_draw_nbgl_qr_code(data_test): - serialized = data_test["test_draw_nbgl_qr_code"] - deserialized = run_deserialize_nbgl(serialized) - expected = \ - NbglDrawObjectEvent( - obj=NbglQrCode( - area=NbglArea( - background_color=NbglColor.DARK_GRAY, - bpp=NbglBpp.BPP_2, - height=55, - width=66, - x0=400, - y0=300 + is_stax = data_test[0] + if is_stax: + serialized = data_test[1]["test_draw_nbgl_qr_code"] + deserialized = run_deserialize_nbgl(is_stax, serialized) + expected = \ + NbglDrawObjectEvent( + obj=NbglQrCode( + area=NbglArea( + background_color=NbglColor.DARK_GRAY, + bpp=NbglBpp.BPP_2, + height=55, + width=66, + x0=400, + y0=300 + ), + foreground_color=NbglColor.DARK_GRAY, + text="fatstacks", + version=NbglQrCodeVersion.QRCODE_V10 ), - foreground_color=NbglColor.DARK_GRAY, - text="fatstacks", - version=NbglQrCodeVersion.QRCODE_V10 - )) - assert deserialized == expected + id=1 + ) + assert deserialized == expected + assert True def test_draw_nbgl_radio(data_test): - serialized = data_test["test_draw_nbgl_radio"] - deserialized = run_deserialize_nbgl(serialized) - expected = \ - NbglDrawObjectEvent( - obj=NbglRadioButton( - area=NbglArea( - background_color=NbglColor.BLACK, - bpp=NbglBpp.BPP_4, - height=100, - width=200, - x0=123, - y0=234 + is_stax = data_test[0] + if is_stax: + serialized = data_test[1]["test_draw_nbgl_radio"] + deserialized = run_deserialize_nbgl(is_stax, serialized) + expected = \ + NbglDrawObjectEvent( + obj=NbglRadioButton( + area=NbglArea( + background_color=NbglColor.BLACK, + bpp=NbglBpp.BPP_4, + height=100, + width=200, + x0=123, + y0=234 + ), + active_color=NbglColor.BLACK, + border_color=NbglColor.DARK_GRAY, + state=NbglState.ON_STATE ), - active_color=NbglColor.BLACK, - border_color=NbglColor.DARK_GRAY, - state=NbglState.ON_STATE + id=1 ) - ) - assert deserialized == expected + assert deserialized == expected + assert True def test_draw_nbgl_switch(data_test): - serialized = data_test["test_draw_nbgl_switch"] - deserialized = run_deserialize_nbgl(serialized) - expected = \ - NbglDrawObjectEvent( - obj=NbglSwitch( - area=NbglArea( - background_color=NbglColor.LIGHT_GRAY, - bpp=NbglBpp.BPP_1, - height=333, - width=89, - x0=1, - y0=10000 + is_stax = data_test[0] + if is_stax: + serialized = data_test[1]["test_draw_nbgl_switch"] + deserialized = run_deserialize_nbgl(is_stax, serialized) + expected = \ + NbglDrawObjectEvent( + obj=NbglSwitch( + area=NbglArea( + background_color=NbglColor.LIGHT_GRAY, + bpp=NbglBpp.BPP_1, + height=333, + width=89, + x0=1, + y0=10000 + ), + off_color=NbglColor.WHITE, + on_color=NbglColor.BLACK, + state=NbglState.OFF_STATE ), - off_color=NbglColor.WHITE, - on_color=NbglColor.BLACK, - state=NbglState.OFF_STATE + id=1 ) - ) - assert deserialized == expected + assert deserialized == expected + assert True def test_draw_nbgl_progress_bar(data_test): - serialized = data_test["test_draw_nbgl_progress_bar"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_progress_bar"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglDrawObjectEvent( obj=NbglProgressBar( @@ -190,61 +220,71 @@ def test_draw_nbgl_progress_bar(data_test): ), with_border=True, state=91 - ) + ), + id=1 ) assert deserialized == expected def test_draw_nbgl_page_indicator(data_test): - serialized = data_test["test_draw_nbgl_page_indicator"] - deserialized = run_deserialize_nbgl(serialized) - expected = \ - NbglDrawObjectEvent( - obj=NbglPageIndicator( - area=NbglArea( - background_color=NbglColor.BLACK, - bpp=NbglBpp.BPP_2, - height=11, - width=22, - x0=33, - y0=44 + is_stax = data_test[0] + if is_stax: + serialized = data_test[1]["test_draw_nbgl_page_indicator"] + deserialized = run_deserialize_nbgl(is_stax, serialized) + expected = \ + NbglDrawObjectEvent( + obj=NbglPageIndicator( + area=NbglArea( + background_color=NbglColor.BLACK, + bpp=NbglBpp.BPP_2, + height=11, + width=22, + x0=33, + y0=44 + ), + active_page=2, + nb_pages=10 ), - active_page=2, - nb_pages=10 + id=1 ) - ) - assert deserialized == expected + assert deserialized == expected + assert True def test_draw_nbgl_button(data_test): - serialized = data_test["test_draw_nbgl_button"] - deserialized = run_deserialize_nbgl(serialized) - expected = \ - NbglDrawObjectEvent( - obj=NbglButton( - area=NbglArea( - background_color=NbglColor.DARK_GRAY, - bpp=NbglBpp.BPP_1, - height=50, - width=255, - x0=500, - y0=1000 + is_stax = data_test[0] + if is_stax: + serialized = data_test[1]["test_draw_nbgl_button"] + deserialized = run_deserialize_nbgl(is_stax, serialized) + expected = \ + NbglDrawObjectEvent( + obj=NbglButton( + area=NbglArea( + background_color=NbglColor.DARK_GRAY, + bpp=NbglBpp.BPP_1, + height=50, + width=255, + x0=500, + y0=1000 + ), + inner_color=NbglColor.WHITE, + border_color=NbglColor.DARK_GRAY, + foreground_color=NbglColor.LIGHT_GRAY, + radius=NbglRadius.RADIUS_24_PIXELS, + font_id=NbglFontId.BAGL_FONT_HM_ALPHA_MONO_MEDIUM_32px, + text="Test button", + localized=True ), - inner_color=NbglColor.WHITE, - border_color=NbglColor.DARK_GRAY, - foreground_color=NbglColor.LIGHT_GRAY, - radius=NbglRadius.RADIUS_24_PIXELS, - font_id=NbglFontId.BAGL_FONT_HM_ALPHA_MONO_MEDIUM_32px, - text="Test button", - localized=True + id=1 ) - ) - assert deserialized == expected + assert deserialized == expected + assert True def test_draw_nbgl_image(data_test): - serialized = data_test["test_draw_nbgl_image"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_image"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglDrawObjectEvent( obj=NbglImage( @@ -261,14 +301,16 @@ def test_draw_nbgl_image(data_test): bpp=0, isFile=1, foreground_color=NbglColor.DARK_GRAY - ) + ), + id=1 ) assert deserialized == expected def test_draw_nbgl_keyboard(data_test): - serialized = data_test["test_draw_nbgl_keyboard"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_keyboard"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglDrawObjectEvent( obj=NbglKeyboard( @@ -285,15 +327,18 @@ def test_draw_nbgl_keyboard(data_test): letters_only=True, upper_case=False, mode=NbglKeyboardMode.MODE_DIGITS, - key_mask=0x12345678 - ) + key_mask=0x12345678, + selected_char_index=0 + ), + id=1 ) assert deserialized == expected def test_draw_nbgl_keypad(data_test): - serialized = data_test["test_draw_nbgl_keypad"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_keypad"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglDrawObjectEvent( obj=NbglKeypad( @@ -310,35 +355,42 @@ def test_draw_nbgl_keypad(data_test): enable_backspace=True, enable_validate=False, enable_digits=True, - shuffled=False - ) + shuffled=False, + selectedKey=0 + ), + id=1 ) assert deserialized == expected def test_draw_nbgl_spinner(data_test): - serialized = data_test["test_draw_nbgl_spinner"] - deserialized = run_deserialize_nbgl(serialized) - expected = \ - NbglDrawObjectEvent( - obj=NbglSpinner( - area=NbglArea( - background_color=NbglColor.LIGHT_GRAY, - bpp=NbglBpp.BPP_1, - height=14, - width=25, - x0=12, - y0=10, + is_stax = data_test[0] + if is_stax: + serialized = data_test[1]["test_draw_nbgl_spinner"] + deserialized = run_deserialize_nbgl(is_stax, serialized) + expected = \ + NbglDrawObjectEvent( + obj=NbglSpinner( + area=NbglArea( + background_color=NbglColor.LIGHT_GRAY, + bpp=NbglBpp.BPP_1, + height=14, + width=25, + x0=12, + y0=10, + ), + position=2 ), - position=2 + id=1 ) - ) - assert deserialized == expected + assert deserialized == expected + assert True def test_draw_nbgl_image_file(data_test): - serialized = data_test["test_draw_nbgl_image_file"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_draw_nbgl_image_file"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglDrawObjectEvent( obj=NbglImageFile( @@ -350,14 +402,16 @@ def test_draw_nbgl_image_file(data_test): x0=22, y0=20, ), - ) + ), + id=1 ) assert deserialized == expected def test_refresh_area(data_test): - serialized = data_test["test_refresh_area"] - deserialized = run_deserialize_nbgl(serialized) + is_stax = data_test[0] + serialized = data_test[1]["test_refresh_area"] + deserialized = run_deserialize_nbgl(is_stax, serialized) expected = \ NbglRefreshAreaEvent( area=NbglArea( diff --git a/lib_nbgl/serialization/test_json_ser_deser.py b/lib_nbgl/serialization/test_json_ser_deser.py index 0c52da0e9..94b3e948c 100644 --- a/lib_nbgl/serialization/test_json_ser_deser.py +++ b/lib_nbgl/serialization/test_json_ser_deser.py @@ -18,7 +18,8 @@ def test_json_deserialize_screen(): 'bpp': 'BPP_4' } } - } + }, + 'id':0 } deserialized = \ NbglDrawObjectEvent( @@ -31,8 +32,8 @@ def test_json_deserialize_screen(): background_color=NbglColor.WHITE, bpp=NbglBpp.BPP_4 ) - ) - + ), + id=0 ) assert serialize_nbgl_json(deserialized) == serialized @@ -56,7 +57,8 @@ def test_json_deserialize_container(): 'nb_children': 4, 'force_clean': True } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -72,8 +74,8 @@ def test_json_deserialize_container(): layout=NbglDirection.VERTICAL, nb_children=4, force_clean=True - ) - + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -99,7 +101,8 @@ def test_json_deserialize_line(): 'thickness': 4, 'offset': 1 } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -116,7 +119,8 @@ def test_json_deserialize_line(): line_color=NbglColor.WHITE, thickness=4, offset=1 - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -141,7 +145,8 @@ def test_json_deserialize_radio_button(): 'border_color': 'BLACK', 'state': 'OFF_STATE' } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -157,7 +162,8 @@ def test_json_deserialize_radio_button(): active_color=NbglColor.WHITE, border_color=NbglColor.BLACK, state=NbglState.OFF_STATE - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -182,7 +188,8 @@ def test_json_deserialize_switch(): 'off_color': 'DARK_GRAY', 'state': 'ON_STATE' } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -198,7 +205,8 @@ def test_json_deserialize_switch(): on_color=NbglColor.BLACK, off_color=NbglColor.DARK_GRAY, state=NbglState.ON_STATE - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -222,7 +230,8 @@ def test_json_deserialize_progress_bar(): 'with_border': True, 'state': 42 } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -237,7 +246,8 @@ def test_json_deserialize_progress_bar(): ), with_border=True, state=42 - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -261,7 +271,8 @@ def test_json_deserialize_page_indicator(): 'active_page': 2, 'nb_pages': 10 } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -276,7 +287,8 @@ def test_json_deserialize_page_indicator(): ), active_page=2, nb_pages=10 - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -305,7 +317,8 @@ def test_json_deserialize_button(): 'localized': True, 'text': 'Hello world' } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -325,7 +338,8 @@ def test_json_deserialize_button(): font_id=NbglFontId.BAGL_FONT_INTER_REGULAR_24px, localized=True, text="Hello world" - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -352,9 +366,11 @@ def test_json_deserialize_text_area(): 'font_id': 'BAGL_FONT_INTER_SEMIBOLD_24px', 'localized': True, 'auto_hide_long_line': True, + 'len': 0, 'text': 'Hello fatstacks' } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -373,8 +389,10 @@ def test_json_deserialize_text_area(): font_id=NbglFontId.BAGL_FONT_INTER_SEMIBOLD_24px, localized=True, auto_hide_long_line=True, + len=0, text='Hello fatstacks' - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized assert deserialized == deserialize_nbgl_json(serialized) @@ -396,7 +414,8 @@ def test_json_deserialize_spinner(): }, 'position': 3 } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -410,7 +429,8 @@ def test_json_deserialize_spinner(): bpp=NbglBpp.BPP_2 ), position=3 - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -437,7 +457,8 @@ def test_json_deserialize_image(): 'isFile':1, 'foreground_color': 'WHITE' } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -455,7 +476,8 @@ def test_json_deserialize_image(): bpp=2, isFile=1, foreground_color=NbglColor.WHITE - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized assert deserialized == deserialize_nbgl_json(serialized) @@ -476,7 +498,8 @@ def test_json_deserialize_image_file(): 'bpp': 'BPP_2' }, } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -489,7 +512,8 @@ def test_json_deserialize_image_file(): background_color=NbglColor.BLACK, bpp=NbglBpp.BPP_2 ), - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -514,7 +538,8 @@ def test_json_deserialize_qr_code(): 'version': 'QRCODE_V10', 'text': 'Qr code text qr code' } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -530,7 +555,8 @@ def test_json_deserialize_qr_code(): foreground_color=NbglColor.LIGHT_GRAY, version=NbglQrCodeVersion.QRCODE_V10, text='Qr code text qr code' - ) + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -556,9 +582,11 @@ def test_json_deserialize_keyboard(): 'letters_only': False, 'upper_case': True, 'mode': 'MODE_SPECIAL', - 'key_mask': 255 + 'key_mask': 255, + 'selected_char_index':2 } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -576,8 +604,10 @@ def test_json_deserialize_keyboard(): letters_only=False, upper_case=True, mode=NbglKeyboardMode.MODE_SPECIAL, - key_mask=255 - ) + key_mask=255, + selected_char_index=2 + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized @@ -603,9 +633,11 @@ def test_json_deserialize_keypad(): 'enable_backspace': True, 'enable_validate': False, 'enable_digits': True, - 'shuffled': False + 'shuffled': False, + 'selectedKey': 0 } - } + }, + 'id':1 } deserialized = \ NbglDrawObjectEvent( @@ -623,8 +655,10 @@ def test_json_deserialize_keypad(): enable_backspace=True, enable_validate=False, enable_digits=True, - shuffled=False - ) + shuffled=False, + selectedKey=0 + ), + id=1 ) assert serialize_nbgl_json(deserialized) == serialized diff --git a/lib_nbgl/src/nbgl_buttons.c b/lib_nbgl/src/nbgl_buttons.c new file mode 100644 index 000000000..b10e92070 --- /dev/null +++ b/lib_nbgl/src/nbgl_buttons.c @@ -0,0 +1,150 @@ +/** + * @file nbgl_buttons.c + * Implementation of buttons management in NBGL + */ + +#ifndef HAVE_SE_TOUCH +/********************* + * INCLUDES + *********************/ +#include +#include "nbgl_obj.h" +#include "nbgl_debug.h" +#include "nbgl_buttons.h" +#include "nbgl_screen.h" +#include "os_pic.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ +static uint8_t gButtonMask = 0; +static uint32_t gButtonSameMaskCounter = 0; + +/********************** + * VARIABLES + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static nbgl_buttonEvent_t maskToEvent(uint8_t mask) +{ + nbgl_buttonEvent_t event = INVALID_BUTTON_EVENT; + switch (mask) { + case RELEASED_MASK | LEFT_BUTTON | RIGHT_BUTTON: + event = BUTTON_BOTH_PRESSED; + break; + + case LEFT_BUTTON | RIGHT_BUTTON: + event = BUTTON_BOTH_TOUCHED; + break; + + case CONTINUOUS_MASK | LEFT_BUTTON: + event = BUTTON_LEFT_CONTINUOUS_PRESSED; + break; + + case RELEASED_MASK | LEFT_BUTTON: + event = BUTTON_LEFT_PRESSED; + break; + + case CONTINUOUS_MASK | RIGHT_BUTTON: + event = BUTTON_RIGHT_CONTINUOUS_PRESSED; + break; + + case RELEASED_MASK | RIGHT_BUTTON: + event = BUTTON_RIGHT_PRESSED; + break; + } + + return event; +} +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief Function to be called periodically to check touchscreen state + * and coordinates + * @param buttonState state of both buttons (only 2 LSB are used) + * @param currentTimeMs current time in ms + */ +void nbgl_buttonsHandler(uint8_t buttonState, uint32_t currentTimeMs) +{ + uint8_t button_mask; + uint32_t button_same_mask_counter; + + (void) currentTimeMs; + // enable speeded up long push (continuous) + if (buttonState == gButtonMask) { + if (buttonState == 0) { + // nothing to be done when both buttons released twice in a row + return; + } + // each 100ms ~ + gButtonSameMaskCounter++; + } + + // append the button mask + button_mask = gButtonMask | buttonState; + + // pre reset variable due to os_sched_exit + button_same_mask_counter = gButtonSameMaskCounter; + + if (buttonState == 0) { + // reset next state when both buttons are released + gButtonMask = 0; + gButtonSameMaskCounter = 0; + + // notify button released event + button_mask |= RELEASED_MASK; + } + else { + gButtonMask = button_mask; + } + + // reset counter when button mask changes + if (buttonState != gButtonMask) { + gButtonSameMaskCounter = 0; + } + + // if the same button(s) is pressed more than 800 ms + if (button_same_mask_counter >= CONTINOUS_PRESS_THRESHOLD) { + // fast bit when pressing and timing is right (tag the event every 300ms) + if ((button_same_mask_counter % CONTINUOUS_PRESS_PERIOD) == 0) { + button_mask |= CONTINUOUS_MASK; + } + + // discard the release event after a fastskip has been detected, to avoid strange at release + // behavior and also to enable user to cancel an operation by starting triggering the fast + // skip + button_mask &= ~RELEASED_MASK; + } + + nbgl_screen_t *topScreen = (nbgl_screen_t *) nbgl_screenGetTop(); + if ((topScreen != NULL) && (topScreen->buttonCallback != NULL)) { + nbgl_buttonEvent_t event = maskToEvent(button_mask); + if (event != INVALID_BUTTON_EVENT) { + topScreen->buttonCallback(topScreen, event); + } + } +} + +void nbgl_buttonsReset(void) +{ + // no button push so far + gButtonMask = 0; + gButtonSameMaskCounter = 0; +} +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/src/nbgl_draw.c b/lib_nbgl/src/nbgl_draw.c index b9832ca54..09e8feca5 100644 --- a/lib_nbgl/src/nbgl_draw.c +++ b/lib_nbgl/src/nbgl_draw.c @@ -16,7 +16,7 @@ #include "nbgl_side.h" #ifdef NBGL_QRCODE #include "qrcodegen.h" -#endif +#endif // NBGL_QRCODE #include "glyphs.h" #include "os_pic.h" #include "os_utils.h" @@ -40,11 +40,11 @@ typedef struct { uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX]; uint8_t QrDrawBuffer[QR_PIXEL_WIDTH_HEIGHT * QR_PIXEL_WIDTH_HEIGHT * QR_MAX_PIX_SIZE / 8]; } QrCodeBuffer_t; -#endif #define qrcode ((QrCodeBuffer_t *) ramBuffer)->qrcode #define tempBuffer ((QrCodeBuffer_t *) ramBuffer)->tempBuffer #define QrDrawBuffer ((QrCodeBuffer_t *) ramBuffer)->QrDrawBuffer +#endif // NBGL_QRCODE /********************** * STATIC PROTOTYPES @@ -53,6 +53,24 @@ typedef struct { /********************** * STATIC VARIABLES **********************/ +static const uint8_t quarter_disc_3px_1bpp[] = {0xEC, 0xFF}; +#ifndef HAVE_SE_TOUCH +static const uint8_t quarter_disc_3px_90_1bpp[] = {0x2F, 0xFF}; +static const uint8_t quarter_disc_3px_180_1bpp[] = {0x9B, 0xFF}; +static const uint8_t quarter_disc_3px_270_1bpp[] = {0xFA, 0x00}; +#endif // HAVE_SE_TOUCH + +static const uint8_t quarter_circle_3px_1bpp[] = {0x4C, 0x00}; +#ifndef HAVE_SE_TOUCH +static const uint8_t quarter_circle_3px_90_1bpp[] = {0x0D, 0x00}; +static const uint8_t quarter_circle_3px_180_1bpp[] = {0x19, 0x00}; +static const uint8_t quarter_circle_3px_270_1bpp[] = {0x58, 0x00}; +#else // HAVE_SE_TOUCH +static const nbgl_icon_details_t C_quarter_disc_3px_1bpp + = {2, 2, NBGL_BPP_1, false, quarter_disc_3px_1bpp}; +static const nbgl_icon_details_t C_quarter_circle_3px_1bpp + = {2, 2, NBGL_BPP_1, false, quarter_circle_3px_1bpp}; + static const uint8_t quarter_disc_4px_1bpp[] = {0x13, 0xFF}; static const nbgl_icon_details_t C_quarter_disc_4px_1bpp = {4, 4, NBGL_BPP_1, false, quarter_disc_4px_1bpp}; @@ -60,12 +78,26 @@ static const nbgl_icon_details_t C_quarter_disc_4px_1bpp static const uint8_t quarter_circle_4px_1bpp[] = {0x13, 0xFF}; static const nbgl_icon_details_t C_quarter_circle_4px_1bpp = {4, 4, NBGL_BPP_1, false, quarter_circle_4px_1bpp}; +#endif // HAVE_SE_TOUCH // indexed by nbgl_radius_t (except RADIUS_0_PIXELS) -static const uint8_t radiusValues[] = {4, 8, 16, 20, 24, 32, 40, 48}; - +static const uint8_t radiusValues[] = {3, +#ifdef HAVE_SE_TOUCH + 4, + 8, + 16, + 20, + 24, + 32, + 40, + 48 +#endif // HAVE_SE_TOUCH +}; + +#ifdef HAVE_SE_TOUCH // indexed by nbgl_radius_t (except RADIUS_0_PIXELS) -static const nbgl_icon_details_t *quarterDiscs[] = {&C_quarter_disc_4px_1bpp, +static const nbgl_icon_details_t *quarterDiscs[] = {&C_quarter_disc_3px_1bpp, + &C_quarter_disc_4px_1bpp, &C_quarter_round_8px_1bpp, &C_quarter_round_16px_1bpp, &C_quarter_round_20px_1bpp, @@ -75,7 +107,8 @@ static const nbgl_icon_details_t *quarterDiscs[] = {&C_quarter_disc_4px_1bpp, &C_quarter_round_48px_1bpp}; // indexed by nbgl_radius_t (except RADIUS_0_PIXELS) -static const nbgl_icon_details_t *quarterCircles[] = {&C_quarter_circle_4px_1bpp, +static const nbgl_icon_details_t *quarterCircles[] = {&C_quarter_circle_3px_1bpp, + &C_quarter_circle_4px_1bpp, &C_quarter_circle_8px_1bpp, &C_quarter_circle_16px_1bpp, &C_quarter_circle_20px_1bpp, @@ -83,6 +116,7 @@ static const nbgl_icon_details_t *quarterCircles[] = {&C_quarter_circle_4px_1bpp &C_quarter_circle_32px_1bpp, &C_quarter_circle_40px_1bpp, &C_quarter_circle_48px_1bpp}; +#endif // HAVE_SE_TOUCH #ifdef NBGL_QRCODE // ensure that the ramBuffer also used for image file decompression is big enough for QR code @@ -105,20 +139,23 @@ static void draw_circle_helper(int x_center, color_t innerColor, color_t backgroundColor) { - uint8_t *quarter_buffer = NULL; - nbgl_area_t area = {.bpp = NBGL_BPP_1, .backgroundColor = backgroundColor}; + const uint8_t *quarter_buffer = NULL; + nbgl_area_t area = {.bpp = NBGL_BPP_1, .backgroundColor = backgroundColor}; +#ifdef HAVE_SE_TOUCH // radius is not supported if (radiusIndex > RADIUS_48_PIXELS) { return; } if (borderColor == innerColor) { quarter_buffer - = (uint8_t *) ((nbgl_icon_details_t *) PIC(quarterDiscs[radiusIndex]))->bitmap; + = (const uint8_t *) ((const nbgl_icon_details_t *) PIC(quarterDiscs[radiusIndex])) + ->bitmap; } else { quarter_buffer - = (uint8_t *) ((nbgl_icon_details_t *) PIC(quarterCircles[radiusIndex]))->bitmap; + = (const uint8_t *) ((const nbgl_icon_details_t *) PIC(quarterCircles[radiusIndex])) + ->bitmap; } area.width = area.height = radiusValues[radiusIndex]; area.backgroundColor = backgroundColor; @@ -142,6 +179,39 @@ static void draw_circle_helper(int x_center, area.y0 = y_center - area.width; nbgl_frontDrawImage(&area, quarter_buffer, NO_TRANSFORMATION, borderColor); } +#else // HAVE_SE_TOUCH + // radius is not supported + if (radiusIndex > RADIUS_3_PIXELS) { + return; + } + area.width = area.height = radiusValues[radiusIndex]; + area.backgroundColor = backgroundColor; + if (quarter & BAGL_FILL_CIRCLE_3PI2_2PI) { // + area.x0 = x_center; + area.y0 = y_center; + quarter_buffer + = (borderColor == innerColor) ? quarter_disc_3px_180_1bpp : quarter_circle_3px_180_1bpp; + } + if (quarter & BAGL_FILL_CIRCLE_PI_3PI2) { // + area.x0 = x_center - area.width; + area.y0 = y_center; + quarter_buffer + = (borderColor == innerColor) ? quarter_disc_3px_270_1bpp : quarter_circle_3px_270_1bpp; + } + if (quarter & BAGL_FILL_CIRCLE_0_PI2) { // + area.x0 = x_center; + area.y0 = y_center - area.width; + quarter_buffer + = (borderColor == innerColor) ? quarter_disc_3px_90_1bpp : quarter_circle_3px_90_1bpp; + } + if (quarter & BAGL_FILL_CIRCLE_PI2_PI) { // + area.x0 = x_center - area.width; + area.y0 = y_center - area.width; + quarter_buffer + = (borderColor == innerColor) ? quarter_disc_3px_1bpp : quarter_circle_3px_1bpp; + } + nbgl_frontDrawImage(&area, quarter_buffer, NO_TRANSFORMATION, borderColor); +#endif // HAVE_SE_TOUCH } /********************** @@ -170,8 +240,16 @@ void nbgl_drawRoundedRect(const nbgl_area_t *area, nbgl_radius_t radiusIndex, co area->height); if (radiusIndex <= RADIUS_48_PIXELS) { +#ifndef HAVE_SE_TOUCH + if (radiusIndex > RADIUS_3_PIXELS) { + return; + } +#endif // HAVE_SE_TOUCH radius = radiusValues[radiusIndex]; } + else if (radiusIndex == RADIUS_1_PIXEL) { + radius = 1; + } else if (radiusIndex == RADIUS_0_PIXELS) { radius = 0; } @@ -205,6 +283,9 @@ void nbgl_drawRoundedRect(const nbgl_area_t *area, nbgl_radius_t radiusIndex, co rectArea.height = area->height - (2 * radius); nbgl_frontDrawRect(&rectArea); + if (radiusIndex == RADIUS_1_PIXEL) { + return; + } // Draw 4 quarters of disc draw_circle_helper(area->x0 + radius, area->y0 + radius, @@ -252,7 +333,6 @@ void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area, color_t innerColor, color_t borderColor) { - uint8_t maskTop, maskBottom; uint8_t radius; nbgl_area_t rectArea; @@ -309,6 +389,8 @@ void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area, } // border // 4 rectangles (with last pixel of each corner not set) +#ifdef HAVE_SE_TOUCH + uint8_t maskTop, maskBottom; if (stroke == 1) { maskTop = 0x1; maskBottom = 0x8; @@ -333,10 +415,20 @@ void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area, rectArea.y0 = area->y0; rectArea.width = area->width - 2 * radius; rectArea.height = 4; - nbgl_frontDrawHorizontalLine(&rectArea, maskTop, borderColor); // bottom + nbgl_frontDrawHorizontalLine(&rectArea, maskTop, borderColor); // top rectArea.x0 = area->x0 + radius; rectArea.y0 = area->y0 + area->height - 4; nbgl_frontDrawHorizontalLine(&rectArea, maskBottom, borderColor); // bottom +#else // HAVE_SE_TOUCH + rectArea.x0 = area->x0 + radius; + rectArea.y0 = area->y0; + rectArea.width = area->width - 2 * radius; + rectArea.height = stroke; + rectArea.backgroundColor = borderColor; + nbgl_frontDrawRect(&rectArea); // top + rectArea.y0 = area->y0 + area->height - stroke; + nbgl_frontDrawRect(&rectArea); // bottom +#endif // HAVE_SE_TOUCH if ((2 * radius) < area->height) { rectArea.x0 = area->x0; rectArea.y0 = area->y0 + radius; @@ -416,9 +508,10 @@ static uint16_t get_bitmap_byte_cnt(const nbgl_font_t *font, uint8_t charId) uint16_t baseId = charId - font->first_char; if (charId < font->last_char) { - nbgl_font_character_t *character = (nbgl_font_character_t *) PIC(&font->characters[baseId]); - nbgl_font_character_t *nextCharacter - = (nbgl_font_character_t *) PIC(&font->characters[baseId + 1]); + const nbgl_font_character_t *character + = (const nbgl_font_character_t *) PIC(&font->characters[baseId]); + const nbgl_font_character_t *nextCharacter + = (const nbgl_font_character_t *) PIC(&font->characters[baseId + 1]); return (nextCharacter->bitmap_offset - character->bitmap_offset); } else if (charId == font->last_char) { @@ -436,11 +529,11 @@ static uint16_t get_bitmap_byte_cnt(const nbgl_font_t *font, uint8_t charId) * @param fontId font to be used * @param fontColor color to use for font */ -void nbgl_drawText(const nbgl_area_t *area, - const char *text, - uint16_t textLen, - nbgl_font_id_e fontId, - color_t fontColor) +nbgl_font_id_e nbgl_drawText(const nbgl_area_t *area, + const char *text, + uint16_t textLen, + nbgl_font_id_e fontId, + color_t fontColor) { // text is a series of characters, each character being a bitmap // we need to align bitmaps on width multiple of 4 limitation. @@ -467,18 +560,18 @@ void nbgl_drawText(const nbgl_area_t *area, rectArea.bpp = (nbgl_bpp_t) font->bpp; while (textLen > 0) { - nbgl_font_character_t *character; - uint8_t char_width; - uint32_t unicode; - bool is_unicode; - uint8_t *char_buffer; - int16_t char_x_min; - int16_t char_y_min; - int16_t char_x_max; - int16_t char_y_max; - uint16_t char_byte_cnt; - uint8_t encoding; - uint8_t nb_skipped_bytes; + const nbgl_font_character_t *character; + uint8_t char_width; + uint32_t unicode; + bool is_unicode; + const uint8_t *char_buffer; + int16_t char_x_min; + int16_t char_y_min; + int16_t char_x_max; + int16_t char_y_max; + uint16_t char_byte_cnt; + uint8_t encoding; + uint8_t nb_skipped_bytes; unicode = nbgl_popUnicodeChar((const uint8_t **) &text, &textLen, &is_unicode); @@ -492,7 +585,7 @@ void nbgl_drawText(const nbgl_area_t *area, } char_width = unicodeCharacter->width; #if defined(HAVE_LANGUAGE_PACK) - char_buffer = (uint8_t *) unicode_ctx->bitmap; + char_buffer = unicode_ctx->bitmap; char_buffer += unicodeCharacter->bitmap_offset; char_x_max = char_width; @@ -522,13 +615,34 @@ void nbgl_drawText(const nbgl_area_t *area, #endif // HAVE_UNICODE_SUPPORT } else { + if (unicode == '\f') { + break; + } + // if \b, switch fontId + else if (unicode == '\b') { + if (fontId == BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp) { // switch to bold + fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + unicode_ctx = nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = (const nbgl_font_t *) nbgl_getFont(fontId); + } + else if (fontId == BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp) { // switch to regular + fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + unicode_ctx = nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = (const nbgl_font_t *) nbgl_getFont(fontId); + } + continue; + } // if not supported char, go to next one if ((unicode < font->first_char) || (unicode > font->last_char)) { continue; } - character - = (nbgl_font_character_t *) PIC(&font->characters[unicode - font->first_char]); - char_buffer = (uint8_t *) PIC(&font->bitmap[character->bitmap_offset]); + character = (const nbgl_font_character_t *) PIC( + &font->characters[unicode - font->first_char]); + char_buffer = (const uint8_t *) PIC(&font->bitmap[character->bitmap_offset]); char_width = character->width; encoding = character->encoding; @@ -569,8 +683,9 @@ void nbgl_drawText(const nbgl_area_t *area, else { nbgl_frontDrawImage(&rectArea, char_buffer, NO_TRANSFORMATION, fontColor); } - x += char_width; + x += char_width - font->char_kerning; } + return fontId; } #ifdef NBGL_QRCODE diff --git a/lib_nbgl/src/nbgl_flow.c b/lib_nbgl/src/nbgl_flow.c new file mode 100644 index 000000000..577478b28 --- /dev/null +++ b/lib_nbgl/src/nbgl_flow.c @@ -0,0 +1,226 @@ +/** + * @file nbgl_flow.c + * @brief Implementation of flow management + */ + +#ifdef NBGL_STEP +/********************* + * INCLUDES + *********************/ +#include +#include "nbgl_debug.h" +#include "nbgl_flow.h" +#include "glyphs.h" +#include "os_pic.h" +#include "ux.h" + +/********************* + * DEFINES + *********************/ +///< Maximum number of layers for flow, cannot be greater than max number of step layers +#define NB_MAX_LAYERS 3 + +/********************** + * TYPEDEFS + **********************/ +typedef struct FlowContext_s { + const nbgl_stepDesc_t *steps; + uint8_t curStep; + uint8_t nbSteps; + bool loop; + bool modal; + nbgl_step_t stepCtx; +} FlowContext_t; + +/********************** + * STATIC VARIABLES + **********************/ +static FlowContext_t contexts[NB_MAX_LAYERS]; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void actionCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event); + +// returns a non-used flow context from the contexts[] array, or NULL if not found +static FlowContext_t *getFreeContext(bool modal) +{ + FlowContext_t *ctx = NULL; + + if (!modal) { + // Index 0 is reserved for background + ctx = &contexts[0]; + } + else { + uint32_t i = 1; + while (i < NB_MAX_LAYERS) { + if (contexts[i].stepCtx == NULL) { + ctx = &contexts[i]; + break; + } + i++; + } + } + if (ctx == NULL) { + LOG_FATAL(FLOW_LOGGER, "getFreeContext(): no available context\n"); + } + else { + ctx->modal = modal; + } + return ctx; +} + +// returns the flow context from the contexts[] array matching with the given step handler, or NULL +// if not found +static FlowContext_t *getContextFromStepCtx(nbgl_step_t stepCtx) +{ + FlowContext_t *ctx = NULL; + uint32_t i = 0; + while (i < NB_MAX_LAYERS) { + if (contexts[i].stepCtx == stepCtx) { + ctx = &contexts[i]; + break; + } + i++; + } + if (ctx == NULL) { + LOG_WARN(FLOW_LOGGER, "getContextFromStepCtx(): no matching context\n"); + } + return ctx; +} + +// draws a step with the provided parameters, using the context provided as @ref ctx +static void drawStep(FlowContext_t *ctx, + nbgl_stepPosition_t pos, + bool modal, + const nbgl_icon_details_t *icon, + const char *txt, + const char *subTxt) +{ + nbgl_layoutCenteredInfo_t info; + if ((ctx->loop) && (ctx->nbSteps > 1)) { + pos |= NEITHER_FIRST_NOR_LAST_STEP; + } + else { + pos |= GET_POS_OF_STEP(ctx->curStep, ctx->nbSteps); + } + + if (icon == NULL) { + ctx->stepCtx + = nbgl_stepDrawText(pos, actionCallback, NULL, txt, subTxt, REGULAR_INFO, modal); + } + else { + info.icon = icon; + info.text1 = txt; + info.text2 = subTxt; + info.onTop = false; + info.style = REGULAR_INFO; + ctx->stepCtx = nbgl_stepDrawCenteredInfo(pos, actionCallback, NULL, &info, modal); + } +} + +// function called on key action of the current step, if not an internal navigation in a multi-pages +// text step +static void actionCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event) +{ + nbgl_stepPosition_t pos; + FlowContext_t *ctx = getContextFromStepCtx(stepCtx); + + if (!ctx) { + return; + } + LOG_DEBUG(FLOW_LOGGER, "actionCallback: event = 0x%X, step = %d\n", event, ctx->curStep); + // if navigation to the previous step + if ((event == BUTTON_LEFT_PRESSED) && (ctx->curStep > 0)) { + ctx->curStep--; + pos = BACKWARD_DIRECTION; + } + // if navigation to the next step + else if ((event == BUTTON_RIGHT_PRESSED) && (ctx->curStep < (int) (ctx->nbSteps - 1))) { + ctx->curStep++; + pos = FORWARD_DIRECTION; + } + // if action on the current step + else if (event == BUTTON_BOTH_PRESSED) { + if (ctx->steps[ctx->curStep].callback != NULL) { + ctx->steps[ctx->curStep].callback(); + } + return; + } + else { + return; + } + const nbgl_stepDesc_t *step = &ctx->steps[ctx->curStep]; + const char *txt = (step->text != NULL) + ? step->text + : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL); + // release the current step before opening new one + nbgl_stepRelease((nbgl_step_t) ctx->stepCtx); + if (step->init != NULL) { + step->init(); + } + drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText); + nbgl_refresh(); +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief draw the given flow, starting at the given step + * + * @param steps array of step descriptions + * @param nbSteps number of steps in above array + * @param initStep init step in above array + * @param loop if true, loop between last and first step, in both direction + * @param modal if true, screens are modal + * @return >= 0 if OK, < 0 otherwise + */ +nbgl_flow_t nbgl_flowDraw(const nbgl_stepDesc_t *steps, + uint8_t nbSteps, + uint8_t initStep, + bool loop, + bool modal) +{ + const nbgl_stepDesc_t *step = &steps[initStep]; + const char *txt = (step->text != NULL) + ? step->text + : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL); + nbgl_stepPosition_t pos = FORWARD_DIRECTION; + FlowContext_t *ctx = getFreeContext(modal); + + if (!ctx) { + return NULL; + } + + ctx->nbSteps = nbSteps; + ctx->curStep = initStep; + ctx->steps = steps; + ctx->loop = loop; + if (step->init != NULL) { + step->init(); + } + + drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText); + nbgl_refresh(); + return (nbgl_flow_t) ctx; +} + +/** + * @brief release the given flow + * + * @param flow flow to release + */ +void nbgl_flowRelease(nbgl_flow_t flow) +{ + FlowContext_t *ctx = (FlowContext_t *) flow; + + if (!ctx) { + LOG_WARN(FLOW_LOGGER, "nbgl_flowRelease: NULL context!"); + return; + } + nbgl_stepRelease(ctx->stepCtx); + ctx->stepCtx = NULL; +} +#endif // NBGL_STEP diff --git a/lib_nbgl/src/nbgl_fonts.c b/lib_nbgl/src/nbgl_fonts.c index b8e6926b8..e457405eb 100644 --- a/lib_nbgl/src/nbgl_fonts.c +++ b/lib_nbgl/src/nbgl_fonts.c @@ -52,6 +52,9 @@ extern const LANGUAGE_PACK *language_pack; #include "nbgl_font_inter_regular_24_1bpp.inc" #include "nbgl_font_inter_semibold_24_1bpp.inc" #include "nbgl_font_inter_medium_32_1bpp.inc" +#include "nbgl_font_open_sans_extrabold_11.inc" +#include "nbgl_font_open_sans_regular_11.inc" +#include "nbgl_font_open_sans_light_16.inc" const nbgl_font_t *const C_nbgl_fonts[] = { @@ -186,7 +189,7 @@ static uint8_t getCharWidth(const nbgl_font_t *font, uint32_t unicode, bool is_u if (!unicodeCharacter) { return 0; } - return unicodeCharacter->width; + return unicodeCharacter->width - font->char_kerning; #else // HAVE_UNICODE_SUPPORT return 0; #endif // HAVE_UNICODE_SUPPORT @@ -198,7 +201,7 @@ static uint8_t getCharWidth(const nbgl_font_t *font, uint32_t unicode, bool is_u } character = (const nbgl_font_character_t *) PIC(&font->characters[unicode - font->first_char]); - return character->width; + return character->width - font->char_kerning; } } @@ -232,7 +235,6 @@ static uint16_t getTextWidth(nbgl_font_id_e fontId, bool is_unicode; unicode = nbgl_popUnicodeChar((const uint8_t **) &text, &textLen, &is_unicode); - if (unicode == '\n') { if (breakOnLineEnd) { break; @@ -241,7 +243,24 @@ static uint16_t getTextWidth(nbgl_font_id_e fontId, line_width = 0; continue; } - + // if \b, switch fontId + else if (unicode == '\b') { + if (fontId == BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp) { // switch to bold + fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + else if (fontId == BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp) { // switch to regular + fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + continue; + } char_width = getCharWidth(font, unicode, is_unicode); line_width += char_width; @@ -378,7 +397,13 @@ uint16_t nbgl_getTextHeight(nbgl_font_id_e fontId, const char *text) uint16_t nbgl_getTextLength(const char *text) { const char *origText = text; - while ((*text) && (*text != '\n')) { + while (*text) { + if (*text == '\f') { + break; + } + else if (*text == '\n') { + break; + } text++; } return text - origText; @@ -420,11 +445,35 @@ void nbgl_getTextMaxLenAndWidth(nbgl_font_id_e fontId, uint16_t curTextLen = textLen; unicode = nbgl_popUnicodeChar((const uint8_t **) &text, &textLen, &is_unicode); + // if \f, exit loop + if (unicode == '\f') { + *len += curTextLen - textLen; + break; + } // if \n, exit - if (unicode == '\n') { + else if (unicode == '\n') { *len += curTextLen - textLen; return; } + // if \b, switch fontId + else if (unicode == '\b') { + if (fontId == BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp) { // switch to bold + fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + else if (fontId == BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp) { // switch to regular + fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + *len += curTextLen - textLen; + continue; + } char_width = getCharWidth(font, unicode, is_unicode); if (char_width == 0) { @@ -457,6 +506,7 @@ void nbgl_getTextMaxLenAndWidth(nbgl_font_id_e fontId, * @param maxWidth maximum width in bytes, if text is greater than that the parsing is escaped * @param maxNbLines maximum number of lines, if text is greater than that the parsing is escaped * @param len (output) consumed bytes in text fitting in maxWidth + * @param wrapping if true, lines are split on separators like spaces, \n... * * @return true if maxNbLines is reached, false otherwise * @@ -465,12 +515,16 @@ bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t maxNbLines, - uint16_t *len) + uint16_t *len, + bool wrapping) { - const nbgl_font_t *font = nbgl_getFont(fontId); - uint16_t textLen = strlen(text); - uint16_t width = 0; - const char *origText = text; + const nbgl_font_t *font = nbgl_getFont(fontId); + uint16_t textLen = strlen(text); + uint16_t width = 0; + const char *lastDelimiter = NULL; + uint32_t lenAtLastDelimiter = 0; + const char *origText = text; + const char *previousText; #ifdef HAVE_UNICODE_SUPPORT nbgl_getUnicodeFont(fontId); @@ -481,13 +535,43 @@ bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, uint32_t unicode; bool is_unicode; - unicode = nbgl_popUnicodeChar((const uint8_t **) &text, &textLen, &is_unicode); + previousText = text; + unicode = nbgl_popUnicodeChar((const uint8_t **) &text, &textLen, &is_unicode); + // memorize cursors at last found delimiter + if ((wrapping == true) && (IS_WORD_DELIM(unicode))) { + lastDelimiter = text; + lenAtLastDelimiter = textLen; + } + // if \n, reset width if (unicode == '\n') { maxNbLines--; width = 0; continue; } + // if \f, exit + else if (unicode == '\f') { + maxNbLines = 0; + continue; + } + // if \b, switch fontId + else if (unicode == '\b') { + if (fontId == BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp) { // switch to bold + fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + else if (fontId == BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp) { // switch to regular + fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + continue; + } char_width = getCharWidth(font, unicode, is_unicode); if (char_width == 0) { @@ -495,6 +579,14 @@ bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, } if ((width + char_width) > maxWidth) { + if ((wrapping == true) && (lastDelimiter != NULL)) { + text = lastDelimiter; + lastDelimiter = NULL; + textLen = lenAtLastDelimiter; + } + else { + text = previousText; + } width = 0; maxNbLines--; if (maxNbLines == 0) { @@ -603,13 +695,35 @@ uint16_t nbgl_getTextNbLinesInWidth(nbgl_font_id_e fontId, lastDelimiter = prevText; lenAtLastDelimiter = textLen; } + // if \f, exit loop + if (unicode == '\f') { + break; + } // if \n, increment the number of lines - if (unicode == '\n') { + else if (unicode == '\n') { nbLines++; width = 0; lastDelimiter = NULL; continue; } + // if \b, switch fontId + else if (unicode == '\b') { + if (fontId == BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp) { // switch to bold + fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + else if (fontId == BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp) { // switch to regular + fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + continue; + } char_width = getCharWidth(font, unicode, is_unicode); if (char_width == 0) { @@ -636,6 +750,115 @@ uint16_t nbgl_getTextNbLinesInWidth(nbgl_font_id_e fontId, return nbLines; } +/** + * @brief compute the number of pages of nbLinesPerPage lines per page of the given text fitting in + * the given maxWidth + * + * @param fontId font ID + * @param text UTF-8 text to get the number of pages from + * @param nbLinesPerPage number of lines in a page + * @param maxWidth maximum width in which the text must fit + * @return the number of pages in the given text + */ +uint8_t nbgl_getTextNbPagesInWidth(nbgl_font_id_e fontId, + const char *text, + uint8_t nbLinesPerPage, + uint16_t maxWidth) +{ + const nbgl_font_t *font = nbgl_getFont(fontId); + uint16_t width = 0; + uint16_t nbLines = 0; + uint8_t nbPages = 1; + uint16_t textLen = strlen(text); + const char *lastDelimiter = NULL; + uint32_t lenAtLastDelimiter = 0; + const char *prevText = NULL; + +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + // end loop when a '\0' is uncountered + while (textLen) { + uint8_t char_width; + uint32_t unicode; + bool is_unicode; + + // memorize the last char + prevText = text; + unicode = nbgl_popUnicodeChar((const uint8_t **) &text, &textLen, &is_unicode); + + // memorize cursors at last found space + if (IS_WORD_DELIM(unicode)) { + lastDelimiter = prevText; + lenAtLastDelimiter = textLen; + } + // if \f, updates page number + if (unicode == '\f') { + nbPages++; + nbLines = 0; + width = 0; + continue; + } + // if \n, increment the number of lines + else if (unicode == '\n') { + nbLines++; + if (nbLines == nbLinesPerPage) { + nbPages++; + nbLines = 0; + } + + width = 0; + lastDelimiter = NULL; + continue; + } + // if \b, switch fontId + else if (unicode == '\b') { + if (fontId == BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp) { // switch to bold + fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + else if (fontId == BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp) { // switch to regular + fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; +#ifdef HAVE_UNICODE_SUPPORT + nbgl_getUnicodeFont(fontId); +#endif // HAVE_UNICODE_SUPPORT + font = nbgl_getFont(fontId); + } + continue; + } + + char_width = getCharWidth(font, unicode, is_unicode); + if (char_width == 0) { + continue; + } + + // if about to reach max len, increment the number of lines/pages + if ((width + char_width) > maxWidth) { + if (lastDelimiter != NULL) { + text = lastDelimiter + 1; + lastDelimiter = NULL; + textLen = lenAtLastDelimiter; + width = 0; + } + else { + width = char_width; + } + nbLines++; + if (nbLines == nbLinesPerPage) { + nbPages++; + nbLines = 0; + } + } + else { + width += char_width; + } + } + return nbPages; +} + /** * @brief return the height of the given multiline text, with the given font. * diff --git a/lib_nbgl/src/nbgl_layout.c b/lib_nbgl/src/nbgl_layout.c index cd16d0967..1e28fe3e1 100644 --- a/lib_nbgl/src/nbgl_layout.c +++ b/lib_nbgl/src/nbgl_layout.c @@ -18,6 +18,7 @@ #include "glyphs.h" #include "os_pic.h" #include "os_helpers.h" +#include "lcx_rng.h" /********************* * DEFINES @@ -32,21 +33,25 @@ #define NB_MAX_LAYOUTS 3 // used by container +#ifdef HAVE_SE_TOUCH #define NB_MAX_CONTAINER_CHILDREN 20 +#endif // HAVE_SE_TOUCH // used by screen -#define NB_MAX_SCREEN_CHILDREN 6 +#define NB_MAX_SCREEN_CHILDREN 7 /** * @brief Max number of complex objects with callback retrievable from pool * */ +#ifdef HAVE_SE_TOUCH #define LAYOUT_OBJ_POOL_LEN 10 #define TAG_VALUE_ICON_WIDTH 32 #define TOUCHABLE_BAR_HEIGHT 88 #define FOOTER_HEIGHT 80 +#endif // HAVE_SE_TOUCH // refresh period of the spinner, in ms #define SPINNER_REFRESH_PERIOD 400 @@ -60,18 +65,18 @@ return NO_MORE_OBJ_ERROR; \ } -#define AVAILABLE_WIDTH (SCREEN_WIDTH - (2 * BORDER_MARGIN)) - /********************** * TYPEDEFS **********************/ +#ifdef HAVE_SE_TOUCH typedef struct { nbgl_obj_t *obj; uint8_t token; // user token, attached to callback uint8_t index; // index within the token tune_index_e tuneId; // if not @ref NBGL_NO_TUNE, a tune will be played } layoutObj_t; +#endif // HAVE_SE_TOUCH /** * @brief Structure containing all information about the current layout. @@ -79,14 +84,17 @@ typedef struct { * */ typedef struct nbgl_layoutInternal_s { - bool modal; ///< if true, means the screen is a modal + bool modal; ///< if true, means the screen is a modal +#ifdef HAVE_SE_TOUCH bool withLeftBorder; ///< if true, draws a light gray left border on the whole height of the ///< screen +#endif // HAVE_SE_TOUCH uint8_t layer; ///< if >0, puts the layout on top of screen stack (modal). Otherwise puts on ///< background (for apps) uint8_t nbChildren; ///< number of children in above array nbgl_obj_t **children; ///< children for main screen +#ifdef HAVE_SE_TOUCH nbgl_obj_type_t bottomContainerUsage; uint8_t nbPages; ///< number of pages for navigation bar uint8_t activePage; ///< index of active page for navigation bar @@ -99,6 +107,9 @@ typedef struct nbgl_layoutInternal_s { uint8_t nbUsedCallbackObjs; nbgl_container_t *container; +#else // HAVE_SE_TOUCH + nbgl_layoutButtonCallback_t callback; // user callback for all controls +#endif // HAVE_SE_TOUCH } nbgl_layoutInternal_t; @@ -112,6 +123,7 @@ typedef struct nbgl_layoutInternal_s { */ static nbgl_layoutInternal_t gLayout[NB_MAX_LAYOUTS] = {0}; +#ifdef HAVE_SE_TOUCH #ifdef NBGL_KEYBOARD static nbgl_button_t *choiceButtons[NB_MAX_SUGGESTION_BUTTONS]; #endif // NBGL_KEYBOARD @@ -122,11 +134,13 @@ static char numText[5]; // numbers of touchable controls for the whole page static uint8_t nbTouchableControls = 0; +#endif // HAVE_SE_TOUCH /********************** * STATIC PROTOTYPES **********************/ +#ifdef HAVE_SE_TOUCH #ifdef HAVE_DISPLAY_FAST_MODE // Unit step in % of touchable progress bar #define HOLD_TO_APPROVE_STEP_PERCENT (10) @@ -384,6 +398,49 @@ static void radioTouchCallback(nbgl_obj_t *obj, } } } +#else // HAVE_SE_TOUCH +static void buttonCallback(nbgl_screen_t *screen, nbgl_buttonEvent_t buttonEvent) +{ + uint8_t i = NB_MAX_LAYOUTS; + nbgl_layoutInternal_t *layout = NULL; + + // parse all layouts (starting with modals) to find the object + while (i > 0) { + i--; + if ((screen->index == gLayout[i].layer) && (gLayout[i].nbChildren > 0)) { + // found + layout = &gLayout[i]; + break; + } + } + if (layout == NULL) { + LOG_WARN( + LAYOUT_LOGGER, + "touchCallback(): screen->index = %d, buttonEvent = %d, no matching active layout\n", + screen->index, + buttonEvent); + return; + } + // special case of keypad + nbgl_obj_t *obj = nbgl_screenContainsObjType(screen, KEYPAD); + if (obj) { + nbgl_keypadCallback(obj, buttonEvent); + return; + } + else { + obj = nbgl_screenContainsObjType(screen, KEYBOARD); + if (obj) { + nbgl_keyboardCallback(obj, buttonEvent); + return; + } + } + if (layout->callback != NULL) { + layout->callback((nbgl_layout_t *) layout, buttonEvent); + } +} +#endif // HAVE_SE_TOUCH + +#ifdef HAVE_SE_TOUCH // callback for spinner ticker static void spinnerTickerCallback(void) @@ -516,21 +573,42 @@ static layoutObj_t *addCallbackObj(nbgl_layoutInternal_t *layout, } /** - * @brief adds the given obj to the container + * @brief adds the given obj to the main container * * @param layout * @param obj */ static void addObjectToLayout(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj) { + if (layout->container->nbChildren == NB_MAX_CONTAINER_CHILDREN) { + LOG_FATAL(LAYOUT_LOGGER, "addObjectToLayout(): No more object\n"); + } layout->container->children[layout->container->nbChildren] = obj; layout->container->nbChildren++; } +#else // HAVE_SE_TOUCH + +/** + * @brief adds the given obj to the layout + * + * @param layout + * @param obj + */ +static void addObjectToLayout(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj) +{ + if (layout->nbChildren == NB_MAX_SCREEN_CHILDREN) { + LOG_FATAL(LAYOUT_LOGGER, "addObjectToLayout(): No more object\n"); + } + layout->children[layout->nbChildren] = obj; + layout->nbChildren++; +} +#endif // HAVE_SE_TOUCH /********************** * GLOBAL FUNCTIONS **********************/ +#ifdef HAVE_SE_TOUCH /** * @brief returns a layout of the given type. The layout is reset * @@ -710,6 +788,97 @@ int nbgl_layoutAddNavigationBar(nbgl_layout_t *layout, const nbgl_layoutNavigati return 0; } +#else // HAVE_SE_TOUCH +/** + * @brief returns a layout of the given type. The layout is reset + * + * @param description description of layout + * @return a pointer to the corresponding layout + */ +nbgl_layout_t *nbgl_layoutGet(const nbgl_layoutDescription_t *description) +{ + nbgl_layoutInternal_t *layout = NULL; + + // find an empty layout in the proper "layer" + if (description->modal) { + if (gLayout[1].nbChildren == 0) { + layout = &gLayout[1]; + } + else if (gLayout[2].nbChildren == 0) { + layout = &gLayout[2]; + } + } + else { + // automatically "release" a potentially opened non-modal layout + gLayout[0].nbChildren = 0; + layout = &gLayout[0]; + } + if (layout == NULL) { + LOG_WARN(LAYOUT_LOGGER, "nbgl_layoutGet(): impossible to get a layout!\n"); + return NULL; + } + + // reset globals + memset(layout, 0, sizeof(nbgl_layoutInternal_t)); + + layout->callback = (nbgl_layoutButtonCallback_t) PIC(description->onActionCallback); + layout->modal = description->modal; + if (description->modal) { + layout->layer = nbgl_screenPush(&layout->children, + NB_MAX_SCREEN_CHILDREN, + &description->ticker, + (nbgl_buttonCallback_t) buttonCallback); + } + else { + nbgl_screenSet(&layout->children, + NB_MAX_SCREEN_CHILDREN, + &description->ticker, + (nbgl_buttonCallback_t) buttonCallback); + layout->layer = 0; + } + + return (nbgl_layout_t *) layout; +} + +/** + * @brief Creates navigation arrows on side(s) of the screen + * + * @param layout the current layout + * @param info structure giving the description of the navigation + * @return >= 0 if OK + */ +int nbgl_layoutAddNavigation(nbgl_layout_t *layout, nbgl_layoutNavigation_t *info) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddNavigation():\n"); + if (layout == NULL) { + return -1; + } + + nbgl_image_t *image; + if (info->indication & LEFT_ARROW) { + image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer); + image->foregroundColor = WHITE; + image->buffer = (info->direction == HORIZONTAL_NAV) ? &C_icon_left : &C_icon_up; + image->obj.area.bpp = NBGL_BPP_1; + image->obj.alignment = MID_LEFT; + addObjectToLayout(layoutInt, (nbgl_obj_t *) image); + } + if (info->indication & RIGHT_ARROW) { + image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer); + image->foregroundColor = WHITE; + image->buffer = (info->direction == HORIZONTAL_NAV) ? &C_icon_right : &C_icon_down; + image->obj.area.bpp = NBGL_BPP_1; + image->obj.alignment = MID_RIGHT; + addObjectToLayout(layoutInt, (nbgl_obj_t *) image); + } + return 0; +} +#endif // HAVE_SE_TOUCH + +#ifdef HAVE_SE_TOUCH + /** * @brief Creates a centered button at bottom of main container * @brief incompatible with navigation bar @@ -1380,148 +1549,431 @@ int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredI return 0; } -#ifdef NBGL_QRCODE +#else // HAVE_SE_TOUCH /** - * @brief Creates an area on the center of the main panel, with a QRCode, - * a possible text in black (bold) under it, and a possible text in black under it + * @brief Creates an area with given text and sub text, using the given style * * @param layout the current layout - * @param info structure giving the description of buttons (texts, icons, layout) + * @param text main text for the switch + * @param subText description under main text (NULL terminated, single line, may be null) + * @param style if @ref REGULAR_INFO, use regular font for text, otherwise use bold font for text * @return >= 0 if OK */ -int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info) +int nbgl_layoutAddText(nbgl_layout_t *layout, + const char *text, + const char *subText, + nbgl_centeredInfoStyle_t style) { nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; nbgl_container_t *container; - nbgl_text_area_t *textArea = NULL; - nbgl_qrcode_t *qrcode; + nbgl_text_area_t *textArea; uint16_t fullHeight = 0; - LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddQRCode():\n"); + UNUSED(subText); + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddText():\n"); if (layout == NULL) { return -1; } - container = (nbgl_container_t *) nbgl_objPoolGet(CONTAINER, layoutInt->layer); - // get container children (max 2 (QRCode + text1/text2)) - container->children = nbgl_containerPoolGet(2, layoutInt->layer); - container->nbChildren = 0; - - qrcode = (nbgl_qrcode_t *) nbgl_objPoolGet(QR_CODE, layoutInt->layer); - // version is forced to V10 if url is longer than 62 characters - if (strlen(PIC(info->url)) > 62) { - qrcode->version = QRCODE_V10; - } - else { - qrcode->version = QRCODE_V4; - } - qrcode->foregroundColor = BLACK; - // in QR V4, we use 8*8 screen pixels for one QR pixel - // in QR V10, we use 4*4 screen pixels for one QR pixel - qrcode->obj.area.width - = (qrcode->version == QRCODE_V4) ? (QR_V4_NB_PIX_SIZE * 8) : (QR_V10_NB_PIX_SIZE * 4); - qrcode->obj.area.height = qrcode->obj.area.width; - qrcode->text = PIC(info->url); - qrcode->obj.area.bpp = NBGL_BPP_1; - qrcode->obj.alignment = TOP_MIDDLE; - qrcode->obj.alignmentMarginY = 24; - - fullHeight += qrcode->obj.area.height; - container->children[container->nbChildren] = (nbgl_obj_t *) qrcode; - container->nbChildren++; - - if (info->text1 != NULL) { - textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); - textArea->textColor = BLACK; - textArea->text = PIC(info->text1); - textArea->textAlignment = CENTER; - textArea->fontId = (info->largeText1 == true) ? BAGL_FONT_INTER_MEDIUM_32px - : BAGL_FONT_INTER_REGULAR_24px; - textArea->wrapping = true; - textArea->obj.area.width = AVAILABLE_WIDTH; - textArea->obj.area.height = nbgl_getTextHeightInWidth( - textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping); - textArea->obj.alignment = BOTTOM_MIDDLE; - textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1]; - textArea->obj.alignmentMarginY = 40; - - fullHeight += textArea->obj.area.height; - - container->children[container->nbChildren] = (nbgl_obj_t *) textArea; + // get container children + container->nbChildren = 1; + if (subText != NULL) { container->nbChildren++; } - else if (info->text2 != NULL) { - textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); - textArea->textColor = DARK_GRAY; - textArea->text = PIC(info->text2); - textArea->textAlignment = CENTER; - textArea->fontId = BAGL_FONT_INTER_REGULAR_24px; - textArea->wrapping = true; - textArea->obj.area.width = AVAILABLE_WIDTH; - textArea->obj.area.height = nbgl_getTextHeightInWidth( - textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping); - textArea->obj.alignment = BOTTOM_MIDDLE; - textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1]; - textArea->obj.alignmentMarginY = 40; - fullHeight += textArea->obj.area.height; + container->children = nbgl_containerPoolGet(container->nbChildren, layoutInt->layer); + container->obj.area.width = AVAILABLE_WIDTH; - container->children[container->nbChildren] = (nbgl_obj_t *) textArea; - container->nbChildren++; + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + textArea->textColor = WHITE; + textArea->text = PIC(text); + textArea->textAlignment = CENTER; + textArea->fontId = (style == REGULAR_INFO) ? BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp + : BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; + textArea->obj.area.width = AVAILABLE_WIDTH; + + uint16_t nbLines + = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true); + // if more than available lines on screen + if (nbLines > NB_MAX_LINES) { + uint16_t len; + + nbLines = NB_MAX_LINES; + textArea->nbMaxLines = NB_MAX_LINES; + nbgl_getTextMaxLenInNbLines( + textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true); + textArea->len = len; + } + const nbgl_font_t *font = nbgl_getFont(textArea->fontId); + textArea->obj.area.height = nbLines * font->line_height; + textArea->wrapping = true; + textArea->obj.alignment = TOP_MIDDLE; + fullHeight += textArea->obj.area.height; + container->children[0] = (nbgl_obj_t *) textArea; + + if (subText != NULL) { + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + textArea->textColor = WHITE; + textArea->text = PIC(subText); + textArea->wrapping = true; + textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; + textArea->obj.area.width = AVAILABLE_WIDTH; + nbLines + = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true); + // if more than available lines on screen + if (nbLines > (NB_MAX_LINES - 1)) { + uint16_t len; + nbLines = NB_MAX_LINES - 1; + textArea->nbMaxLines = nbLines; + nbgl_getTextMaxLenInNbLines( + textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true); + textArea->len = len; + } + textArea->obj.area.height = nbLines * font->line_height; + textArea->textAlignment = CENTER; + textArea->obj.alignment = NO_ALIGNMENT; + textArea->obj.alignmentMarginY = 2; + fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY; + container->children[1] = (nbgl_obj_t *) textArea; } container->obj.area.height = fullHeight; container->layout = VERTICAL; - // center the QRCode only if it's the first (and probably only) child - if (layoutInt->container->nbChildren == 0) { - container->obj.alignment = CENTER; - } - else { - container->obj.alignment = BOTTOM_MIDDLE; - container->obj.alignmentMarginY = BORDER_MARGIN; - container->obj.alignTo - = layoutInt->container->children[layoutInt->container->nbChildren - 1]; - } - - container->obj.area.width = AVAILABLE_WIDTH; - - // set this new container as child of main container + container->obj.alignment = CENTER; + // set this new obj as child of main container addObjectToLayout(layoutInt, (nbgl_obj_t *) container); return 0; } -#endif // NBGL_QRCODE /** - * @brief Creates two buttons to make a choice. Both buttons are mandatory + * @brief Creates a menu list (only for nanos) with the given parameters. The navigation (and + * selection) must be handled by the caller * * @param layout the current layout - * @param info structure giving the description of buttons (texts, icons, layout) + * @param list structure giving the list of choices and the current selected one * @return >= 0 if OK */ -int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceButtons_t *info) +int nbgl_layoutAddMenuList(nbgl_layout_t *layout, nbgl_layoutMenuList_t *list) { - layoutObj_t *obj; - nbgl_button_t *topButton, *bottomButton; nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + uint8_t i; - LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddChoiceButtons():\n"); + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddMenuList():\n"); if (layout == NULL) { return -1; } + for (i = 0; i < list->nbChoices; i++) { + nbgl_text_area_t *textArea; - // texts cannot be NULL - if ((info->bottomText == NULL) || (info->topText == NULL)) { - return -1; + // check whether this object is visible or not + // only the two objects above or below the selected one are visible + if (((list->selectedChoice > 2) && (i < (list->selectedChoice - 2))) + || (i > (list->selectedChoice + 2))) { + continue; + } + + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + + // init text area for this choice + textArea->text = list->callback(i); + textArea->textAlignment = CENTER; + textArea->obj.area.width = AVAILABLE_WIDTH; + textArea->obj.area.height = 12; + textArea->style = NO_STYLE; + textArea->obj.alignment = CENTER; + textArea->obj.alignmentMarginY = ((i - list->selectedChoice) * 16); + textArea->textColor = WHITE; + + // highlight init choice + if (i == list->selectedChoice) { + textArea->fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; + } + else { + textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; + } + + // set this new obj as child of main container + addObjectToLayout(layoutInt, (nbgl_obj_t *) textArea); } - // create bottomButton (in white) at first - bottomButton = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layoutInt->layer); - obj = addCallbackObj(layoutInt, (nbgl_obj_t *) bottomButton, info->token, info->tuneId); - if (obj == NULL) { + return 0; +} + +/** + * @brief Creates an area on the center of the main panel, with a possible icon/image, + * a possible text in black under it, and a possible text in gray under it + * + * @param layout the current layout + * @param info structure giving the description of buttons (texts, icons, layout) + * @return >= 0 if OK + */ +int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredInfo_t *info) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_container_t *container; + nbgl_text_area_t *textArea = NULL; + nbgl_image_t *image = NULL; + uint16_t fullHeight = 0; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddCenteredInfo():\n"); + if (layout == NULL) { return -1; } - // associate with with index 1 + + container = (nbgl_container_t *) nbgl_objPoolGet(CONTAINER, layoutInt->layer); + + // 3 children at max + container->children = nbgl_containerPoolGet(3, layoutInt->layer); + container->nbChildren = 0; + if (info->icon != NULL) { + image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer); + image->foregroundColor = WHITE; + image->buffer = PIC(info->icon); + image->obj.area.bpp = NBGL_BPP_1; + image->obj.alignment = TOP_MIDDLE; + image->obj.alignTo = NULL; + + fullHeight += image->buffer->height; + container->children[container->nbChildren] = (nbgl_obj_t *) image; + container->nbChildren++; + } + if (info->text1 != NULL) { + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + textArea->textColor = WHITE; + textArea->text = PIC(info->text1); + textArea->textAlignment = CENTER; + textArea->fontId = (info->style == REGULAR_INFO) ? BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp + : BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; + textArea->obj.area.width = AVAILABLE_WIDTH; + textArea->wrapping = true; + uint16_t nbLines + = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true); + // if more than available lines on screen + if (nbLines > NB_MAX_LINES) { + uint16_t len; + nbLines = NB_MAX_LINES; + textArea->nbMaxLines = NB_MAX_LINES; + nbgl_getTextMaxLenInNbLines( + textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true); + textArea->len = len; + } + const nbgl_font_t *font = nbgl_getFont(textArea->fontId); + textArea->obj.area.height = nbLines * font->line_height; + textArea->style = NO_STYLE; + if (info->icon != NULL) { + textArea->obj.alignment = BOTTOM_MIDDLE; // under icon + textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1]; + textArea->obj.alignmentMarginY = (nbLines < 3) ? 4 : 0; + } + else if (info->text2 == NULL) { + textArea->obj.alignment = CENTER; + textArea->obj.alignTo = NULL; + } + else { + textArea->obj.alignment = TOP_MIDDLE; + textArea->obj.alignTo = NULL; + } + + fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY; + + container->children[container->nbChildren] = (nbgl_obj_t *) textArea; + container->nbChildren++; + } + if (info->text2 != NULL) { + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + textArea->textColor = WHITE; + textArea->text = PIC(info->text2); + textArea->textAlignment = CENTER; + textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; + textArea->obj.area.width = AVAILABLE_WIDTH; + uint16_t nbLines + = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true); + // if more than available lines on screen + if (nbLines > (NB_MAX_LINES - 1)) { + uint16_t len; + nbLines = NB_MAX_LINES - 1; + textArea->nbMaxLines = nbLines; + nbgl_getTextMaxLenInNbLines( + textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true); + textArea->len = len; + } + const nbgl_font_t *font = nbgl_getFont(textArea->fontId); + textArea->obj.area.height = nbLines * font->line_height; + + textArea->style = NO_STYLE; + textArea->obj.alignment = BOTTOM_MIDDLE; + textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1]; + textArea->obj.alignmentMarginY = 2; + + fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY; + + container->children[container->nbChildren] = (nbgl_obj_t *) textArea; + container->nbChildren++; + } + container->obj.area.height = fullHeight; + container->layout = VERTICAL; + container->obj.alignmentMarginY = 0; + if (info->onTop) { + container->obj.alignment = TOP_MIDDLE; + } + else { + container->obj.alignment = CENTER; + } + + container->obj.area.width = AVAILABLE_WIDTH; + + // set this new container as child of main container + addObjectToLayout(layoutInt, (nbgl_obj_t *) container); + + return 0; +} +#endif // HAVE_SE_TOUCH + +#ifdef NBGL_QRCODE +/** + * @brief Creates an area on the center of the main panel, with a QRCode, + * a possible text in black (bold) under it, and a possible text in black under it + * + * @param layout the current layout + * @param info structure giving the description of buttons (texts, icons, layout) + * @return >= 0 if OK + */ +int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_container_t *container; + nbgl_text_area_t *textArea = NULL; + nbgl_qrcode_t *qrcode; + uint16_t fullHeight = 0; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddQRCode():\n"); + if (layout == NULL) { + return -1; + } + + container = (nbgl_container_t *) nbgl_objPoolGet(CONTAINER, layoutInt->layer); + + // get container children (max 2 (QRCode + text1/text2)) + container->children = nbgl_containerPoolGet(2, layoutInt->layer); + container->nbChildren = 0; + + qrcode = (nbgl_qrcode_t *) nbgl_objPoolGet(QR_CODE, layoutInt->layer); + // version is forced to V10 if url is longer than 62 characters + if (strlen(PIC(info->url)) > 62) { + qrcode->version = QRCODE_V10; + } + else { + qrcode->version = QRCODE_V4; + } + qrcode->foregroundColor = BLACK; + // in QR V4, we use 8*8 screen pixels for one QR pixel + // in QR V10, we use 4*4 screen pixels for one QR pixel + qrcode->obj.area.width + = (qrcode->version == QRCODE_V4) ? (QR_V4_NB_PIX_SIZE * 8) : (QR_V10_NB_PIX_SIZE * 4); + qrcode->obj.area.height = qrcode->obj.area.width; + qrcode->text = PIC(info->url); + qrcode->obj.area.bpp = NBGL_BPP_1; + qrcode->obj.alignment = TOP_MIDDLE; + qrcode->obj.alignmentMarginY = 24; + + fullHeight += qrcode->obj.area.height; + container->children[container->nbChildren] = (nbgl_obj_t *) qrcode; + container->nbChildren++; + + if (info->text1 != NULL) { + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + textArea->textColor = BLACK; + textArea->text = PIC(info->text1); + textArea->textAlignment = CENTER; + textArea->fontId = (info->largeText1 == true) ? BAGL_FONT_INTER_MEDIUM_32px + : BAGL_FONT_INTER_REGULAR_24px; + textArea->wrapping = true; + textArea->obj.area.width = AVAILABLE_WIDTH; + textArea->obj.area.height = nbgl_getTextHeightInWidth( + textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping); + textArea->obj.alignment = BOTTOM_MIDDLE; + textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1]; + textArea->obj.alignmentMarginY = 40; + + fullHeight += textArea->obj.area.height; + + container->children[container->nbChildren] = (nbgl_obj_t *) textArea; + container->nbChildren++; + } + else if (info->text2 != NULL) { + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + textArea->textColor = DARK_GRAY; + textArea->text = PIC(info->text2); + textArea->textAlignment = CENTER; + textArea->fontId = BAGL_FONT_INTER_REGULAR_24px; + textArea->wrapping = true; + textArea->obj.area.width = AVAILABLE_WIDTH; + textArea->obj.area.height = nbgl_getTextHeightInWidth( + textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping); + textArea->obj.alignment = BOTTOM_MIDDLE; + textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1]; + textArea->obj.alignmentMarginY = 40; + + fullHeight += textArea->obj.area.height; + + container->children[container->nbChildren] = (nbgl_obj_t *) textArea; + container->nbChildren++; + } + container->obj.area.height = fullHeight; + container->layout = VERTICAL; + // center the QRCode only if it's the first (and probably only) child + if (layoutInt->container->nbChildren == 0) { + container->obj.alignment = CENTER; + } + else { + container->obj.alignment = BOTTOM_MIDDLE; + container->obj.alignmentMarginY = BORDER_MARGIN; + container->obj.alignTo + = layoutInt->container->children[layoutInt->container->nbChildren - 1]; + } + + container->obj.area.width = AVAILABLE_WIDTH; + + // set this new container as child of main container + addObjectToLayout(layoutInt, (nbgl_obj_t *) container); + + return 0; +} +#endif // NBGL_QRCODE + +#ifdef HAVE_SE_TOUCH +/** + * @brief Creates two buttons to make a choice. Both buttons are mandatory + * + * @param layout the current layout + * @param info structure giving the description of buttons (texts, icons, layout) + * @return >= 0 if OK + */ +int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceButtons_t *info) +{ + layoutObj_t *obj; + nbgl_button_t *topButton, *bottomButton; + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddChoiceButtons():\n"); + if (layout == NULL) { + return -1; + } + + // texts cannot be NULL + if ((info->bottomText == NULL) || (info->topText == NULL)) { + return -1; + } + + // create bottomButton (in white) at first + bottomButton = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layoutInt->layer); + obj = addCallbackObj(layoutInt, (nbgl_obj_t *) bottomButton, info->token, info->tuneId); + if (obj == NULL) { + return -1; + } + // associate with with index 1 obj->index = 1; bottomButton->obj.alignment = BOTTOM_MIDDLE; if (info->style == ROUNDED_AND_FOOTER_STYLE) { @@ -1704,6 +2156,7 @@ int nbgl_layoutAddTagValueList(nbgl_layout_t *layout, const nbgl_layoutTagValueL return 0; } +#endif // HAVE_SE_TOUCH /** * @brief Creates an area in main panel to display a progress bar, with a title text and a @@ -1722,6 +2175,7 @@ int nbgl_layoutAddProgressBar(nbgl_layout_t *layout, const nbgl_layoutProgressBa if (layout == NULL) { return -1; } +#ifdef HAVE_SE_TOUCH if (barLayout->text != NULL) { nbgl_text_area_t *textArea; @@ -1774,10 +2228,59 @@ int nbgl_layoutAddProgressBar(nbgl_layout_t *layout, const nbgl_layoutProgressBa subTextArea->obj.alignmentMarginY = BORDER_MARGIN; addObjectToLayout(layoutInt, (nbgl_obj_t *) subTextArea); } +#else // HAVE_SE_TOUCH + if (barLayout->text != NULL) { + nbgl_text_area_t *textArea; + + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, + ((nbgl_layoutInternal_t *) layout)->layer); + textArea->textColor = WHITE; + textArea->text = PIC(barLayout->text); + textArea->textAlignment = CENTER; + textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; + textArea->obj.area.width = AVAILABLE_WIDTH; + textArea->obj.area.height = nbgl_getTextHeight(textArea->fontId, textArea->text); + textArea->obj.alignment = TOP_MIDDLE; + textArea->obj.alignmentMarginX = 0; + textArea->obj.alignmentMarginY = 16; // 16 px from top + addObjectToLayout(layoutInt, (nbgl_obj_t *) textArea); + } + progress = (nbgl_progress_bar_t *) nbgl_objPoolGet(PROGRESS_BAR, + ((nbgl_layoutInternal_t *) layout)->layer); + progress->foregroundColor = WHITE; + progress->withBorder = true; + progress->state = barLayout->percentage; + progress->obj.area.width = 102; + progress->obj.area.height = 14; + progress->obj.alignment = TOP_MIDDLE; + progress->obj.alignmentMarginX = 0; + progress->obj.alignmentMarginY = 33; // 33px from top + addObjectToLayout(layoutInt, (nbgl_obj_t *) progress); + + if (barLayout->subText != NULL) { + nbgl_text_area_t *subTextArea; + + subTextArea = (nbgl_text_area_t *) nbgl_objPoolGet( + TEXT_AREA, ((nbgl_layoutInternal_t *) layout)->layer); + subTextArea->textColor = WHITE; + subTextArea->text = PIC(barLayout->subText); + subTextArea->textAlignment = CENTER; + subTextArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; + subTextArea->obj.area.width = AVAILABLE_WIDTH; + subTextArea->obj.area.height = nbgl_getTextHeight(subTextArea->fontId, subTextArea->text); + subTextArea->obj.alignment = BOTTOM_MIDDLE; + subTextArea->obj.alignTo = (nbgl_obj_t *) progress; + subTextArea->obj.alignmentMarginX = 0; + subTextArea->obj.alignmentMarginY = 4; + addObjectToLayout(layoutInt, (nbgl_obj_t *) subTextArea); + } +#endif // HAVE_SE_TOUCH return 0; } +#ifdef HAVE_SE_TOUCH + /** * @brief adds a separation line on bottom of the last added item * @@ -2243,8 +2746,10 @@ int nbgl_layoutAddSpinner(nbgl_layout_t *layout, const char *text, bool fixed) return 0; } +#endif // HAVE_SE_TOUCH #ifdef NBGL_KEYBOARD +#ifdef HAVE_SE_TOUCH /** * @brief Creates a keyboard on bottom of the screen, with the given configuration * @@ -2728,9 +3233,157 @@ int nbgl_layoutUpdateConfirmationButton(nbgl_layout_t *layout, nbgl_redrawObject((nbgl_obj_t *) button, NULL, false); return 0; } +#else // HAVE_SE_TOUCH +/** + * @brief Creates a keyboard on bottom of the screen, with the given configuration + * + * @param layout the current layout + * @param kbdInfo configuration of the keyboard to draw (including the callback when touched) + * @return the index of keyboard, to use in @ref nbgl_layoutUpdateKeyboard() + */ +int nbgl_layoutAddKeyboard(nbgl_layout_t *layout, const nbgl_layoutKbd_t *kbdInfo) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_keyboard_t *keyboard; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddKeyboard():\n"); + if (layout == NULL) { + return -1; + } + + // create keyboard + keyboard = (nbgl_keyboard_t *) nbgl_objPoolGet(KEYBOARD, layoutInt->layer); + keyboard->obj.alignmentMarginY = 0; + keyboard->obj.alignment = CENTER; + keyboard->enableBackspace = kbdInfo->enableBackspace; + keyboard->enableValidate = kbdInfo->enableValidate; + if (kbdInfo->lettersOnly) { + keyboard->selectedCharIndex = cx_rng_u32() % 26; + keyboard->mode = MODE_LOWER_LETTERS; + } + else { + keyboard->mode = MODE_NONE; + } + keyboard->callback = PIC(kbdInfo->callback); + keyboard->lettersOnly = kbdInfo->lettersOnly; + keyboard->keyMask = kbdInfo->keyMask; + // set this new keyboard as child of the container + addObjectToLayout(layoutInt, (nbgl_obj_t *) keyboard); + + // return index of keyboard to be modified later on + return (layoutInt->nbChildren - 1); +} + +/** + * @brief Updates an existing keyboard on bottom of the screen, with the given configuration + * + * @param layout the current layout + * @param index index returned by @ref nbgl_layoutAddKeyboard() + * @param keyMask mask of keys to activate/deactivate on keyboard + * @return >=0 if OK + */ +int nbgl_layoutUpdateKeyboard(nbgl_layout_t *layout, uint8_t index, uint32_t keyMask) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_keyboard_t *keyboard; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutUpdateKeyboard(): keyMask = 0x%X\n", keyMask); + if (layout == NULL) { + return -1; + } + + // get keyboard at given index + keyboard = (nbgl_keyboard_t *) layoutInt->children[index]; + if ((keyboard == NULL) || (keyboard->obj.type != KEYBOARD)) { + return -1; + } + keyboard->keyMask = keyMask; + if (keyboard->lettersOnly) { + if (keyMask & (1 << 26)) { + keyboard->selectedCharIndex = cx_rng_u32() % 26; + } + else { + keyboard->selectedCharIndex = 0; + } + } + + nbgl_redrawObject((nbgl_obj_t *) keyboard, NULL, false); + + return 0; +} + +/** + * @brief Adds a "text entry" area under the previously entered object. + * The max number of really displayable characters is 8, even if there are 9 placeholders (_) + * If longer than 8 chars, the first ones are replaced by a '..' + * The 9th placeholder is never filled + * + * @param layout the current layout + * @param text string to display in the area + * @param lettersOnly if true, display 8 chars placeholders, otherwise 9 + * @return >= 0 if OK + */ +int nbgl_layoutAddEnteredText(nbgl_layout_t *layout, const char *text, bool lettersOnly) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_text_entry_t *textEntry; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddEnteredText():\n"); + if (layout == NULL) { + return -1; + } + + // create text area + textEntry = (nbgl_text_entry_t *) nbgl_objPoolGet(TEXT_ENTRY, layoutInt->layer); + textEntry->text = text; + textEntry->fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; + textEntry->nbChars = lettersOnly ? 8 : 9; + textEntry->obj.alignmentMarginY = 5; + textEntry->obj.alignment = BOTTOM_MIDDLE; + textEntry->obj.area.width = 98; + textEntry->obj.area.height = 16; + + // set this new text area as child of the container + addObjectToLayout(layoutInt, (nbgl_obj_t *) textEntry); + + // return index of text area to be modified later on + return (layoutInt->nbChildren - 1); +} + +/** + * @brief Updates an existing "text entry" area, created with @ref nbgl_layoutAddEnteredText() + * + * @param layout the current layout + * @param index index of the text (return value of @ref nbgl_layoutAddEnteredText()) + * @param text string to display in the area + * @return <0 if error, 0 if OK with text fitting the area, 1 of 0K with text + * not fitting the area + */ +int nbgl_layoutUpdateEnteredText(nbgl_layout_t *layout, uint8_t index, const char *text) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_text_entry_t *textEntry; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutUpdateEnteredText():\n"); + if (layout == NULL) { + return -1; + } + + // update main text area + textEntry = (nbgl_text_entry_t *) layoutInt->children[index]; + if ((textEntry == NULL) || (textEntry->obj.type != TEXT_ENTRY)) { + return -1; + } + textEntry->text = text; + nbgl_redrawObject((nbgl_obj_t *) textEntry, NULL, false); + + return 0; +} +#endif // HAVE_SE_TOUCH #endif // NBGL_KEYBOARD #ifdef NBGL_KEYPAD +#ifdef HAVE_SE_TOUCH /** * @brief Adds a keypad on bottom of the screen, with the associated callback * @@ -2953,6 +3606,226 @@ int nbgl_layoutUpdateHiddenDigits(nbgl_layout_t *layout, uint8_t index, uint8_t return 0; } +#else // HAVE_SE_TOUCH +/** + * @brief Adds a keypad on bottom of the screen, with the associated callback + * + * @note Validate and Backspace keys are not enabled at start-up + * + * @param layout the current layout + * @param callback function called when any of the key is touched + * @param text text to use as title for the keypad + * @param shuffled if set to true, digits are shuffled in keypad + * @return the index of keypad in layout, to use in @ref nbgl_layoutUpdateKeypad() + */ +int nbgl_layoutAddKeypad(nbgl_layout_t *layout, + keyboardCallback_t callback, + const char *text, + bool shuffled) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_keypad_t *keypad; + nbgl_text_area_t *textArea; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddKeypad():\n"); + if (layout == NULL) { + return -1; + } + + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer); + textArea->textColor = WHITE; + textArea->text = PIC(text); + textArea->textAlignment = CENTER; + textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp; + textArea->obj.area.width = AVAILABLE_WIDTH; + textArea->obj.area.height = 12; + textArea->wrapping = false; + textArea->obj.alignment = TOP_MIDDLE; + textArea->obj.alignmentMarginY = 3; + // set this new obj as child of main container + addObjectToLayout(layoutInt, (nbgl_obj_t *) textArea); + + // create keypad + keypad = (nbgl_keypad_t *) nbgl_objPoolGet(KEYPAD, layoutInt->layer); + keypad->obj.alignment = BOTTOM_MIDDLE; + keypad->obj.alignmentMarginY = 6; + keypad->obj.alignTo = NULL; + keypad->callback = PIC(callback); + keypad->enableBackspace = false; + keypad->enableValidate = false; + keypad->selectedKey = 0xFF; // to be picked + keypad->shuffled = shuffled; + // set this new keypad as child of the container + addObjectToLayout(layoutInt, (nbgl_obj_t *) keypad); + + // return index of keypad to be modified later on + return (layoutInt->nbChildren - 1); +} + +/** + * @brief Updates an existing keypad on bottom of the screen, with the given configuration + * + * @param layout the current layout + * @param index index returned by @ref nbgl_layoutAddKeypad() + * @param enableValidate if true, enable Validate key + * @param enableBackspace if true, enable Backspace key + * @return >=0 if OK + */ +int nbgl_layoutUpdateKeypad(nbgl_layout_t *layout, + uint8_t index, + bool enableValidate, + bool enableBackspace) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_keypad_t *keypad; + + LOG_DEBUG(LAYOUT_LOGGER, + "nbgl_layoutUpdateKeypad(): enableValidate = %d, enableBackspace = %d\n", + enableValidate, + enableBackspace); + if (layout == NULL) { + return -1; + } + + // get existing keypad + keypad = (nbgl_keypad_t *) layoutInt->children[index]; + if ((keypad == NULL) || (keypad->obj.type != KEYPAD)) { + LOG_WARN(LAYOUT_LOGGER, "nbgl_layoutUpdateKeypad(): keypad not found\n"); + return -1; + } + if (enableValidate && !keypad->enableValidate) { + // if validate key is enabled and was not, select it directly + keypad->selectedKey = 11; + } + else { + // otherwise let the draw function pick a new selected + keypad->selectedKey = 0xFF; + } + keypad->enableValidate = enableValidate; + keypad->enableBackspace = enableBackspace; + + nbgl_redrawObject((nbgl_obj_t *) keypad, NULL, false); + + return 0; +} + +/** + * @brief Adds a placeholder for hidden digits on top of a keypad, to represent the entered digits, + * as full circles + * + * @note It must be the last added object, after keypad. Vertical positions of title and hidden + * digits will be computed here + * + * @param layout the current layout + * @param nbDigits number of digits to be displayed + * @return the index of digits set, to use in @ref nbgl_layoutUpdateHiddenDigits() + */ +int nbgl_layoutAddHiddenDigits(nbgl_layout_t *layout, uint8_t nbDigits) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_container_t *container; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddHiddenDigits():\n"); + if (layout == NULL) { + return -1; + } + + // create a container, invisible or bordered + container = (nbgl_container_t *) nbgl_objPoolGet(CONTAINER, layoutInt->layer); + container->nbChildren = nbDigits; + container->children = nbgl_containerPoolGet(container->nbChildren, layoutInt->layer); + // 1 pixel between each icon (knowing that the effective bullets are 8px large) + container->obj.area.width = nbDigits * C_pin_bullet_empty.width + (nbDigits - 1); + container->obj.area.height = C_pin_bullet_empty.height; + // distance from top to digits is fixed to 24 px + container->obj.alignmentMarginY = 24; + container->obj.alignTo = NULL; + container->obj.alignment = TOP_MIDDLE; + + // set this new container as child of the main container + addObjectToLayout(layoutInt, (nbgl_obj_t *) container); + + // create children of the container, as images (empty circles) + nbgl_objPoolGetArray(IMAGE, nbDigits, layoutInt->layer, (nbgl_obj_t **) container->children); + for (int i = 0; i < nbDigits; i++) { + nbgl_image_t *image = (nbgl_image_t *) container->children[i]; + image->buffer = &C_pin_bullet_empty; + image->foregroundColor = WHITE; + if (i > 0) { + image->obj.alignment = MID_RIGHT; + image->obj.alignTo = (nbgl_obj_t *) container->children[i - 1]; + image->obj.alignmentMarginX = 1; + } + else { + image->obj.alignment = NO_ALIGNMENT; + } + } + // return index of container to be modified later on + return (layoutInt->nbChildren - 1); +} + +/** + * @brief Updates an existing set of hidden digits, with the given configuration + * + * @param layout the current layout + * @param index index returned by @ref nbgl_layoutAddHiddenDigits() + * @param nbActive number of "active" digits (represented by discs instead of circles) + * @return >=0 if OK + */ +int nbgl_layoutUpdateHiddenDigits(nbgl_layout_t *layout, uint8_t index, uint8_t nbActive) +{ + nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout; + nbgl_container_t *container; + nbgl_image_t *image; + + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutUpdateHiddenDigits(): nbActive = %d\n", nbActive); + if (layout == NULL) { + return -1; + } + + // get container + container = (nbgl_container_t *) layoutInt->children[index]; + // sanity check + if ((container == NULL) || (container->obj.type != CONTAINER)) { + return -1; + } + if (nbActive > container->nbChildren) { + return -1; + } + if (nbActive == 0) { + // deactivate the first digit + image = (nbgl_image_t *) container->children[0]; + if ((image == NULL) || (image->obj.type != IMAGE)) { + return -1; + } + image->buffer = &C_pin_bullet_empty; + } + else { + image = (nbgl_image_t *) container->children[nbActive - 1]; + if ((image == NULL) || (image->obj.type != IMAGE)) { + return -1; + } + // if the last "active" is already active, it means that we are decreasing the number of + // active otherwise we are increasing it + if (image->buffer == &C_pin_bullet_filled) { + // all digits are already active + if (nbActive == container->nbChildren) { + return 0; + } + // deactivate the next digit + image = (nbgl_image_t *) container->children[nbActive]; + image->buffer = &C_pin_bullet_empty; + } + else { + image->buffer = &C_pin_bullet_filled; + } + } + + nbgl_redrawObject((nbgl_obj_t *) image, NULL, false); + + return 0; +} +#endif // HAVE_SE_TOUCH #endif // NBGL_KEYPAD /** @@ -2968,6 +3841,7 @@ int nbgl_layoutDraw(nbgl_layout_t *layoutParam) if (layout == NULL) { return -1; } +#ifdef HAVE_SE_TOUCH LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutDraw(): container.nbChildren =%d, layout->nbChildren = %d\n", layout->container->nbChildren, @@ -2982,6 +3856,9 @@ int nbgl_layoutDraw(nbgl_layout_t *layoutParam) layout->children[layout->nbChildren] = (nbgl_obj_t *) line; layout->nbChildren++; } +#else // HAVE_SE_TOUCH + LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutDraw(): layout->nbChildren = %d\n", layout->nbChildren); +#endif // HAVE_SE_TOUCH nbgl_screenRedraw(); return 0; diff --git a/lib_nbgl/src/nbgl_navigation.c b/lib_nbgl/src/nbgl_navigation.c index a21775b81..832d3f0fb 100644 --- a/lib_nbgl/src/nbgl_navigation.c +++ b/lib_nbgl/src/nbgl_navigation.c @@ -5,6 +5,8 @@ * */ +#ifdef HAVE_SE_TOUCH + /********************* * INCLUDES *********************/ @@ -200,3 +202,5 @@ nbgl_container_t *nbgl_navigationPopulate(uint8_t nbPages, return navContainer; } + +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/src/nbgl_obj.c b/lib_nbgl/src/nbgl_obj.c index de2bccab2..1020056e8 100644 --- a/lib_nbgl/src/nbgl_obj.c +++ b/lib_nbgl/src/nbgl_obj.c @@ -23,6 +23,9 @@ *********************/ #define NB_MAX_PAGES_WITH_DASHES 10 +// max number of letters in TEXT_ENTRY +#define NB_MAX_LETTERS 9 + /********************** * TYPEDEFS **********************/ @@ -30,7 +33,7 @@ /********************** * STATIC PROTOTYPES **********************/ -void extendRefreshArea(nbgl_obj_t *obj); +static void extendRefreshArea(nbgl_obj_t *obj); /********************** * STATIC VARIABLES @@ -231,8 +234,10 @@ static void compute_relativePosition(nbgl_obj_t *obj, nbgl_obj_t *prevObj) } } } +#ifdef HAVE_SE_TOUCH // align on multiples of 4 obj->rel_y0 &= ~0x3; +#endif // HAVE_SE_TOUCH } static void compute_position(nbgl_obj_t *obj, nbgl_obj_t *prevObj) @@ -260,6 +265,7 @@ static void compute_position(nbgl_obj_t *obj, nbgl_obj_t *prevObj) obj->area.x0, obj->area.width); } +#ifdef HAVE_SE_TOUCH if ((obj->area.y0 + obj->area.height) > SCREEN_HEIGHT) { LOG_FATAL(OBJ_LOGGER, "compute_position(), forbidden height, obj->type = %d, y0=%d, height=%d\n", @@ -267,6 +273,7 @@ static void compute_position(nbgl_obj_t *obj, nbgl_obj_t *prevObj) obj->area.y0, obj->area.height); } +#endif // HAVE_SE_TOUCH } static void draw_screen(nbgl_container_t *obj) @@ -304,6 +311,7 @@ static void draw_container(nbgl_container_t *obj, nbgl_obj_t *prevObj, bool comp } } +#ifdef HAVE_SE_TOUCH /** * @brief internal function used to draw a button * @note The button contains an icon AND/OR a single-line UTF-8 text @@ -456,6 +464,7 @@ static void draw_line(nbgl_line_t *obj, nbgl_obj_t *prevObj, bool computePositio nbgl_frontDrawHorizontalLine(&rectArea, mask, obj->lineColor); } } +#endif // HAVE_SE_TOUCH static void draw_image(nbgl_image_t *obj, nbgl_obj_t *prevObj, bool computePosition) { @@ -474,6 +483,9 @@ static void draw_image(nbgl_image_t *obj, nbgl_obj_t *prevObj, bool computePosit else { iconDetails = obj->buffer; } + if (iconDetails == NULL) { + return; + } // use dimension and bpp from the icon details obj->obj.area.width = iconDetails->width; @@ -501,6 +513,7 @@ static void draw_image(nbgl_image_t *obj, nbgl_obj_t *prevObj, bool computePosit nbgl_drawIcon((nbgl_area_t *) obj, colorMap, iconDetails); } +#ifdef HAVE_SE_TOUCH static void draw_switch(nbgl_switch_t *obj, nbgl_obj_t *prevObj, bool computePosition) { nbgl_area_t rectArea; @@ -526,12 +539,10 @@ static void draw_switch(nbgl_switch_t *obj, nbgl_obj_t *prevObj, bool computePos rectArea.backgroundColor = obj->obj.area.backgroundColor; rectArea.bpp = NBGL_BPP_1; if (obj->state == OFF_STATE) { - nbgl_frontDrawImage( - &rectArea, (uint8_t *) C_switch_60_40.bitmap, NO_TRANSFORMATION, obj->offColor); + nbgl_frontDrawImage(&rectArea, C_switch_60_40.bitmap, NO_TRANSFORMATION, obj->offColor); } else { - nbgl_frontDrawImage( - &rectArea, (uint8_t *) C_switch_60_40.bitmap, VERTICAL_MIRROR, obj->onColor); + nbgl_frontDrawImage(&rectArea, C_switch_60_40.bitmap, VERTICAL_MIRROR, obj->onColor); } } @@ -570,6 +581,7 @@ static void draw_radioButton(nbgl_radio_t *obj, nbgl_obj_t *prevObj, bool comput nbgl_drawIcon(&rectArea, obj->activeColor, &C_radio_active_32px); } } +#endif // HAVE_SE_TOUCH /** * @brief internal function used to draw a progress bar object (@ref PROGRESS_BAR type) @@ -580,6 +592,7 @@ static void draw_radioButton(nbgl_radio_t *obj, nbgl_obj_t *prevObj, bool comput */ static void draw_progressBar(nbgl_progress_bar_t *obj, nbgl_obj_t *prevObj, bool computePosition) { +#ifdef HAVE_SE_TOUCH uint8_t stroke = 3; // 3 pixels for border uint16_t levelWidth; @@ -617,8 +630,50 @@ static void draw_progressBar(nbgl_progress_bar_t *obj, nbgl_obj_t *prevObj, bool nbgl_drawRoundedRect((nbgl_area_t *) obj, RADIUS_0_PIXELS, obj->foregroundColor); obj->obj.area.width = tmp_width; } +#else // HAVE_SE_TOUCH + uint8_t stroke = 1; // 1 pixels for border + uint16_t levelWidth; + + if (computePosition) { + compute_position((nbgl_obj_t *) obj, prevObj); + } + LOG_DEBUG(OBJ_LOGGER, + "draw_progressBar(), x0 = %d, y0 = %d, level = %d %%\n", + obj->obj.area.x0, + obj->obj.area.y0, + obj->state); + + // inherit background from parent + obj->obj.area.backgroundColor = obj->obj.parent->area.backgroundColor; + + // draw external part if necessary + if (obj->withBorder) { + nbgl_drawRoundedBorderedRect((nbgl_area_t *) obj, + RADIUS_3_PIXELS, + stroke, + obj->obj.area.backgroundColor, + obj->foregroundColor); + } + else { + nbgl_drawRoundedRect((nbgl_area_t *) obj, RADIUS_3_PIXELS, obj->obj.area.backgroundColor); + } + // draw level + levelWidth = MIN((obj->obj.area.width - 2) * obj->state / 100, (obj->obj.area.width - 2)); + if (levelWidth > 0) { + nbgl_area_t rectArea; + rectArea.width = levelWidth; + rectArea.height = obj->obj.area.height - 2; + rectArea.backgroundColor = obj->foregroundColor; + rectArea.bpp = NBGL_BPP_1; + rectArea.x0 = obj->obj.area.x0 + 1; + rectArea.y0 = obj->obj.area.y0 + 1; + + nbgl_frontDrawRect(&rectArea); + } +#endif // HAVE_SE_TOUCH } +#ifdef HAVE_SE_TOUCH /** * @brief internal function used to draw a navigation indicator object (@ref PAGE_INDICATOR type) * @note It is represented as a dashed line with as many dashes as pages @@ -708,6 +763,7 @@ static void draw_pageIndicator(nbgl_page_indicator_t *obj, nbgl_drawText(&rectArea, navText, strlen(navText), BAGL_FONT_INTER_REGULAR_24px, DARK_GRAY); } } +#endif // HAVE_SE_TOUCH /** * @brief internal function used to draw a text area @@ -719,10 +775,11 @@ static void draw_pageIndicator(nbgl_page_indicator_t *obj, */ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool computePosition) { - nbgl_area_t rectArea; - uint16_t textWidth, fontHeight, lineHeight, textHeight, midHeight; - uint8_t line, nbLines; - const char *text; + nbgl_area_t rectArea; + uint16_t textWidth, fontHeight, lineHeight, textHeight, midHeight; + uint8_t line, nbLines; + const char *text; + nbgl_font_id_e fontId = obj->fontId; if (computePosition) { compute_position((nbgl_obj_t *) obj, prevObj); @@ -760,12 +817,25 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu obj->obj.area.backgroundColor = obj->obj.parent->area.backgroundColor; // draw background to make sure it's clean - rectArea.x0 = obj->obj.area.x0; - rectArea.y0 = obj->obj.area.y0; - rectArea.width = obj->obj.area.width; - rectArea.height = obj->obj.area.height; - rectArea.backgroundColor = obj->obj.area.backgroundColor; - nbgl_frontDrawRect(&rectArea); + if (obj->style == INVERTED_COLORS) { + obj->obj.area.backgroundColor = WHITE; + rectArea.backgroundColor = BLACK; + } + else { + // inherit background from parent + obj->obj.area.backgroundColor = obj->obj.parent->area.backgroundColor; + rectArea.backgroundColor = obj->obj.area.backgroundColor; + } + rectArea.x0 = obj->obj.area.x0; + rectArea.y0 = obj->obj.area.y0; + rectArea.width = obj->obj.area.width; + rectArea.height = obj->obj.area.height; + if (obj->style == INVERTED_COLORS) { + nbgl_drawRoundedRect(&rectArea, RADIUS_1_PIXEL, WHITE); + } + else { + nbgl_frontDrawRect(&rectArea); + } // draw border with given style if (obj->style == LEDGER_BORDER) { // draw horizontal segments (4 pixels stroke) @@ -795,25 +865,25 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu nbgl_frontDrawRect(&rectArea); // bottom left } - fontHeight = nbgl_getFontHeight(obj->fontId); - lineHeight = nbgl_getFontLineHeight(obj->fontId); + fontHeight = nbgl_getFontHeight(fontId); + lineHeight = nbgl_getFontLineHeight(fontId); // special case of autoHideLongLine, when the text is too long for a line, draw '...' at the // beginning if (obj->autoHideLongLine == true) { - textWidth = nbgl_getSingleLineTextWidth(obj->fontId, text); + textWidth = nbgl_getSingleLineTextWidth(fontId, text); if (textWidth > obj->obj.area.width) { uint16_t lineWidth, lineLen; uint16_t dotsWidth; // at first draw "..." at beginning - dotsWidth = nbgl_getTextWidth(obj->fontId, "..."); + dotsWidth = nbgl_getTextWidth(fontId, "..."); rectArea.x0 = obj->obj.area.x0; rectArea.y0 = obj->obj.area.y0 + (obj->obj.area.height - fontHeight) / 2; rectArea.width = dotsWidth; - nbgl_drawText(&rectArea, "...", 3, obj->fontId, obj->textColor); + nbgl_drawText(&rectArea, "...", 3, fontId, obj->textColor); // then draw the end of text nbgl_getTextMaxLenAndWidthFromEnd( - obj->fontId, text, obj->obj.area.width - dotsWidth, &lineLen, &lineWidth); + fontId, text, obj->obj.area.width - dotsWidth, &lineLen, &lineWidth); rectArea.x0 += dotsWidth; rectArea.width = lineWidth; nbgl_drawText(&rectArea, @@ -826,7 +896,7 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu } // get nb lines in the given width (depending of wrapping) - nbLines = nbgl_getTextNbLinesInWidth(obj->fontId, text, obj->obj.area.width, obj->wrapping); + nbLines = nbgl_getTextNbLinesInWidth(fontId, text, obj->obj.area.width, obj->wrapping); // saturate nb lines if nbMaxLines is greater than 0 if ((obj->nbMaxLines > 0) && (obj->nbMaxLines < nbLines)) { nbLines = obj->nbMaxLines; @@ -836,9 +906,15 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu midHeight = (obj->obj.area.height - textHeight) / 2; // Be sure midHeight is modulo 4 +#ifdef HAVE_SE_TOUCH if (midHeight % 4) { midHeight -= midHeight % 4; } +#else // HAVE_SE_TOUCH + if (obj->style == INVERTED_COLORS) { + midHeight--; + } +#endif // HAVE_SE_TOUCH rectArea.backgroundColor = obj->obj.area.backgroundColor; rectArea.height = fontHeight; @@ -847,7 +923,7 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu uint16_t lineWidth, lineLen; nbgl_getTextMaxLenAndWidth( - obj->fontId, text, obj->obj.area.width, &lineLen, &lineWidth, obj->wrapping); + fontId, text, obj->obj.area.width, &lineLen, &lineWidth, obj->wrapping); if (obj->textAlignment == MID_LEFT) { rectArea.x0 = obj->obj.area.x0; } @@ -864,19 +940,21 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu rectArea.width = lineWidth; LOG_DEBUG(OBJ_LOGGER, - "draw_textArea(), %s line %d, lineLen %d lineWidth = %d, obj->obj.area.height = " - "%d, textHeight = %d, obj->nbMaxLines = %d\n", - text, + "draw_textArea(), %s line %d, lineLen %d lineWidth = %d, obj.area.height = %d, " + "textHeight = %d, nbMaxLines = %d, wrapping = %d\n", + text + 3, line, lineLen, lineWidth, obj->obj.area.height, textHeight, - obj->nbMaxLines); + obj->nbMaxLines, + obj->wrapping); if ((obj->nbMaxLines == 0) || (line < (obj->nbMaxLines - 1))) { - nbgl_drawText(&rectArea, text, lineLen, obj->fontId, obj->textColor); + fontId = nbgl_drawText(&rectArea, text, lineLen, fontId, obj->textColor); } else { +#ifdef HAVE_SE_TOUCH // for last chunk, if nbMaxLines is used, replace the 3 last chars by "..." // draw line except 3 last chars nbgl_drawText(&rectArea, text, lineLen - 3, obj->fontId, obj->textColor); @@ -884,6 +962,9 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu rectArea.x0 += nbgl_getSingleLineTextWidthInLen(obj->fontId, text, lineLen - 3); rectArea.width = nbgl_getSingleLineTextWidth(obj->fontId, "..."); nbgl_drawText(&rectArea, "...", 3, obj->fontId, obj->textColor); +#else // HAVE_SE_TOUCH + nbgl_drawText(&rectArea, text, lineLen, fontId, obj->textColor); +#endif // HAVE_SE_TOUCH return; } text += lineLen; @@ -894,6 +975,7 @@ static void draw_textArea(nbgl_text_area_t *obj, nbgl_obj_t *prevObj, bool compu } } +#ifdef NBGL_QRCODE /** * @brief internal function used to draw a QR Code * @note the QRCode is centered in the given object area @@ -928,12 +1010,12 @@ static void draw_qrCode(nbgl_qrcode_t *obj, nbgl_obj_t *prevObj, bool computePos rectArea.width = obj->obj.area.width; rectArea.height = obj->obj.area.height; rectArea.backgroundColor = obj->obj.area.backgroundColor; -#ifdef NBGL_QRCODE nbgl_drawQrCode( &rectArea, (obj->version == QRCODE_V4) ? 4 : 10, obj->text, obj->foregroundColor); -#endif // NBGL_QRCODE } +#endif // NBGL_QRCODE +#ifdef NBGL_KEYBOARD /** * @brief internal function used to draw a Keyboard object * @@ -943,11 +1025,16 @@ static void draw_qrCode(nbgl_qrcode_t *obj, nbgl_obj_t *prevObj, bool computePos */ static void draw_keyboard(nbgl_keyboard_t *obj, nbgl_obj_t *prevObj, bool computePosition) { +#ifdef HAVE_SE_TOUCH obj->obj.area.width = SCREEN_WIDTH; obj->obj.area.height = 3 * KEYBOARD_KEY_HEIGHT; if (!obj->lettersOnly) { obj->obj.area.height += KEYBOARD_KEY_HEIGHT; } +#else // HAVE_SE_TOUCH + obj->obj.area.width = KEYBOARD_WIDTH; + obj->obj.area.height = KEYBOARD_KEY_HEIGHT; +#endif // HAVE_SE_TOUCH if (computePosition) { compute_position((nbgl_obj_t *) obj, prevObj); @@ -961,11 +1048,11 @@ static void draw_keyboard(nbgl_keyboard_t *obj, nbgl_obj_t *prevObj, bool comput // inherit background from parent obj->obj.area.backgroundColor = obj->obj.parent->area.backgroundColor; -#ifdef NBGL_KEYBOARD nbgl_objDrawKeyboard(obj); -#endif // NBGL_KEYBOARD } +#endif // NBGL_KEYBOARD +#ifdef NBGL_KEYPAD /** * @brief internal function used to draw a Keypad object * @@ -975,8 +1062,13 @@ static void draw_keyboard(nbgl_keyboard_t *obj, nbgl_obj_t *prevObj, bool comput */ static void draw_keypad(nbgl_keypad_t *obj, nbgl_obj_t *prevObj, bool computePosition) { +#ifdef HAVE_SE_TOUCH obj->obj.area.width = SCREEN_WIDTH; obj->obj.area.height = 4 * KEYPAD_KEY_HEIGHT; +#else // HAVE_SE_TOUCH + obj->obj.area.height = KEYPAD_HEIGHT; + obj->obj.area.width = KEYPAD_WIDTH; +#endif // HAVE_SE_TOUCH if (computePosition) { compute_position((nbgl_obj_t *) obj, prevObj); @@ -989,11 +1081,11 @@ static void draw_keypad(nbgl_keypad_t *obj, nbgl_obj_t *prevObj, bool computePos // inherit background from parent obj->obj.area.backgroundColor = obj->obj.parent->area.backgroundColor; -#ifdef NBGL_KEYPAD nbgl_objDrawKeypad(obj); -#endif // NBGL_KEYPAD } +#endif // NBGL_KEYPAD +#ifdef HAVE_SE_TOUCH /** * @brief internal function used to draw a Spinner object * @@ -1119,6 +1211,80 @@ static void draw_spinner(nbgl_spinner_t *obj, nbgl_obj_t *prevObj, bool computeP } } +#else // HAVE_SE_TOUCH + +/** + * @brief internal function used to draw a text entry + * + * @param obj the object to draw + * @param prevObj the previous object drawned in the same container, with the default layout + * @param computePosition if TRUE, force to compute the object position + */ +static void draw_textEntry(nbgl_text_entry_t *obj, nbgl_obj_t *prevObj, bool computePosition) +{ + nbgl_area_t rectArea; + int textLen = strlen(obj->text); + uint32_t offsetX; + + if (computePosition) { + compute_position((nbgl_obj_t *) obj, prevObj); + } + + LOG_DEBUG(OBJ_LOGGER, + "draw_textEntry(), x0 = %d, y0 = %d, width = %d, height = %d\n", + obj->obj.area.x0, + obj->obj.area.y0, + obj->obj.area.width, + obj->obj.area.height); + + // draw background to make sure it's clean + obj->obj.area.backgroundColor = WHITE; + rectArea.backgroundColor = BLACK; + rectArea.x0 = obj->obj.area.x0; + rectArea.y0 = obj->obj.area.y0; + rectArea.width = obj->obj.area.width; + rectArea.height = obj->obj.area.height; + rectArea.bpp = NBGL_BPP_1; + nbgl_drawRoundedRect(&rectArea, RADIUS_3_PIXELS, WHITE); + + rectArea.backgroundColor = obj->obj.area.backgroundColor; + rectArea.height = nbgl_getFontHeight(obj->fontId); + if (obj->nbChars > NB_MAX_LETTERS) { + return; + } + offsetX = (obj->obj.area.width - (obj->nbChars * 10)) / 2; + // draw each of the nb chars + for (int i = 0; i < obj->nbChars; i++) { + char digit; + rectArea.x0 = obj->obj.area.x0 + offsetX + (i * 10); + rectArea.y0 = obj->obj.area.y0 - 2; + rectArea.width = 8; + if (textLen < obj->nbChars) { + if (i < textLen) { + digit = obj->text[i]; + } + else { + digit = '_'; + } + } + else { + // first char is '..' to notify continuing + if (i == 0) { + nbgl_drawText(&rectArea, "..", 2, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp, BLACK); + continue; + } + else if (i < (obj->nbChars - 1)) { + digit = obj->text[textLen - obj->nbChars + 1 + i]; + } + else { + digit = '_'; + } + } + nbgl_drawText(&rectArea, &digit, 1, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp, BLACK); + } +} +#endif // HAVE_SE_TOUCH + /** * @brief internal function used to draw an image file * @@ -1140,7 +1306,7 @@ static void draw_image_file(nbgl_image_file_t *obj, nbgl_obj_t *prevObj, bool co LOG_DEBUG( OBJ_LOGGER, "draw_image_file(), x0 = %d, y0 = %d\n", obj->obj.area.x0, obj->obj.area.y0); - nbgl_frontDrawImageFile((nbgl_area_t *) obj, (uint8_t *) obj->buffer, 0, ramBuffer); + nbgl_frontDrawImageFile((nbgl_area_t *) obj, obj->buffer, 0, ramBuffer); } /** @@ -1166,45 +1332,64 @@ draw_object(nbgl_obj_t *obj, nbgl_obj_t *prevObj, bool computePosition) case CONTAINER: draw_container((nbgl_container_t *) obj, prevObj, computePosition); break; +#ifdef HAVE_SE_TOUCH case BUTTON: draw_button((nbgl_button_t *) obj, prevObj, computePosition); break; case LINE: draw_line((nbgl_line_t *) obj, prevObj, computePosition); break; +#endif // HAVE_SE_TOUCH case IMAGE: draw_image((nbgl_image_t *) obj, prevObj, computePosition); break; +#ifdef HAVE_SE_TOUCH case SWITCH: draw_switch((nbgl_switch_t *) obj, prevObj, computePosition); break; case RADIO_BUTTON: draw_radioButton((nbgl_radio_t *) obj, prevObj, computePosition); break; +#endif // HAVE_SE_TOUCH case PROGRESS_BAR: draw_progressBar((nbgl_progress_bar_t *) obj, prevObj, computePosition); break; +#ifdef HAVE_SE_TOUCH case PAGE_INDICATOR: draw_pageIndicator((nbgl_page_indicator_t *) obj, prevObj, computePosition); break; +#endif // HAVE_SE_TOUCH case TEXT_AREA: draw_textArea((nbgl_text_area_t *) obj, prevObj, computePosition); break; +#ifdef NBGL_QRCODE case QR_CODE: draw_qrCode((nbgl_qrcode_t *) obj, prevObj, computePosition); break; +#endif // NBGL_QRCODE +#ifdef NBGL_KEYBOARD case KEYBOARD: draw_keyboard((nbgl_keyboard_t *) obj, prevObj, computePosition); break; +#endif // NBGL_KEYBOARD +#ifdef NBGL_KEYPAD case KEYPAD: draw_keypad((nbgl_keypad_t *) obj, prevObj, computePosition); break; +#endif // NBGL_KEYPAD +#ifdef HAVE_SE_TOUCH case SPINNER: draw_spinner((nbgl_spinner_t *) obj, prevObj, computePosition); break; +#endif // HAVE_SE_TOUCH case IMAGE_FILE: draw_image_file((nbgl_image_file_t *) obj, prevObj, computePosition); break; +#ifndef HAVE_SE_TOUCH + case TEXT_ENTRY: + draw_textEntry((nbgl_text_entry_t *) obj, prevObj, computePosition); + break; +#endif // HAVE_SE_TOUCH default: LOG_DEBUG(OBJ_LOGGER, "Not existing object type\n"); break; @@ -1224,9 +1409,9 @@ draw_object(nbgl_obj_t *obj, nbgl_obj_t *prevObj, bool computePosition) * * @param obj the object drawn */ -void extendRefreshArea(nbgl_obj_t *obj) +static void extendRefreshArea(nbgl_obj_t *obj) { - uint16_t x1, y1; // bottom right corner + int16_t x1, y1; // bottom right corner x1 = refreshArea.x0 + refreshArea.width; y1 = refreshArea.y0 + refreshArea.height; @@ -1255,10 +1440,14 @@ void extendRefreshArea(nbgl_obj_t *obj) refreshArea.width); } if (y1 > SCREEN_HEIGHT) { +#ifdef HAVE_SE_TOUCH LOG_FATAL(OBJ_LOGGER, "extendRefreshArea: Impossible area y0 = %d height %d\n", refreshArea.y0, refreshArea.height); +#else // HAVE_SE_TOUCH + y1 = SCREEN_HEIGHT; +#endif // HAVE_SE_TOUCH } // recompute width and height refreshArea.width = x1 - refreshArea.x0; diff --git a/lib_nbgl/src/nbgl_obj_keyboard.c b/lib_nbgl/src/nbgl_obj_keyboard.c index 05df5bc04..506dc54f3 100644 --- a/lib_nbgl/src/nbgl_obj_keyboard.c +++ b/lib_nbgl/src/nbgl_obj_keyboard.c @@ -6,6 +6,7 @@ */ #ifdef NBGL_KEYBOARD +#ifdef HAVE_SE_TOUCH /********************* * INCLUDES @@ -705,4 +706,5 @@ void nbgl_objDrawKeyboard(nbgl_keyboard_t *kbd) // left keys touch_exclude_borders(TOP_BORDER); } +#endif // HAVE_SE_TOUCH #endif // NBGL_KEYBOARD diff --git a/lib_nbgl/src/nbgl_obj_keyboard_nanos.c b/lib_nbgl/src/nbgl_obj_keyboard_nanos.c new file mode 100644 index 000000000..dc5b017f7 --- /dev/null +++ b/lib_nbgl/src/nbgl_obj_keyboard_nanos.c @@ -0,0 +1,386 @@ + +/** + * @file nbgl_obj_keyboard_nanos.c + * @brief The construction and touch management of a keyboard object for Nanos + * + */ + +#ifdef NBGL_KEYBOARD +#ifndef HAVE_SE_TOUCH + +/********************* + * INCLUDES + *********************/ +#include +#include "nbgl_debug.h" +#include "nbgl_front.h" +#include "nbgl_draw.h" +#include "nbgl_obj.h" +#include "nbgl_fonts.h" +#include "nbgl_touch.h" +#include "glyphs.h" +#include "os_io.h" + +/********************* + * DEFINES + *********************/ + +#define BACKSPACE_KEY_INDEX 26 +#define VALIDATE_INDEX 27 +#define SHIFT_KEY_INDEX 28 +#define LETTER_TO_DIGITS_OFFSET (sizeof(keysByMode[DIGITS_AND_SPECIALS]) - 29) +#define GET_CHAR(mode, char_idx) ((const char *) PIC(screen_keyboard_keys_by_mode[mode]))[char_idx] + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LOWER_LETTERS, + UPPER_LETTERS, + DIGITS_AND_SPECIALS +} KbdMode_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ +const char *const keysByMode[] = { + // when first letter is already entered + "abcdefghijklmnopqrstuvwxyz\b\n\r", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\b\n\r", + "0123456789 '\"`&/?!:;.,~*$=+-[](){}^<>\\_#@|%\b\n\r", +}; + +// these icons will be centered +const nbgl_icon_details_t *const keyboardIcons[] = { + &C_icon_lowercase, + &C_icon_uppercase, + &C_icon_digits, + &C_icon_backspace, + &C_icon_validate, + &C_icon_classes, + &C_icon_lowercase_invert, + &C_icon_uppercase_invert, + &C_icon_digits_invert, + &C_icon_backspace_invert, + &C_icon_validate_invert, + &C_icon_classes_invert, +}; + +static const nbgl_icon_details_t *const modeIcons[] = { + &C_icon_lowercase, + &C_icon_uppercase, + &C_icon_digits, +}; + +/********************** + * VARIABLES + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void keyboardDrawIcon(int16_t x0, int8_t y0, bool inverted, const nbgl_icon_details_t *icon) +{ + nbgl_area_t rectArea; + + rectArea.backgroundColor = inverted ? WHITE : BLACK; + rectArea.width = icon->width; + rectArea.height = icon->height; + rectArea.bpp = NBGL_BPP_1; + // center + rectArea.x0 = x0 + (KEYBOARD_KEY_WIDTH - icon->width) / 2; + rectArea.y0 = y0 + (KEYBOARD_KEY_HEIGHT - icon->height) / 2; + nbgl_frontDrawImage(&rectArea, icon->bitmap, NO_TRANSFORMATION, inverted ? BLACK : WHITE); +} + +static void keyboardDrawChar(int16_t x0, int8_t y0, bool inverted, const char *charPtr) +{ + nbgl_area_t rectArea; + + rectArea.backgroundColor = inverted ? WHITE : BLACK; + rectArea.width = nbgl_getCharWidth(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, charPtr); + rectArea.height = 12; + rectArea.bpp = NBGL_BPP_1; + // center + rectArea.x0 = x0 + (KEYBOARD_KEY_WIDTH - rectArea.width) / 2; + rectArea.y0 = y0 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2 - 3; + nbgl_drawText( + &rectArea, charPtr, 1, BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, inverted ? BLACK : WHITE); +} + +static void keyboardDrawCommon(nbgl_keyboard_t *keyboard) +{ + nbgl_area_t rectArea; + + // clean full area + rectArea.backgroundColor = BLACK; + rectArea.x0 = keyboard->obj.area.x0; + rectArea.y0 = keyboard->obj.area.y0; + rectArea.width = keyboard->obj.area.width; + rectArea.height = keyboard->obj.area.height; + nbgl_frontDrawRect(&rectArea); + + // draw select 'key' in white + rectArea.x0 = keyboard->obj.area.x0 + 2 * KEYBOARD_KEY_WIDTH; + rectArea.y0 = keyboard->obj.area.y0; + rectArea.width = KEYBOARD_KEY_WIDTH; + rectArea.height = keyboard->obj.area.height; + nbgl_drawRoundedRect(&rectArea, RADIUS_3_PIXELS, WHITE); + + // draw separating '-' in white + rectArea.backgroundColor = WHITE; + rectArea.x0 = keyboard->obj.area.x0 + KEYBOARD_KEY_WIDTH + 5; + rectArea.y0 = keyboard->obj.area.y0 + 6; + rectArea.width = 3; + rectArea.height = 1; + nbgl_frontDrawRect(&rectArea); + rectArea.x0 = keyboard->obj.area.x0 + 3 * KEYBOARD_KEY_WIDTH + 5; + nbgl_frontDrawRect(&rectArea); +} + +// draw letters for letters mode +static void keyboardDrawLettersOnly(nbgl_keyboard_t *keyboard) +{ + uint8_t i; + const char *keys = keysByMode[keyboard->mode]; + + if (keyboard->keyMask == 0x07FFFFFF) { + return; + } + + keyboardDrawCommon(keyboard); + + // if selectedChar is masked, move to the first unmasked + while (keyboard->keyMask & (1 << keyboard->selectedCharIndex)) { + if (keyboard->selectedCharIndex < BACKSPACE_KEY_INDEX) { + keyboard->selectedCharIndex++; + } + else { + keyboard->selectedCharIndex = 0; + } + } + + // fill the letters at position middle and right + uint8_t j = 1; + i = keyboard->selectedCharIndex; + while (j < 3) { + // use the provided mask to check what letters(+backspace at 27th position) to use + if ((keyboard->keyMask & (1 << i)) == 0) { + if (i == BACKSPACE_KEY_INDEX) { // backspace + keyboardDrawIcon(keyboard->obj.area.x0 + 2 * j * KEYBOARD_KEY_WIDTH, + keyboard->obj.area.y0, + (j == 1), + &C_icon_backspace); + } + else { // any char + keyboardDrawChar(keyboard->obj.area.x0 + 2 * j * KEYBOARD_KEY_WIDTH, + keyboard->obj.area.y0, + (j == 1), + &keys[i]); + } + j++; + } + i++; + i %= 27; + // safe check in case mask is full of 1s + if (i == keyboard->selectedCharIndex) { + break; + } + } + // fill the letters at left position from end + i = (keyboard->selectedCharIndex + 26) % 27; + while (true) { + if ((keyboard->keyMask & (1 << i)) == 0) { + if (i == BACKSPACE_KEY_INDEX) { // backspace + keyboardDrawIcon( + keyboard->obj.area.x0, keyboard->obj.area.y0, false, &C_icon_backspace); + } + else { // any char + keyboardDrawChar(keyboard->obj.area.x0, keyboard->obj.area.y0, false, &keys[i]); + } + break; + } + if (i > 0) { + i--; + } + else { + i = BACKSPACE_KEY_INDEX; + } + // safe check in case mask is full of 1s + if (i == (keyboard->selectedCharIndex + 26) % 27) { + break; + } + } +} + +// draw letters for regular mode +static void keyboardDrawRegular(nbgl_keyboard_t *keyboard) +{ + int8_t i; + + keyboardDrawCommon(keyboard); + + // if mode is not already defined, display the 3 icons of keyboard modes to let user choose it: + // "ab, AB and 0? " + if (keyboard->mode == MODE_NONE) { + for (i = 0; i < 3; i++) { + uint8_t charIndex = (keyboard->selectedCharIndex + 2 + i) % 3; + keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH, + keyboard->obj.area.y0, + (i == 1), + modeIcons[charIndex]); + } + return; + } + + const char *keys = keysByMode[keyboard->mode]; + uint8_t maxLen = strlen(keys); + + // mode is defined, so draw the proper 3 letters (or icons) + for (i = 0; i < 3; i++) { + uint8_t charIndex = (keyboard->selectedCharIndex + maxLen - 1 + i) % maxLen; + if (keys[charIndex] == '\r') { + keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH, + keyboard->obj.area.y0, + (i == 1), + &C_icon_classes); + } + else if (keys[charIndex] == '\n') { + keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH, + keyboard->obj.area.y0, + (i == 1), + &C_icon_validate_14); + } + else if (keys[charIndex] == '\b') { + keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH, + keyboard->obj.area.y0, + (i == 1), + &C_icon_backspace); + } + else { + keyboardDrawChar(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH, + keyboard->obj.area.y0, + (i == 1), + &keys[charIndex]); + } + } +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief function to be called when the keyboard object is receiving a button press + * + * @param obj touched object (keyboard) + * @param buttonEvent type of button event + * @return none + */ +void nbgl_keyboardCallback(nbgl_obj_t *obj, nbgl_buttonEvent_t buttonEvent) +{ + nbgl_keyboard_t *keyboard = (nbgl_keyboard_t *) obj; + uint8_t nbMax; + + LOG_DEBUG(MISC_LOGGER, "nbgl_keyboardCallback(): buttonEvent = %d\n", buttonEvent); + + if (keyboard->mode == MODE_NONE) { + nbMax = 2; + } + else { + if (keyboard->lettersOnly) { + nbMax = BACKSPACE_KEY_INDEX; + } + else { + nbMax = strlen(keysByMode[keyboard->mode]) - 1; + } + } + if (buttonEvent == BUTTON_BOTH_PRESSED) { + if (keyboard->mode == MODE_NONE) { + // apply the selected mode + keyboard->mode = keyboard->selectedCharIndex; + // reset the selected index to start with "a" (or first char of selected mode) + keyboard->selectedCharIndex = 0; + } + else { + if (keyboard->lettersOnly) { + if ((keyboard->selectedCharIndex < 26) + && ((keyboard->keyMask & (1 << keyboard->selectedCharIndex)) == 0)) { + const char *keys = keysByMode[keyboard->mode]; + keyboard->callback(keys[keyboard->selectedCharIndex]); + } + else if (keyboard->selectedCharIndex == BACKSPACE_KEY_INDEX) { // backspace + keyboard->callback(BACKSPACE_KEY); + } + } + else { + char key = keysByMode[keyboard->mode][keyboard->selectedCharIndex]; + if (key == '\r') { + // go back to mode choice + keyboard->mode = MODE_NONE; + // reset the selected index + keyboard->selectedCharIndex = 0; + nbgl_redrawObject((nbgl_obj_t *) keyboard, NULL, false); + nbgl_refresh(); + } + else if (key == '\n') { + keyboard->callback(VALIDATE_KEY); + } + else if (key == '\b') { + keyboard->callback(BACKSPACE_KEY); + } + else { + keyboard->callback(key); + } + } + return; + } + } + else if (buttonEvent == BUTTON_LEFT_PRESSED) { + do { + if (keyboard->selectedCharIndex > 0) { + keyboard->selectedCharIndex--; + } + else { + keyboard->selectedCharIndex = nbMax; + } + } while (keyboard->keyMask & (1 << keyboard->selectedCharIndex)); + } + else if (buttonEvent == BUTTON_RIGHT_PRESSED) { + do { + if (keyboard->selectedCharIndex < nbMax) { + keyboard->selectedCharIndex++; + } + else { + keyboard->selectedCharIndex = 0; + } + } while (keyboard->keyMask & (1 << keyboard->selectedCharIndex)); + } + else { + return; + } + nbgl_redrawObject((nbgl_obj_t *) keyboard, NULL, false); + nbgl_refresh(); +} + +/** + * @brief This function draws a keyboard object + * + * @param kbd the object to be drawned + */ +void nbgl_objDrawKeyboard(nbgl_keyboard_t *kbd) +{ + if (kbd->lettersOnly) { + keyboardDrawLettersOnly(kbd); + } + else { + keyboardDrawRegular(kbd); + } +} +#endif // HAVE_SE_TOUCH +#endif // NBGL_KEYBOARD diff --git a/lib_nbgl/src/nbgl_obj_keypad.c b/lib_nbgl/src/nbgl_obj_keypad.c index fd28a7930..bec8a6fc4 100644 --- a/lib_nbgl/src/nbgl_obj_keypad.c +++ b/lib_nbgl/src/nbgl_obj_keypad.c @@ -6,6 +6,7 @@ */ #ifdef NBGL_KEYPAD +#ifdef HAVE_SE_TOUCH /********************* * INCLUDES @@ -399,4 +400,5 @@ void nbgl_objDrawKeypad(nbgl_keypad_t *kpd) keypadDraw(kpd); } +#endif // HAVE_SE_TOUCH #endif // NBGL_KEYPAD diff --git a/lib_nbgl/src/nbgl_obj_keypad_nanos.c b/lib_nbgl/src/nbgl_obj_keypad_nanos.c new file mode 100644 index 000000000..75dd229d8 --- /dev/null +++ b/lib_nbgl/src/nbgl_obj_keypad_nanos.c @@ -0,0 +1,281 @@ + +/** + * @file nbgl_obj_keypad_nanos.c + * @brief The construction and key management of a keypad object for nanos + * + */ + +#ifdef NBGL_KEYPAD +#ifndef HAVE_SE_TOUCH + +/********************* + * INCLUDES + *********************/ +#include "nbgl_debug.h" +#include "nbgl_front.h" +#include "nbgl_draw.h" +#include "nbgl_obj.h" +#include "nbgl_fonts.h" +#include "nbgl_screen.h" +#include "glyphs.h" +#include "os_io_seproxyhal.h" +#include "lcx_rng.h" + +/********************* + * DEFINES + *********************/ +#define KEY_WIDTH 9 +#define DIGIT_HEIGHT 12 +#define DIGIT_OFFSET_X 13 +#define DIGIT_OFFSET_Y ((KEYPAD_HEIGHT - DIGIT_HEIGHT) / 2) +#define INIT_DIGIT_VALUE 5 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ +static const nbgl_icon_details_t *digits_icons[] = {&C_digit_0, + &C_digit_1, + &C_digit_2, + &C_digit_3, + &C_digit_4, + &C_digit_5, + &C_digit_6, + &C_digit_7, + &C_digit_8, + &C_digit_9}; +/********************** + * VARIABLES + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ +static char positionToChar(uint8_t pos) +{ + if (pos == 0) { + return BACKSPACE_KEY; + } + else if (pos == 11) { + return VALIDATE_KEY; + } + else { + return 0x30 + (pos - 1); + } +} + +static void keypadDrawDigits(nbgl_keypad_t *keypad) +{ + uint8_t i; + nbgl_area_t rectArea; + + // clean full area + rectArea.backgroundColor = BLACK; + rectArea.x0 = keypad->obj.area.x0; + rectArea.y0 = keypad->obj.area.y0; + rectArea.width = keypad->obj.area.width; + rectArea.height = keypad->obj.area.height; + nbgl_frontDrawRect(&rectArea); + + rectArea.backgroundColor = BLACK; + rectArea.y0 = keypad->obj.area.y0 + DIGIT_OFFSET_Y; + rectArea.bpp = NBGL_BPP_1; + // row of digits: 0 1 2 3... 9 + for (i = 0; i < 10; i++) { + rectArea.width = digits_icons[i]->width; + rectArea.height = digits_icons[i]->height; + + rectArea.x0 = keypad->obj.area.x0 + DIGIT_OFFSET_X + i * KEY_WIDTH; + nbgl_frontDrawImage(&rectArea, digits_icons[i]->bitmap, NO_TRANSFORMATION, WHITE); + } + // draw backspace + if (keypad->enableBackspace) { + rectArea.width = C_icon_backspace.width; + rectArea.height = C_icon_backspace.height; + rectArea.x0 = keypad->obj.area.x0; + rectArea.y0 = keypad->obj.area.y0 + ((KEYPAD_HEIGHT - C_icon_backspace.height) / 2); + nbgl_frontDrawImage(&rectArea, C_icon_backspace.bitmap, NO_TRANSFORMATION, WHITE); + } + + // draw validate + if (keypad->enableValidate) { + rectArea.width = C_digit_validate_bold.width; + rectArea.height = C_digit_validate_bold.height; + rectArea.x0 = keypad->obj.area.x0 + KEYPAD_WIDTH - C_digit_validate_bold.width; + rectArea.y0 = keypad->obj.area.y0 + ((KEYPAD_HEIGHT - C_digit_validate_bold.height) / 2); + nbgl_frontDrawImage(&rectArea, C_digit_validate_bold.bitmap, NO_TRANSFORMATION, WHITE); + } +} + +static void keypadDrawSelected(nbgl_keypad_t *keypad) +{ + nbgl_area_t rectArea; + /// then draw 1 horizontal line + rectArea.backgroundColor = WHITE; + + if (keypad->selectedKey == 0) { + rectArea.x0 = keypad->obj.area.x0; + } + else if (keypad->selectedKey < 11) { // if it's a digit + rectArea.x0 = keypad->obj.area.x0 + DIGIT_OFFSET_X + (keypad->selectedKey - 1) * KEY_WIDTH; + } + else if (keypad->selectedKey == 11) { + rectArea.x0 = keypad->obj.area.x0 + KEYPAD_WIDTH - C_digit_validate_bold.width; + } + else { + return; + } + rectArea.y0 = keypad->obj.area.y0 + keypad->obj.area.height - 2; + rectArea.width = 8; + rectArea.height = 2; + nbgl_frontDrawRect(&rectArea); +} + +static void keypadDrawSelectedTouched(nbgl_keypad_t *keypad) +{ + nbgl_area_t rectArea; + /// draw 1 horizontal line upper selected key + rectArea.backgroundColor = WHITE; + + if (keypad->selectedKey == 0) { + rectArea.x0 = keypad->obj.area.x0; + } + else if (keypad->selectedKey < 11) { // if it's a digit + rectArea.x0 = keypad->obj.area.x0 + DIGIT_OFFSET_X + (keypad->selectedKey - 1) * KEY_WIDTH; + } + else if (keypad->selectedKey == 11) { + rectArea.x0 = keypad->obj.area.x0 + KEYPAD_WIDTH - C_digit_validate_bold.width; + } + else { + return; + } + rectArea.y0 = keypad->obj.area.y0; + rectArea.width = 8; + rectArea.height = 2; + nbgl_frontDrawRect(&rectArea); + nbgl_frontRefreshArea(&rectArea, FULL_COLOR_CLEAN_REFRESH, POST_REFRESH_KEEP_POWER_STATE); +} + +static void keypadInitSelected(nbgl_keypad_t *keypad) +{ + if (!keypad->shuffled) { + keypad->selectedKey = 1 + INIT_DIGIT_VALUE; + } + else { + uint8_t nbChoices = 10; + uint8_t random; + if (keypad->enableBackspace) { + nbChoices++; + } + if (keypad->enableValidate) { + nbChoices++; + } + random = cx_rng_u32_range(0, nbChoices); + if (random < 10) { + keypad->selectedKey = 1 + random; + } + else if (random == 10) { + keypad->selectedKey = 0; + } + else if (random == 11) { + keypad->selectedKey = 11; + } + } +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief function to be called when the keypad object is touched + * + * @param obj touched object (keypad) + * @param buttonEvent type of key event + * @return none + */ +void nbgl_keypadCallback(nbgl_obj_t *obj, nbgl_buttonEvent_t buttonEvent) +{ + nbgl_keypad_t *keypad = (nbgl_keypad_t *) obj; + + LOG_DEBUG(OBJ_LOGGER, "nbgl_keypadCallback(): buttonEvent = %d\n", buttonEvent); + + if (buttonEvent == BUTTON_BOTH_TOUCHED) { + // draw bar upper selected key + keypadDrawSelectedTouched(keypad); + } + else if (buttonEvent == BUTTON_BOTH_PRESSED) { + keypad->callback(positionToChar(keypad->selectedKey)); + } + else if ((buttonEvent == BUTTON_LEFT_PRESSED) + || (buttonEvent == BUTTON_LEFT_CONTINUOUS_PRESSED)) { + switch (keypad->selectedKey) { + case 1: + if (keypad->enableBackspace) { + keypad->selectedKey = 0; + } + else { + keypad->selectedKey = 10; + } + break; + case 0: // backspace + if (keypad->enableValidate) { + keypad->selectedKey = 11; + } + else { + keypad->selectedKey = 10; + } + break; + default: + keypad->selectedKey--; + break; + } + nbgl_screenRedraw(); + } + else if ((buttonEvent == BUTTON_RIGHT_PRESSED) + || (buttonEvent == BUTTON_RIGHT_CONTINUOUS_PRESSED)) { + switch (keypad->selectedKey) { + case 10: // '9' + if (keypad->enableValidate) { + keypad->selectedKey = 11; + } + else if (keypad->enableBackspace) { + keypad->selectedKey = 0; + } + else { + keypad->selectedKey = 1; + } + break; + case 11: // validate + keypad->selectedKey = 0; + break; + default: + keypad->selectedKey++; + break; + } + nbgl_screenRedraw(); + } +} + +/** + * @brief This function draws a keypad object + * + * @param keypad keypad object to draw + * @return the keypad object + */ +void nbgl_objDrawKeypad(nbgl_keypad_t *keypad) +{ + LOG_DEBUG(OBJ_LOGGER, "nbgl_objDrawKeypad keypad->shuffled= %d\n", keypad->shuffled); + // draw digits content + keypadDrawDigits(keypad); + if (keypad->selectedKey == 0xFF) { + keypadInitSelected(keypad); + } + keypadDrawSelected(keypad); +} + +#endif // HAVE_SE_TOUCH +#endif // NBGL_KEYPAD diff --git a/lib_nbgl/src/nbgl_obj_pool.c b/lib_nbgl/src/nbgl_obj_pool.c index 13948d10e..4da5a2d7e 100644 --- a/lib_nbgl/src/nbgl_obj_pool.c +++ b/lib_nbgl/src/nbgl_obj_pool.c @@ -20,12 +20,20 @@ * @brief Max number of objects retrievable from pool * */ -#define OBJ_POOL_LEN 80 +#ifdef HAVE_SE_TOUCH +#define OBJ_POOL_LEN 80 +#else // HAVE_SE_TOUCH +#define OBJ_POOL_LEN 40 +#endif // HAVE_SE_TOUCH /** * @brief Max number of objects pointers usable for container pool * */ +#ifdef HAVE_SE_TOUCH #define OBJ_CONTAINER_POOL_LEN 128 +#else // HAVE_SE_TOUCH +#define OBJ_CONTAINER_POOL_LEN 64 +#endif // HAVE_SE_TOUCH #define INVALID_LAYER 0xFF @@ -35,19 +43,27 @@ typedef struct { union { - nbgl_obj_t obj; + nbgl_obj_t obj; + nbgl_text_area_t textAreaObj; + nbgl_progress_bar_t progressBarObj; + nbgl_container_t containerObj; + nbgl_image_t imageObj; +#ifdef HAVE_SE_TOUCH nbgl_radio_t radioObj; nbgl_switch_t switchObj; - nbgl_text_area_t textAreaObj; nbgl_button_t buttonObj; - nbgl_progress_bar_t progressBarObj; nbgl_page_indicator_t navBarObj; - nbgl_container_t containerObj; - nbgl_image_t imageObj; nbgl_line_t lineObj; - nbgl_keyboard_t keyboardObj; - nbgl_keypad_t keypadObj; nbgl_spinner_t spinnerObj; +#else // HAVE_SE_TOUCH + nbgl_text_entry_t entryObj; +#endif // HAVE_SE_TOUCH +#ifdef NBGL_KEYBOARD + nbgl_keyboard_t keyboardObj; +#endif // NBGL_KEYBOARD +#ifdef NBGL_KEYPAD + nbgl_keypad_t keypadObj; +#endif // NBGL_KEYPAD }; } genericObj_t; @@ -249,8 +265,10 @@ void nbgl_containerPoolRelease(uint8_t layer) { uint8_t i; LOG_DEBUG(OBJ_POOL_LOGGER, - "nbgl_containerPoolRelease(): %d containers in pool\n", - nbUsedObjsInContainerPool); + "nbgl_containerPoolRelease(): %d used obj containers in pool, trying to release for " + "layer %d\n", + nbUsedObjsInContainerPool, + layer); if (nbUsedObjsInContainerPool == 0) { return; } @@ -272,6 +290,10 @@ nbgl_obj_t **nbgl_containerPoolGet(uint8_t nbObjs, uint8_t layer) { uint8_t i = 0, nbContiguousFree = 0; nbgl_obj_t **container; + LOG_DEBUG(OBJ_POOL_LOGGER, + "nbgl_containerPoolGet(): getting %d obj containers for layer %d\n", + nbObjs, + layer); if (initialized == false) { memset(objPoolLayers, INVALID_LAYER, OBJ_POOL_LEN); memset(objPointersPoolLayers, INVALID_LAYER, OBJ_CONTAINER_POOL_LEN); diff --git a/lib_nbgl/src/nbgl_screen.c b/lib_nbgl/src/nbgl_screen.c index 68eda239a..f1638e8ee 100644 --- a/lib_nbgl/src/nbgl_screen.c +++ b/lib_nbgl/src/nbgl_screen.c @@ -122,25 +122,39 @@ static int nbgl_screenSetAt(uint8_t screenIndex, nbgl_obj_t ***children, uint8_t nbChildren, const nbgl_screenTickerConfiguration_t *ticker, - nbgl_touchCallback_t callback) +#ifdef HAVE_SE_TOUCH + nbgl_touchCallback_t callback) +{ +#else // HAVE_SE_TOUCH + nbgl_buttonCallback_t callback) { +#endif // HAVE_SE_TOUCH if (screenIndex >= SCREEN_STACK_SIZE) { LOG_WARN(SCREEN_LOGGER, "nbgl_screenSetAt(): forbidden screenIndex (%d)\n", screenIndex); return -1; } *children = nbgl_containerPoolGet(nbChildren, screenIndex); screenStack[screenIndex].container.obj.type = SCREEN; +#ifdef HAVE_SE_TOUCH screenStack[screenIndex].container.obj.area.backgroundColor = WHITE; - screenStack[screenIndex].container.obj.area.height = SCREEN_HEIGHT; - screenStack[screenIndex].container.obj.area.width = SCREEN_WIDTH; - screenStack[screenIndex].container.obj.area.x0 = 0; - screenStack[screenIndex].container.obj.area.y0 = 0; - screenStack[screenIndex].container.obj.rel_x0 = 0; - screenStack[screenIndex].container.obj.rel_y0 = 0; - screenStack[screenIndex].container.layout = VERTICAL; - screenStack[screenIndex].container.children = *children; - screenStack[screenIndex].container.nbChildren = nbChildren; - screenStack[screenIndex].touchCallback = callback; +#else // HAVE_SE_TOUCH + screenStack[screenIndex].container.obj.area.backgroundColor = BLACK; +#endif // HAVE_SE_TOUCH + screenStack[screenIndex].container.obj.area.height = SCREEN_HEIGHT; + screenStack[screenIndex].container.obj.area.width = SCREEN_WIDTH; + screenStack[screenIndex].container.obj.area.x0 = 0; + screenStack[screenIndex].container.obj.area.y0 = 0; + screenStack[screenIndex].container.obj.rel_x0 = 0; + screenStack[screenIndex].container.obj.rel_y0 = 0; + screenStack[screenIndex].index = screenIndex; + screenStack[screenIndex].container.layout = VERTICAL; + screenStack[screenIndex].container.children = *children; + screenStack[screenIndex].container.nbChildren = nbChildren; +#ifdef HAVE_SE_TOUCH + screenStack[screenIndex].touchCallback = callback; +#else // HAVE_SE_TOUCH + screenStack[screenIndex].buttonCallback = callback; +#endif // HAVE_SE_TOUCH if (ticker != NULL) { screenStack[screenIndex].ticker.tickerCallback = (nbgl_tickerCallback_t) PIC(ticker->tickerCallback); @@ -170,8 +184,13 @@ static int nbgl_screenSetAt(uint8_t screenIndex, int nbgl_screenSet(nbgl_obj_t ***elements, uint8_t nbElements, const nbgl_screenTickerConfiguration_t *ticker, - nbgl_touchCallback_t callback) +#ifdef HAVE_SE_TOUCH + nbgl_touchCallback_t callback) +{ +#else // HAVE_SE_TOUCH + nbgl_buttonCallback_t callback) { +#endif // HAVE_SE_TOUCH // if no screen, consider it as a first fake push if (nbScreensOnStack == 0) { nbScreensOnStack++; @@ -270,8 +289,13 @@ nbgl_obj_t **nbgl_screenGetElements(uint8_t screenIndex) int nbgl_screenPush(nbgl_obj_t ***elements, uint8_t nbElements, const nbgl_screenTickerConfiguration_t *ticker, - nbgl_touchCallback_t callback) +#ifdef HAVE_SE_TOUCH + nbgl_touchCallback_t callback) +{ +#else // HAVE_SE_TOUCH + nbgl_buttonCallback_t callback) { +#endif // HAVE_SE_TOUCH uint8_t screenIndex; if (nbScreensOnStack >= SCREEN_STACK_SIZE) { LOG_WARN(SCREEN_LOGGER, @@ -446,6 +470,40 @@ static bool objIsIn(nbgl_obj_t *refObj, nbgl_obj_t *obj) return false; } +/** + * @brief return true if the given obj can be found in refObj or any of its children + * + * @param refObj the object to search obj into + * @param obj the object to search + * @return found object or NULL if not found + */ +static nbgl_obj_t *objIsOfType(nbgl_obj_t *refObj, nbgl_obj_type_t type) +{ + uint8_t i; + + if (refObj->type == type) { + LOG_DEBUG(SCREEN_LOGGER, "objIsOfType(): yes\n"); + return refObj; + } + + if ((refObj->type == SCREEN) || (refObj->type == CONTAINER)) { + nbgl_container_t *container = (nbgl_container_t *) refObj; + // draw the children, if any + if (container->children != NULL) { + for (i = 0; i < container->nbChildren; i++) { + nbgl_obj_t *current = container->children[i]; + if (current != NULL) { + nbgl_obj_t *found = objIsOfType(current, type); + if (found) { + return found; + } + } + } + } + } + return NULL; +} + /** * @brief return true if the given obj can be found in refObj or any of its children * @@ -459,3 +517,19 @@ bool nbgl_screenContainsObj(nbgl_obj_t *obj) } return objIsIn((nbgl_obj_t *) topOfStack, obj); } + +/** + * @brief return an object of the given type in the given screen + * + * @param screen the screen in which to search + * @param type the type of object to search for + * @return the found object of given type + */ +nbgl_obj_t *nbgl_screenContainsObjType(nbgl_screen_t *screen, nbgl_obj_type_t type) +{ + if (nbScreensOnStack == 0) { + return NULL; + } + + return objIsOfType((nbgl_obj_t *) screen, type); +} diff --git a/lib_nbgl/src/nbgl_serialize.c b/lib_nbgl/src/nbgl_serialize.c index 441a63f89..bd09e882e 100644 --- a/lib_nbgl/src/nbgl_serialize.c +++ b/lib_nbgl/src/nbgl_serialize.c @@ -22,7 +22,7 @@ static void nbgl_appendU32(uint32_t value, uint8_t *out, size_t *w_cnt, size_t m nbgl_appendU8((uint8_t) (value & 0xFF), out, w_cnt, max_len); } -static void nbgl_appendPtr(void *value, uint8_t *out, size_t *w_cnt, size_t max_len) +static void nbgl_appendPtr(const void *value, uint8_t *out, size_t *w_cnt, size_t max_len) { if (max_len < (*w_cnt + sizeof(void *))) { return; @@ -188,6 +188,7 @@ static void nbgl_serializeTextArea(nbgl_text_area_t *obj, nbgl_appendU8((uint8_t) obj->fontId, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->localized, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->autoHideLongLine, out, w_cnt, max_len); + nbgl_appendU16((uint16_t) obj->len, out, w_cnt, max_len); nbgl_serializeText(obj->text, out, w_cnt, max_len); } @@ -262,13 +263,13 @@ static void nbgl_serializeButton(nbgl_button_t *obj, uint8_t *out, size_t *w_cnt nbgl_appendU8((uint8_t) obj->fontId, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->localized, out, w_cnt, max_len); nbgl_serializeText(obj->text, out, w_cnt, max_len); - nbgl_serializeIcon((void *) obj->icon, out, w_cnt, max_len); + nbgl_serializeIcon(obj->icon, out, w_cnt, max_len); } static void nbgl_serializeImage(nbgl_image_t *obj, uint8_t *out, size_t *w_cnt, size_t max_len) { nbgl_serializeObj((nbgl_obj_t *) &obj->obj, out, w_cnt, max_len); - nbgl_serializeIcon((void *) obj->buffer, out, w_cnt, max_len); + nbgl_serializeIcon(obj->buffer, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->foregroundColor, out, w_cnt, max_len); } @@ -288,7 +289,11 @@ static void nbgl_serializeKeyboard(nbgl_keyboard_t *obj, nbgl_appendU8((uint8_t) obj->textColor, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->borderColor, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->lettersOnly, out, w_cnt, max_len); +#ifdef HAVE_SE_TOUCH nbgl_appendU8((uint8_t) obj->casing, out, w_cnt, max_len); +#else // HAVE_SE_TOUCH + nbgl_appendU8((uint8_t) obj->selectedCharIndex, out, w_cnt, max_len); +#endif // HAVE_SE_TOUCH nbgl_appendU8((uint8_t) obj->mode, out, w_cnt, max_len); nbgl_appendU32(obj->keyMask, out, w_cnt, max_len); } @@ -297,17 +302,25 @@ static void nbgl_serializeKeypad(nbgl_keypad_t *obj, uint8_t *out, size_t *w_cnt { nbgl_serializeObj((nbgl_obj_t *) &obj->obj, out, w_cnt, max_len); +#ifdef HAVE_SE_TOUCH nbgl_appendU8((uint8_t) obj->textColor, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->borderColor, out, w_cnt, max_len); +#endif // HAVE_SE_TOUCH nbgl_appendU8((uint8_t) obj->enableBackspace, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->enableValidate, out, w_cnt, max_len); +#ifdef HAVE_SE_TOUCH nbgl_appendU8((uint8_t) obj->enableDigits, out, w_cnt, max_len); +#endif // HAVE_SE_TOUCH nbgl_appendU8((uint8_t) obj->shuffled, out, w_cnt, max_len); +#ifdef HAVE_SE_TOUCH nbgl_appendU8((uint8_t) obj->digitIndexes[0], out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->digitIndexes[1], out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->digitIndexes[2], out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->digitIndexes[3], out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->digitIndexes[4], out, w_cnt, max_len); +#else // HAVE_SE_TOUCH + nbgl_appendU8((uint8_t) obj->selectedKey, out, w_cnt, max_len); +#endif // HAVE_SE_TOUCH } static void nbgl_serializeImageFile(nbgl_image_file_t *obj, @@ -316,7 +329,7 @@ static void nbgl_serializeImageFile(nbgl_image_file_t *obj, size_t max_len) { nbgl_serializeObj((nbgl_obj_t *) &obj->obj, out, w_cnt, max_len); - nbgl_appendPtr((void *) obj->buffer, out, w_cnt, max_len); + nbgl_appendPtr((const void *) obj->buffer, out, w_cnt, max_len); } static void nbgl_serializeContainer(nbgl_container_t *obj, diff --git a/lib_nbgl/src/nbgl_step.c b/lib_nbgl/src/nbgl_step.c new file mode 100644 index 000000000..ac96ec375 --- /dev/null +++ b/lib_nbgl/src/nbgl_step.c @@ -0,0 +1,562 @@ +/** + * @file nbgl_step.c + * @brief Implementation of predefined pages management for Applications + */ + +#ifdef NBGL_STEP +/********************* + * INCLUDES + *********************/ +#include +#include "nbgl_debug.h" +#include "nbgl_step.h" +#include "glyphs.h" +#include "os_pic.h" +#include "os_print.h" + +/********************* + * DEFINES + *********************/ +// string to store the title for a multi-pages text+subtext +#define TMP_STRING_MAX_LEN 24 + +///< Maximum number of layers for steps, cannot be greater than max number of layout layers +#define NB_MAX_LAYERS 3 + +/********************** + * TYPEDEFS + **********************/ +/** + * type of step + */ +typedef enum { + TEXT_STEP = 0, ///< for a simple text step + CENTERED_INFO_STEP, ///< for a centered info step + MENU_LIST_STEP ///< for a menu list step +} StepStype_t; + +/** + * definition of context for a @ref TEXT_STEP or @ref CENTERED_INFO_STEP step + */ +typedef struct TextContext_s { + uint8_t nbPages; ///< number of pages for this text step + uint8_t currentPage; ///< current page for this text step + const char *txtStart; ///< pointer on the start point of text (first page) + const char *nextPageStart; ///< pointer on the start point of text at the next page + const char *subTxtStart; ///< pointer on the start point of sub-text (first page) + nbgl_stepPosition_t pos; ///< position of the step within a flow (used for navigation arrows) + nbgl_stepButtonCallback_t onActionCallback; ///< function called when key actions done on this + ///< step (other than internal navigation) + char tmpString[TMP_STRING_MAX_LEN]; ///< temporary string used for title when text + + ///< multi-pages subText + nbgl_centeredInfoStyle_t style; ///< style to be used with a @ref CENTERED_INFO_STEP step +} TextContext_t; + +/** + * definition of context for a @ref MENU_LIST_STEP step + */ +typedef struct MenuListContext_s { + nbgl_stepMenuListCallback_t + selectedCallback; ///< function to call when a menu list item is selected + nbgl_layoutMenuList_t + list; ///< structure to store the number of menu items and the way to select them +} MenuListContext_t; + +typedef struct StepContext_s { + union { + TextContext_t textContext; ///< if type is @ref TEXT_STEP or @ref CENTERED_INFO_STEP + MenuListContext_t menuListContext; ///< if type is @ref MENU_LIST_STEP + }; + nbgl_screenTickerConfiguration_t ticker; ///< structure containing information about ticker + nbgl_layout_t *layout; ///< handler of the used layout + StepStype_t type; ///< type of step + bool modal; ///< true if modal +} StepContext_t; + +/********************** + * STATIC VARIABLES + **********************/ +///< array of step contexts. Index 0 is reserved for background +static StepContext_t contexts[NB_MAX_LAYERS]; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void actionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event); +static void menuListActionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event); + +// returns a non-used step context from the contexts[] array, or NULL if not found +static StepContext_t *getFreeContext(StepStype_t type, bool modal) +{ + StepContext_t *ctx = NULL; + + if (!modal) { + // Index 0 is reserved for background + ctx = &contexts[0]; + } + else { + uint32_t i = 1; + while (i < NB_MAX_LAYERS) { + if (contexts[i].layout == NULL) { + ctx = &contexts[i]; + break; + } + i++; + } + } + if (ctx == NULL) { + LOG_FATAL(STEP_LOGGER, "getFreeContext(): no available context\n"); + } + else { + memset(ctx, 0, sizeof(StepContext_t)); + ctx->type = type; + ctx->modal = modal; + } + return ctx; +} + +// returns the step context from the contexts[] array matching with the given layout handler, or +// NULL if not found +static StepContext_t *getContextFromLayout(nbgl_layout_t layout) +{ + StepContext_t *ctx = NULL; + uint32_t i = 0; + while (i < NB_MAX_LAYERS) { + if (contexts[i].layout == layout) { + ctx = &contexts[i]; + break; + } + i++; + } + if (ctx == NULL) { + LOG_WARN(STEP_LOGGER, "getContextFromLayout(): no matching context\n"); + } + return ctx; +} + +// from the current details context, return a pointer on the details at the given page +static const char *getTextPageAt(StepContext_t *ctx, uint8_t textPage) +{ + uint8_t page = 0; + const char *currentChar = ctx->textContext.txtStart; + while (page < textPage) { + if (page < (ctx->textContext.nbPages - 1)) { + uint16_t len; + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + currentChar, + AVAILABLE_WIDTH, + NB_MAX_LINES, + &len, + true); + currentChar = currentChar + len; + } + page++; + } + return currentChar; +} + +// from the current details context, return a pointer on the details at the given page, for subText +static const char *getSubTextPageAt(StepContext_t *ctx, uint8_t textPage) +{ + uint8_t page = 0; + const char *currentChar = ctx->textContext.subTxtStart; + while (page < textPage) { + if (page < (ctx->textContext.nbPages - 1)) { + uint16_t len; + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + currentChar, + AVAILABLE_WIDTH, + NB_MAX_LINES - 1, + &len, + true); + currentChar = currentChar + len; + } + page++; + } + return currentChar; +} + +// utility function to compute navigation arrows +static nbgl_layoutNavIndication_t getNavigationInfo(nbgl_stepPosition_t pos, + uint8_t nbPages, + uint8_t currentPage) +{ + nbgl_layoutNavIndication_t indication = NO_ARROWS; + + if (nbPages > 1) { + if (currentPage > 0) { + indication |= LEFT_ARROW; + } + if (currentPage < (nbPages - 1)) { + indication |= RIGHT_ARROW; + } + } + if (pos == FIRST_STEP) { + indication |= RIGHT_ARROW; + } + else if (pos == LAST_STEP) { + indication |= LEFT_ARROW; + } + else if (pos == NEITHER_FIRST_NOR_LAST_STEP) { + indication |= RIGHT_ARROW | LEFT_ARROW; + } + return indication; +} + +// function used to display the current page in details review mode +static void displayTextPage(StepContext_t *ctx, uint8_t textPage) +{ + const char *txt; + + // if move backward or first page + if (textPage <= ctx->textContext.currentPage) { + // recompute current start from beginning + if (ctx->textContext.subTxtStart == NULL) { + txt = getTextPageAt(ctx, textPage); + } + else { + txt = getSubTextPageAt(ctx, textPage); + } + } + // else move forward + else { + txt = ctx->textContext.nextPageStart; + } + ctx->textContext.currentPage = textPage; + + if (ctx->textContext.currentPage < (ctx->textContext.nbPages - 1)) { + uint16_t len; + uint8_t nbLines + = (ctx->textContext.subTxtStart == NULL) ? NB_MAX_LINES : (NB_MAX_LINES - 1); + nbgl_getTextMaxLenInNbLines( + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, txt, AVAILABLE_WIDTH, nbLines, &len, true); + // memorize next position to save processing + ctx->textContext.nextPageStart = txt + len; + } + else { + ctx->textContext.nextPageStart = NULL; + } + nbgl_layoutDescription_t layoutDescription; + nbgl_layoutNavigation_t navInfo = { + .direction = HORIZONTAL_NAV, + }; + + layoutDescription.modal = ctx->modal; + layoutDescription.onActionCallback = actionCallback; + layoutDescription.ticker.tickerCallback = ctx->ticker.tickerCallback; + layoutDescription.ticker.tickerIntervale = ctx->ticker.tickerIntervale; + layoutDescription.ticker.tickerValue = ctx->ticker.tickerValue; + ctx->layout = nbgl_layoutGet(&layoutDescription); + + navInfo.indication = getNavigationInfo( + ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage); + + if (ctx->textContext.subTxtStart == NULL) { + nbgl_layoutAddText(ctx->layout, txt, NULL, ctx->textContext.style); + } + else { + if (ctx->textContext.nbPages == 1) { + nbgl_layoutAddText(ctx->layout, ctx->textContext.txtStart, txt, ctx->textContext.style); + } + else { + SPRINTF(ctx->textContext.tmpString, + "%s (%d/%d)", + ctx->textContext.txtStart, + ctx->textContext.currentPage + 1, + ctx->textContext.nbPages); + nbgl_layoutAddText( + ctx->layout, ctx->textContext.tmpString, txt, ctx->textContext.style); + } + } + if (navInfo.indication != NO_ARROWS) { + nbgl_layoutAddNavigation(ctx->layout, &navInfo); + } + nbgl_layoutDraw(ctx->layout); + nbgl_refresh(); +} + +// callback on key touch +static void actionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event) +{ + StepContext_t *ctx = getContextFromLayout(layout); + + if (!ctx) { + return; + } + if (event == BUTTON_LEFT_PRESSED) { + if (ctx->textContext.currentPage > 0) { + displayTextPage(ctx, ctx->textContext.currentPage - 1); + return; + } + else if ((ctx->textContext.pos == LAST_STEP) + || (ctx->textContext.pos == NEITHER_FIRST_NOR_LAST_STEP)) { + ctx->textContext.onActionCallback((nbgl_step_t) ctx, event); + } + } + else if (event == BUTTON_RIGHT_PRESSED) { + if (ctx->textContext.currentPage < (ctx->textContext.nbPages - 1)) { + displayTextPage(ctx, ctx->textContext.currentPage + 1); + return; + } + else if ((ctx->textContext.pos == FIRST_STEP) + || (ctx->textContext.pos == NEITHER_FIRST_NOR_LAST_STEP)) { + ctx->textContext.onActionCallback((nbgl_step_t) ctx, event); + } + } + else if (event == BUTTON_BOTH_PRESSED) { + ctx->textContext.onActionCallback((nbgl_step_t) ctx, event); + } +} + +static void displayMenuList(StepContext_t *ctx) +{ + nbgl_layoutDescription_t layoutDescription + = {.modal = ctx->modal, .onActionCallback = menuListActionCallback}; + nbgl_layoutMenuList_t *list = &ctx->menuListContext.list; + + layoutDescription.ticker.tickerCallback = ctx->ticker.tickerCallback; + layoutDescription.ticker.tickerIntervale = ctx->ticker.tickerIntervale; + layoutDescription.ticker.tickerValue = ctx->ticker.tickerValue; + + ctx->layout = nbgl_layoutGet(&layoutDescription); + nbgl_layoutAddMenuList(ctx->layout, list); + if (list->nbChoices > 1) { + nbgl_layoutNavigation_t navInfo = {.direction = VERTICAL_NAV}; + navInfo.indication = 0; + if (list->selectedChoice > 0) { + navInfo.indication |= LEFT_ARROW; + } + if (list->selectedChoice < (list->nbChoices - 1)) { + navInfo.indication |= RIGHT_ARROW; + } + + if (navInfo.indication != NO_ARROWS) { + nbgl_layoutAddNavigation(ctx->layout, &navInfo); + } + } + nbgl_layoutDraw(ctx->layout); + nbgl_refresh(); +} + +// callback on key touch +static void menuListActionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event) +{ + StepContext_t *ctx = getContextFromLayout(layout); + if (!ctx) { + return; + } + + if (event == BUTTON_LEFT_PRESSED) { + if (ctx->menuListContext.list.selectedChoice > 0) { + ctx->menuListContext.list.selectedChoice--; + displayMenuList(ctx); + } + } + else if (event == BUTTON_RIGHT_PRESSED) { + if (ctx->menuListContext.list.selectedChoice < (ctx->menuListContext.list.nbChoices - 1)) { + ctx->menuListContext.list.selectedChoice++; + displayMenuList(ctx); + } + } + else if (event == BUTTON_BOTH_PRESSED) { + ctx->menuListContext.selectedCallback(ctx->menuListContext.list.selectedChoice); + } +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief draws a text type step, that can be multi-pages, depending of the length of text and + * subText. The navigation arrows are displayed depending of the given position of this step in a + * flow, and depending of the page in case of multi-pages + * + * @param pos position of this step in the flow (first, last, single, not_first_nor_last) + * @param onActionCallback common callback for all actions on this page + * @param ticker ticker configuration, set to NULL to disable it + * @param text text to display (depending of style) + * @param subText text to display under text (depending of style) + * @param style style to use for text and subText + * @param modal if true, means this step shall be displayed on top of existing one + * @return the step context (or NULL if error) + */ +nbgl_step_t nbgl_stepDrawText(nbgl_stepPosition_t pos, + nbgl_stepButtonCallback_t onActionCallback, + nbgl_screenTickerConfiguration_t *ticker, + const char *text, + const char *subText, + nbgl_centeredInfoStyle_t style, + bool modal) +{ + StepContext_t *ctx = getFreeContext(TEXT_STEP, modal); + if (!ctx) { + return NULL; + } + // initialize context (already set to 0 by getFreeContext()) + ctx->textContext.onActionCallback = onActionCallback; + if (ticker) { + ctx->ticker.tickerCallback = ticker->tickerCallback; + ctx->ticker.tickerIntervale = ticker->tickerIntervale; + ctx->ticker.tickerValue = ticker->tickerValue; + } + + // if no subText, get the number of pages for main text + if (subText == NULL) { + ctx->textContext.nbPages = nbgl_getTextNbPagesInWidth( + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, text, NB_MAX_LINES, AVAILABLE_WIDTH); + } + else { + // NB_MAX_LINES-1 because first line is for main text + ctx->textContext.nbPages = nbgl_getTextNbPagesInWidth( + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, subText, NB_MAX_LINES - 1, AVAILABLE_WIDTH); + } + LOG_DEBUG(STEP_LOGGER, + "nbgl_stepDrawText: ctx = %p, nbPages = %d, pos = 0x%X\n", + ctx, + ctx->textContext.nbPages, + pos); + if (pos & BACKWARD_DIRECTION) { + // start with last page + ctx->textContext.currentPage = ctx->textContext.nbPages - 1; + } + ctx->textContext.txtStart = text; + ctx->textContext.subTxtStart = subText; + // keep only direction part of position + ctx->textContext.pos = pos & (RIGHT_ARROW | LEFT_ARROW); + ctx->textContext.style = style; + displayTextPage(ctx, ctx->textContext.currentPage); + + return (nbgl_step_t) ctx; +} + +/** + * @brief draw a step with a centered info (icon + text). This is always a single page step + * + * @param pos position of this step in the flow (first, last, single, not_first_nor_last) + * @param onActionCallback common callback for all actions on this page + * @param ticker ticker configuration, set to NULL to disable it + * @param info all information about the cenetered info to be displayed + * @param modal if true, means this step shall be displayed on top of existing one + * @return the step context (or NULL if error) + */ +nbgl_step_t nbgl_stepDrawCenteredInfo(nbgl_stepPosition_t pos, + nbgl_stepButtonCallback_t onActionCallback, + nbgl_screenTickerConfiguration_t *ticker, + nbgl_layoutCenteredInfo_t *info, + bool modal) +{ + nbgl_layoutDescription_t layoutDescription + = {.modal = modal, .onActionCallback = (nbgl_layoutButtonCallback_t) actionCallback}; + nbgl_layoutNavigation_t navInfo = { + .direction = HORIZONTAL_NAV, + }; + StepContext_t *ctx = getFreeContext(CENTERED_INFO_STEP, modal); + if (!ctx) { + return NULL; + } + + // initialize context (already set to 0 by getFreeContext()) + ctx->textContext.onActionCallback = onActionCallback; + if (ticker) { + ctx->ticker.tickerCallback = ticker->tickerCallback; + ctx->ticker.tickerIntervale = ticker->tickerIntervale; + ctx->ticker.tickerValue = ticker->tickerValue; + } + + ctx->textContext.nbPages = 1; + // keep only direction part of position + ctx->textContext.pos = pos & (RIGHT_ARROW | LEFT_ARROW); + navInfo.indication = getNavigationInfo( + ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage); + + ctx->layout = nbgl_layoutGet(&layoutDescription); + nbgl_layoutAddCenteredInfo(ctx->layout, info); + if (navInfo.indication != NO_ARROWS) { + nbgl_layoutAddNavigation(ctx->layout, &navInfo); + } + nbgl_layoutDraw(ctx->layout); + nbgl_refresh(); + + LOG_DEBUG(STEP_LOGGER, "nbgl_stepDrawCenteredInfo(): step = %p\n", ctx); + return (nbgl_step_t) ctx; +} + +/** + * @brief draw a step page with a menu list and navigation arrows to parse it. This step must be + * alone + * + * @param onActionCallback common callback for all actions on this page + * @param ticker ticker configuration, set to NULL to disable it + * @param list configuration of the menu list + * @param modal if true, means this step shall be displayed on top of existing one + * @return the step context (or NULL if error) + */ +nbgl_step_t nbgl_stepDrawMenuList(nbgl_stepMenuListCallback_t onActionCallback, + nbgl_screenTickerConfiguration_t *ticker, + nbgl_layoutMenuList_t *list, + bool modal) +{ + StepContext_t *ctx = getFreeContext(MENU_LIST_STEP, modal); + if (!ctx) { + return NULL; + } + + // initialize context (already set to 0 by getFreeContext()) + if (ticker) { + ctx->ticker.tickerCallback = ticker->tickerCallback; + ctx->ticker.tickerIntervale = ticker->tickerIntervale; + ctx->ticker.tickerValue = ticker->tickerValue; + } + + ctx->menuListContext.list.nbChoices = list->nbChoices; + ctx->menuListContext.list.selectedChoice = list->selectedChoice; + ctx->menuListContext.list.callback = list->callback; + ctx->menuListContext.selectedCallback = onActionCallback; + + displayMenuList(ctx); + + LOG_DEBUG(STEP_LOGGER, "nbgl_stepDrawMenuList(): step = %p\n", ctx); + + return (nbgl_step_t) ctx; +} + +/** + * @brief Get the index of the currently selected item in the menulist + * + * @param step step from which to get the current menulist choice + * @return current menulist choice + */ +uint8_t nbgl_stepGetMenuListCurrent(nbgl_step_t step) +{ + StepContext_t *ctx = (StepContext_t *) step; + if (!ctx) { + return 0; + } + return (ctx->menuListContext.list.selectedChoice); +} + +/** + * @brief Release the step obtained with any of the nbgl_stepDrawXXX() functions + * + * @param step step to release + * @return >= 0 if OK + */ +int nbgl_stepRelease(nbgl_step_t step) +{ + StepContext_t *ctx = (StepContext_t *) step; + int ret; + + LOG_DEBUG(STEP_LOGGER, "nbgl_stepRelease(): ctx = %p\n", ctx); + if (!ctx) { + return -1; + } + ret = nbgl_layoutRelease((nbgl_layout_t *) ctx->layout); + + ctx->layout = NULL; + + return ret; +} + +#endif // NBGL_STEP diff --git a/lib_nbgl/src/nbgl_touch.c b/lib_nbgl/src/nbgl_touch.c index 766c07c37..541bf7245 100644 --- a/lib_nbgl/src/nbgl_touch.c +++ b/lib_nbgl/src/nbgl_touch.c @@ -3,6 +3,7 @@ * Implementation of touchscreen management in new BAGL */ +#ifdef HAVE_SE_TOUCH /********************* * INCLUDES *********************/ @@ -282,3 +283,4 @@ nbgl_obj_t *nbgl_touchGetObjectFromId(nbgl_obj_t *obj, uint8_t id) return NULL; } } +#endif // HAVE_SE_TOUCH diff --git a/lib_nbgl/src/nbgl_use_case.c b/lib_nbgl/src/nbgl_use_case.c index 9349091f9..a8910331f 100644 --- a/lib_nbgl/src/nbgl_use_case.c +++ b/lib_nbgl/src/nbgl_use_case.c @@ -4,6 +4,7 @@ */ #ifdef NBGL_USE_CASE +#ifdef HAVE_SE_TOUCH /********************* * INCLUDES *********************/ @@ -480,7 +481,8 @@ static const char *getDetailsPageAt(uint8_t detailsPage) currentChar, SCREEN_WIDTH - 2 * BORDER_MARGIN, NB_MAX_LINES_IN_DETAILS, - &len); + &len, + false); len -= 3; currentChar = currentChar + len; } @@ -530,7 +532,8 @@ static void displayDetailsPage(uint8_t detailsPage, bool forceFullRefresh) currentPair.value, SCREEN_WIDTH - 2 * BORDER_MARGIN, NB_MAX_LINES_IN_DETAILS, - &len); + &len, + false); len -= 3; // memorize next position to save processing detailsContext.nextPageStart = currentPair.value + len; @@ -1428,4 +1431,5 @@ void nbgl_useCaseSpinner(const char *text) pageContext = nbgl_pageDrawSpinner(NULL, (const char *) text); nbgl_refreshSpecial(FULL_COLOR_PARTIAL_REFRESH); } +#endif // HAVE_SE_TOUCH #endif // NBGL_USE_CASE diff --git a/lib_nbgl/src/nbgl_use_case_nanos.c b/lib_nbgl/src/nbgl_use_case_nanos.c new file mode 100644 index 000000000..048273ccd --- /dev/null +++ b/lib_nbgl/src/nbgl_use_case_nanos.c @@ -0,0 +1,456 @@ +/** + * @file nbgl_use_case_nanos.c + * @brief Implementation of typical pages (or sets of pages) for Applications, for Nanos (X, SP) + */ + +#ifdef NBGL_USE_CASE +#ifndef HAVE_SE_TOUCH +/********************* + * INCLUDES + *********************/ +#include +#include +#include "nbgl_debug.h" +#include "nbgl_use_case.h" +#include "glyphs.h" +#include "os_pic.h" +#include "ux.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct ReviewContext_s { + nbgl_navCallback_t onNav; + nbgl_choiceCallback_t onChoice; + nbgl_layoutTagValueList_t tagValueList; + uint8_t currentPairIndex; + const nbgl_icon_details_t *icon; + const char *reviewTitle; + const char *acceptText; + const char *rejectText; + bool forwardNavOnly; +} ReviewContext_t; + +typedef struct HomeContext_s { + const char *appName; + const nbgl_icon_details_t *appIcon; + const char *appVersion; + const char *tagline; + nbgl_callback_t aboutCallback; + nbgl_callback_t quitCallback; +} HomeContext_t; + +typedef struct SettingsContext_s { + nbgl_navCallback_t onNav; + nbgl_callback_t quitCallback; + nbgl_actionCallback_t actionCallback; +} SettingsContext_t; + +typedef enum { + REVIEW_USE_CASE, + HOME_USE_CASE, + SETTINGS_USE_CASE +} ContextType_t; + +typedef struct UseCaseContext_s { + ContextType_t type; + uint8_t nbPages; + int8_t currentPage; + nbgl_step_t stepCtx; + nbgl_stepDesc_t step; + union { + ReviewContext_t review; + HomeContext_t home; + SettingsContext_t settings; + }; +} UseCaseContext_t; + +typedef struct AddressConfirmationContext_s { + const char *address; + nbgl_layout_t modalLayout; + const nbgl_layoutTagValueList_t *tagValueList; +} AddressConfirmationContext_t; + +/********************** + * STATIC VARIABLES + **********************/ +// char buffers to build some strings +static char appDescription[APP_DESCRIPTION_MAX_LEN]; + +static UseCaseContext_t context; + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void buttonCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event); +static void displayReviewPage(nbgl_stepPosition_t pos); +static void displayHomePage(nbgl_stepPosition_t pos); + +static void onAccept(void) +{ + if (context.review.onChoice) { + context.review.onChoice(true); + } +} + +static void onReject(void) +{ + if (context.review.onChoice) { + context.review.onChoice(false); + } +} + +static void onSettingsAction(void) +{ + if (context.settings.actionCallback) { + context.settings.actionCallback(context.currentPage); + } +} + +static void drawStep(nbgl_stepPosition_t pos, + const nbgl_icon_details_t *icon, + const char *txt, + const char *subTxt) +{ + if (context.nbPages > 1) { + pos |= NEITHER_FIRST_NOR_LAST_STEP; + } + else { + pos |= GET_POS_OF_STEP(context.currentPage, context.nbPages); + } + + if (icon == NULL) { + context.stepCtx + = nbgl_stepDrawText(pos, buttonCallback, NULL, txt, subTxt, BOLD_TEXT1_INFO, false); + } + else { + nbgl_layoutCenteredInfo_t info; + info.icon = icon; + info.text1 = txt; + info.text2 = subTxt; + info.onTop = false; + info.style = BOLD_TEXT1_INFO; + context.stepCtx = nbgl_stepDrawCenteredInfo(pos, buttonCallback, NULL, &info, false); + } +} + +static void buttonCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event) +{ + nbgl_stepPosition_t pos; + + UNUSED(stepCtx); + // create text_area for main text + if (event == BUTTON_LEFT_PRESSED) { + if (context.currentPage > 0) { + context.currentPage--; + } + else { + context.currentPage = (context.nbPages - 1); + } + pos = BACKWARD_DIRECTION; + } + else if (event == BUTTON_RIGHT_PRESSED) { + if (context.currentPage < (int) (context.nbPages - 1)) { + context.currentPage++; + } + else { + context.currentPage = 0; + } + pos = FORWARD_DIRECTION; + } + else { + if ((event == BUTTON_BOTH_PRESSED) && (context.step.callback != NULL)) { + context.step.callback(); + } + return; + } + if ((context.type == REVIEW_USE_CASE) || (context.type == SETTINGS_USE_CASE)) { + displayReviewPage(pos); + } + else { + displayHomePage(pos); + } +} + +// function used to display the current page in review +static void displayReviewPage(nbgl_stepPosition_t pos) +{ + memset(&context.step, 0, sizeof(context.step)); + + if (context.type == REVIEW_USE_CASE) { + if (context.review.onNav != NULL) { + // try to get content for this page/step + if (context.review.onNav(context.currentPage, &context.step) == false) { + return; + } + } + else { + if (context.currentPage == 0) { // title page + context.step.icon = context.review.icon; + context.step.text = context.review.reviewTitle; + } + else if (context.currentPage == (context.nbPages - 2)) { // accept page + context.step.icon = &C_icon_validate_14; + context.step.text = context.review.acceptText; + context.step.callback = onAccept; + } + else if (context.currentPage == (context.nbPages - 1)) { // reject page + context.step.icon = &C_icon_crossmark; + context.step.text = context.review.rejectText; + context.step.callback = onReject; + } + else { + context.step.text = context.review.tagValueList.pairs[context.currentPage - 1].item; + context.step.subText + = context.review.tagValueList.pairs[context.currentPage - 1].value; + } + } + } + else if (context.type == SETTINGS_USE_CASE) { + if (context.currentPage < (context.nbPages - 1)) { + // try to get content for this page/step + if ((context.settings.onNav == NULL) + || (context.settings.onNav(context.currentPage, &context.step) == false)) { + return; + } + context.step.callback = onSettingsAction; + } + else { // last page is for quit + context.step.icon = &C_icon_back_x; + context.step.text = "Back"; + context.step.callback = context.settings.quitCallback; + } + } + + const char *txt = NULL; + if (context.step.text != NULL) { + txt = context.step.text; + } + else if (context.step.textId != INVALID_ID) { + txt = get_ux_loc_string(context.step.textId); + } + if (context.step.init != NULL) { + context.step.init(); + } + drawStep(pos, context.step.icon, txt, context.step.subText); + nbgl_refresh(); +} + +// function used to display the current page in home +static void displayHomePage(nbgl_stepPosition_t pos) +{ + memset(&context.step, 0, sizeof(context.step)); + + switch (context.currentPage) { + case 0: + context.step.icon = context.home.appIcon; + context.step.text = context.home.tagline; + break; + case 1: + context.step.text = "Version"; + context.step.subText = context.home.appVersion; + break; + case 2: + context.step.icon = &C_icon_certificate; + context.step.text = "About"; + context.step.callback = context.home.aboutCallback; + break; + case 3: + context.step.icon = &C_icon_dashboard_x; + context.step.text = "Quit"; + context.step.callback = context.home.quitCallback; + break; + default: + break; + } + + const char *txt = NULL; + if (context.step.text != NULL) { + txt = context.step.text; + } + else if (context.step.textId != INVALID_ID) { + txt = get_ux_loc_string(context.step.textId); + } + if (context.step.init != NULL) { + context.step.init(); + } + drawStep(pos, context.step.icon, txt, context.step.subText); + nbgl_refresh(); +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief draws the home page of an app (page on which we land when launching it from dashboard) + * + * @param appName app name + * @param appIcon app icon + * @param appVersion app version + * @param tagline text under app name (if NULL, it will be "\nisready") + * @param aboutCallback callback called when the "about" step is selected (double key) + * @param quitCallback callback called when the "quit" step is selected (double key) + */ +void nbgl_useCaseHome(const char *appName, + const nbgl_icon_details_t *appIcon, + const char *appVersion, + const char *tagline, + nbgl_callback_t aboutCallback, + nbgl_callback_t quitCallback) +{ + memset(&context, 0, sizeof(UseCaseContext_t)); + context.type = HOME_USE_CASE; + context.home.aboutCallback = aboutCallback; + context.home.quitCallback = quitCallback; + + if (tagline == NULL) { + snprintf(appDescription, APP_DESCRIPTION_MAX_LEN, "%s\nis ready", appName); + context.home.tagline = appDescription; + } + else { + context.home.tagline = tagline; + } + + context.home.appName = appName; + context.home.appIcon = appIcon; + context.home.appVersion = appVersion; + + context.nbPages = 4; + context.currentPage = 0; + + displayHomePage(FORWARD_DIRECTION); +} + +/** + * @brief Draws the settings pages of an app with as many pages as given + * For each page, the given navCallback will be called to get the content. Only 'type' and + * union has to be set in this content + * + * @param initPage page on which to start [0->(nbPages-1)] + * @param nbPages number of pages + * @param quitCallback callback called when "quit" step is selected (double button) + * @param navCallback callback called when pages are navigated with buttons + * @param actionCallback callback called when one of the navigations page is selected (double + * button) + */ +void nbgl_useCaseSettings(uint8_t initPage, + uint8_t nbPages, + nbgl_callback_t quitCallback, + nbgl_navCallback_t navCallback, + nbgl_actionCallback_t actionCallback) +{ + memset(&context, 0, sizeof(UseCaseContext_t)); + // memorize context + context.type = SETTINGS_USE_CASE; + context.settings.onNav = navCallback; + context.settings.quitCallback = quitCallback; + context.settings.actionCallback = actionCallback; + + context.nbPages = nbPages + 1; + context.currentPage = initPage; + displayReviewPage(FORWARD_DIRECTION); +} + +/** + * @brief Draws a flow of pages of a review. Navigation is available for all pages + * For each page, the given navCallback will be called to get the content. + * When navigating before the first page of after the last page, the page number will be -1 + * + * @param initPage page on which to start [0->(nbPages-1)] + * @param nbPages number of pages. + * @param navCallback callback called when navigation is touched + */ +void nbgl_useCaseRegularReview(uint8_t initPage, uint8_t nbPages, nbgl_navCallback_t navCallback) +{ + memset(&context, 0, sizeof(UseCaseContext_t)); + context.type = REVIEW_USE_CASE; + // memorize context + context.review.onNav = navCallback; + context.review.forwardNavOnly = false; + + context.currentPage = initPage; + context.nbPages = nbPages; + + displayReviewPage(FORWARD_DIRECTION); +} + +/** + * @brief Draws a flow of pages of a review, without back key. + * It is possible to go to next page thanks to "tap to continue". + * For each page, the given navCallback will be called to get the content. Only 'type' and + * union has to be set in this content + * + * @param navCallback callback called when navigation "tap to continue" is touched, to get the + * content of next page + */ +void nbgl_useCaseForwardOnlyReview(nbgl_navCallback_t navCallback) +{ + // memorize context + context.type = REVIEW_USE_CASE; + context.review.onNav = navCallback; + context.review.forwardNavOnly = true; +} + +/** + * @brief Draws a flow of pages of a review. + * @note All tag/value pairs are provided in the API and the number of pages is automatically + * computed, the last page being a long press one + * + * @param tagValueList list of tag/value pairs + * @param icon icon to use in first page + * @param reviewTitle text to use in title page of the transaction + * @param acceptText text to use in validation page + * @param rejectText text to use in rejection page + * @param callback callback called when transaction is accepted (param is true) or rejected (param + * is false) + */ +void nbgl_useCaseStaticReview(nbgl_layoutTagValueList_t *tagValueList, + const nbgl_icon_details_t *icon, + const char *reviewTitle, + const char *acceptText, + const char *rejectText, + nbgl_choiceCallback_t callback) +{ + // memorize context + memset(&context, 0, sizeof(UseCaseContext_t)); + context.review.forwardNavOnly = false; + context.type = REVIEW_USE_CASE; + + memcpy(&context.review.tagValueList, tagValueList, sizeof(nbgl_layoutTagValueList_t)); + + context.review.currentPairIndex = 0; + context.review.reviewTitle = reviewTitle; + context.review.icon = icon; + context.review.acceptText = acceptText; + context.review.rejectText = rejectText; + context.review.onChoice = callback; + + context.currentPage = 0; + // + 3 because 1 page for title and 2 pages at the end for accept/reject + context.nbPages = tagValueList->nbPairs + 3; + + displayReviewPage(FORWARD_DIRECTION); +} + +/** + * @brief draw a spinner page with the given parameters. The spinner will "turn" automatically every + * 800 ms + * + * @param text text to use under spinner + */ +void nbgl_useCaseSpinner(const char *text) +{ + // pageContext = nbgl_pageDrawSpinner(NULL, (const char*)text); + UNUSED(text); + nbgl_refresh(); +} + +#endif // TARGET_STAX +#endif // NBGL_USE_CASE diff --git a/lib_nbgl/tools/icon2glyph.py b/lib_nbgl/tools/icon2glyph.py index d17373a79..98175952a 100755 --- a/lib_nbgl/tools/icon2glyph.py +++ b/lib_nbgl/tools/icon2glyph.py @@ -61,6 +61,9 @@ def open_image(file_path) -> Optional[Tuple[Image, int]]: if bits_per_pixel == 3: bits_per_pixel = 4 + if bits_per_pixel == 0: + bits_per_pixel = 1 + # Invert if bpp is 1 if bits_per_pixel == 1: im = ImageOps.invert(im) @@ -68,7 +71,7 @@ def open_image(file_path) -> Optional[Tuple[Image, int]]: return im, bits_per_pixel -def image_to_packed_buffer(img, bpp: int): +def image_to_packed_buffer(img, bpp: int, reverse_1bpp): """ Rotate and pack bitmap data of the character. """ @@ -94,6 +97,9 @@ def image_to_packed_buffer(img, bpp: int): if color_index >= nb_colors: color_index = nb_colors - 1 + if bpp == 1 and reverse_1bpp: + color_index = (color_index+1)&0x1 + # le encoded current_byte += color_index << ((8-bpp)-current_bit) current_bit += bpp @@ -113,12 +119,12 @@ def image_to_packed_buffer(img, bpp: int): # Compressions functions -def rle_compress(im: Image, bpp) -> Optional[bytes]: +def rle_compress(im: Image, bpp, reverse) -> Optional[bytes]: """ Run RLE compression on input image """ if bpp == 1: - return Rle1bpp.rle_1bpp(im)[1] + return Rle1bpp.rle_1bpp(im, reverse)[1] elif bpp == 2: # No compression supports BPP2 return None @@ -126,11 +132,11 @@ def rle_compress(im: Image, bpp) -> Optional[bytes]: return Rle4bpp.rle_4bpp(im)[1] -def gzlib_compress(im: Image, bpp: int) -> bytes: +def gzlib_compress(im: Image, bpp: int, reverse) -> bytes: """ Run gzlib compression on input image """ - pixels_buffer = image_to_packed_buffer(im, bpp) + pixels_buffer = image_to_packed_buffer(im, bpp, reverse) output_buffer = [] # cut into chunks of 2048 bytes max of uncompressed data (because decompression needs the full buffer) full_uncompressed_size = len(pixels_buffer) @@ -151,18 +157,25 @@ def gzlib_compress(im: Image, bpp: int) -> bytes: NBGL_IMAGE_FILE_HEADER_SIZE = 8 -def compress(im: Image, bpp) -> Tuple[NbglFileCompression, bytes]: +def compress(im: Image, bpp, reverse) -> Tuple[NbglFileCompression, bytes]: """ Compute multiple compression methods on the input image, and return a tuple containing: - The best compression method achieved - The associated compressed bytes """ - compressed_bufs = { - NbglFileCompression.NoCompression: image_to_packed_buffer(im, bpp), - NbglFileCompression.Gzlib: gzlib_compress(im, bpp), - NbglFileCompression.Rle: rle_compress(im, bpp) - } + # GZlib is not supported on Nanos + if not reverse: + compressed_bufs = { + NbglFileCompression.NoCompression: image_to_packed_buffer(im, bpp, reverse), + NbglFileCompression.Gzlib: gzlib_compress(im, bpp, reverse), + NbglFileCompression.Rle: rle_compress(im, bpp, reverse) + } + else: + compressed_bufs = { + NbglFileCompression.NoCompression: image_to_packed_buffer(im, bpp, reverse), + NbglFileCompression.Rle: rle_compress(im, bpp, reverse) + } min_len = len(compressed_bufs[NbglFileCompression.NoCompression]) min_comp = NbglFileCompression.NoCompression @@ -201,13 +214,13 @@ def convert_to_image_file(image_data: bytes, width: int, height: int, return bytes(bytearray(result)) -def compute_app_icon_data(im: Image, bpp) -> Tuple[bool, bytes]: +def compute_app_icon_data(im: Image, bpp, reverse) -> Tuple[bool, bytes]: """ Process image as app icon: - App icon are always image file - Compression is not limited to 64x64 """ - compression, image_data = compress(im, bpp) + compression, image_data = compress(im, bpp, reverse) is_file = True width, height = im.size image_data = convert_to_image_file( @@ -215,7 +228,7 @@ def compute_app_icon_data(im: Image, bpp) -> Tuple[bool, bytes]: return is_file, image_data -def compute_regular_icon_data(no_comp: bool, im: Image, bpp) -> Tuple[bool, bytes]: +def compute_regular_icon_data(no_comp: bool, im: Image, bpp, reverse) -> Tuple[bool, bytes]: """ Process image as regular icon: - Regular icon are image file only if compressed @@ -224,7 +237,7 @@ def compute_regular_icon_data(no_comp: bool, im: Image, bpp) -> Tuple[bool, byte width, height = im.size if not no_comp: - compression, image_data = compress(im, bpp) + compression, image_data = compress(im, bpp, reverse) if compression != NbglFileCompression.NoCompression: is_file = True image_data = convert_to_image_file( @@ -233,7 +246,7 @@ def compute_regular_icon_data(no_comp: bool, im: Image, bpp) -> Tuple[bool, byte is_file = False else: is_file = False - image_data = image_to_packed_buffer(im, bpp) + image_data = image_to_packed_buffer(im, bpp, reverse) return is_file, image_data # glyphs.c/.h chunk files generators @@ -295,6 +308,7 @@ def main(): parser.add_argument('--hexbitmaponly', action='store_true') parser.add_argument('--glyphcheader', action='store_true') parser.add_argument('--glyphcfile', action='store_true') + parser.add_argument('--reverse', help="Reverse B&W for 1BPP icons", action='store_true') args = parser.parse_args() # Print C header @@ -321,7 +335,7 @@ def main(): if args.hexbitmaponly: # Prepare and print app icon data - _, image_data = compute_app_icon_data(im, bpp) + _, image_data = compute_app_icon_data(im, bpp, args.reverse) print(binascii.hexlify(image_data).decode('utf-8')) else: # Prepare and print regular icon data @@ -334,7 +348,7 @@ def main(): else: no_comp = False - is_file, image_data = compute_regular_icon_data(no_comp, im, bpp) + is_file, image_data = compute_regular_icon_data(no_comp, im, bpp, args.reverse) if args.glyphcfile: print_glyphcfile_data(image_name, bpp, image_data) diff --git a/lib_nbgl/tools/nbgl_rle.py b/lib_nbgl/tools/nbgl_rle.py index c1655c814..86d8dd960 100644 --- a/lib_nbgl/tools/nbgl_rle.py +++ b/lib_nbgl/tools/nbgl_rle.py @@ -163,7 +163,7 @@ class Rle1bpp(): """ # ------------------------------------------------------------------------- @staticmethod - def image_to_pixels(img): + def image_to_pixels(img, reverse): """ Rotate and pack bitmap data of the character. return an array of pixels values. @@ -173,8 +173,12 @@ def image_to_pixels(img): pixels = [] # Intensity level value to be considered a white pixel white_threshold = 128 - white_pixel = 1 - black_pixel = 0 + if reverse: + white_pixel = 0 + black_pixel = 1 + else: + white_pixel = 1 + black_pixel = 0 # col first for col in reversed(range(width)): @@ -314,7 +318,7 @@ def decode_pass2(cls, data): # ------------------------------------------------------------------------- @classmethod - def rle_1bpp(cls, img) -> Tuple[int, bytes]: + def rle_1bpp(cls, img, reverse) -> Tuple[int, bytes]: """ Input: image to compress - convert the picture to an array of pixels @@ -322,7 +326,7 @@ def rle_1bpp(cls, img) -> Tuple[int, bytes]: - encode using custom RLE Output: array of compressed bytes """ - pixels = cls.image_to_pixels(img) + pixels = cls.image_to_pixels(img, reverse) pairs = cls.encode_pass1(pixels) encoded_data = cls.encode_pass2(pairs) diff --git a/lib_ux/include/ux.h b/lib_ux/include/ux.h index c3edb907f..7c86f1b40 100644 --- a/lib_ux/include/ux.h +++ b/lib_ux/include/ux.h @@ -27,6 +27,7 @@ #include "os_math.h" #include "os_ux.h" #include "os_task.h" +#include "os_screen.h" #ifndef HAVE_BOLOS_UX #ifndef HAVE_UX_FLOW diff --git a/lib_ux_stax/ux.h b/lib_ux_stax/ux.h index 26b153e4d..d5406b3f0 100644 --- a/lib_ux_stax/ux.h +++ b/lib_ux_stax/ux.h @@ -18,6 +18,10 @@ #pragma once +#if defined(HAVE_BOLOS) +#include "bolos_privileged_ux.h" +#endif // HAVE_BOLOS + #include "os_math.h" #include "os_ux.h" #include "os_task.h" @@ -26,6 +30,9 @@ #include +#define BUTTON_LEFT 1 +#define BUTTON_RIGHT 2 + typedef void (*asynchmodal_end_callback_t)(unsigned int ux_status); /** diff --git a/src/os_io_seproxyhal.c b/src/os_io_seproxyhal.c index d89af470a..683c08c5d 100644 --- a/src/os_io_seproxyhal.c +++ b/src/os_io_seproxyhal.c @@ -1036,7 +1036,7 @@ void io_seproxyhal_se_reset(void) #ifdef HAVE_SERIALIZED_NBGL -#define SERIALIZED_NBGL_MAX_LEN 100 +#define SERIALIZED_NBGL_MAX_LEN 120 static uint8_t nbgl_serialize_buffer[SERIALIZED_NBGL_MAX_LEN]; diff --git a/tools/ttf2inc.py b/tools/ttf2inc.py index cf8a1bff8..1861e595c 100755 --- a/tools/ttf2inc.py +++ b/tools/ttf2inc.py @@ -70,6 +70,7 @@ def __init__(self, args): self.loaded_baseline = 0 self.baseline_offset = 0 self.bpp = 1 + self.kerning = 0 self.char_info = {} self.ttf_info_dictionary = {} # Be sure there are at least some mandatory characters @@ -162,6 +163,7 @@ def init_config(self): self.font_size = config.getint('fontSize') self.line_size = config.getint('lineSize') self.crop = config.getboolean('crop', False) + self.kerning = config.getint('kerning',0) self.rle = config.getboolean('rle', True) self.bpp = config.getint('bpp', 1) self.nbgl = config.getboolean('nbgl', False) @@ -735,6 +737,7 @@ def save_nbgl_font(self, inc, crop, suffix, first_char, last_char): uint8_t bpp; ///< number of bits per pixels uint8_t height; ///< height of all characters in pixels uint8_t line_height; ///< height of a line for all characters in pixels + uint8_t char_kerning; ///< kerning for the font uint8_t crop; ///< If false, x_min_offset+y_min_offset=bytes to skip uint8_t y_min; ///< Most top Y coordinate of any char in the font uint8_t first_char; ///< ASCII code of the first character @@ -752,6 +755,7 @@ def save_nbgl_font(self, inc, crop, suffix, first_char, last_char): f" (uint8_t) NBGL_BPP_{self.bpp}, // bpp\n" f" {self.height}, // height of all characters in pixels\n" f" {self.line_size}, // line height in pixels\n" + f" {self.kerning}, // kerning\n" f" {crop}, // crop enabled (1) or not (0)\n" f" {self.char_topmost_y}, // Most top Y coordinate of any char\n" f" 0x{first_char:X}, // first character\n" @@ -842,8 +846,10 @@ def save_nbgl_font_unicode(self, inc, crop, suffix): uint8_t bpp; ///< Number of bits/pixels, (nbgl_bpp_t) uint8_t height; ///< height of all characters in pixels uint8_t line_height; ///< height of a line for all characters in pixels + uint8_t char_kerning; ///< kerning for the font uint8_t crop; ///< If false, x_min_offset+y_min_offset=bytes to skip uint8_t y_min; ///< Most top Y coordinate of any char in the font + uint8_t unused[3]; ///< for alignment uint16_t nb_characters; ///< Number of characters in this font } nbgl_font_unicode_t; """ @@ -855,8 +861,10 @@ def save_nbgl_font_unicode(self, inc, crop, suffix): f" (uint8_t) NBGL_BPP_{self.bpp}, // bpp\n" f" {self.height}, // height of all characters in pixels\n" f" {self.line_size}, // line height in pixels\n" + f" {self.kerning}, // kerning in pixels\n" f" {crop}, // crop enabled (1) or not (0)\n" f" {self.char_topmost_y}, // Most top Y coordinate of any char\n" + " 0,0,0, // for alignment\n" f" {len(self.char_info)}, // Nb of characters\n") if not suffix: inc.write(f" characters{self.basename.upper()},\n") @@ -1169,7 +1177,10 @@ def get_font_id(self): "BAGL_FONT_HM_ALPHA_MONO_MEDIUM_32px": 3, "BAGL_FONT_INTER_REGULAR_24px_1bpp": 4, "BAGL_FONT_INTER_SEMIBOLD_24px_1bpp": 5, - "BAGL_FONT_INTER_MEDIUM_32px_1bpp": 6 + "BAGL_FONT_INTER_MEDIUM_32px_1bpp": 6, + "BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp": 8, + "BAGL_FONT_OPEN_SANS_LIGHT_16px_1bpp": 9, + "BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp": 10 } if self.nbgl: font_ids = nbgl_font_ids @@ -1450,6 +1461,7 @@ def main(args): "height": ttf.height, "baseline": ttf.baseline, "line_height": ttf.line_size, + "char_kerning": ttf.kerning, "crop": crop, "nb_characters": len(ttf.char_info), "char_leftmost_x": ttf.char_leftmost_x, diff --git a/unit-tests/lib_nbgl/CMakeLists.txt b/unit-tests/lib_nbgl/CMakeLists.txt index bd86247ea..6b817fced 100644 --- a/unit-tests/lib_nbgl/CMakeLists.txt +++ b/unit-tests/lib_nbgl/CMakeLists.txt @@ -22,13 +22,24 @@ ENABLE_TESTING() # specify C standard set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED True) +if(DEFINED ENV{STAX}) add_compile_definitions(HAVE_BAGL_FONT_INTER_REGULAR_24PX) add_compile_definitions(HAVE_BAGL_FONT_INTER_SEMIBOLD_24PX) add_compile_definitions(HAVE_BAGL_FONT_INTER_MEDIUM_32PX) add_compile_definitions(HAVE_BAGL_FONT_HMALPHAMONO_MEDIUM_32PX) +add_compile_definitions(HAVE_SE_TOUCH) +else() +add_compile_definitions(HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX) +add_compile_definitions(HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX) +add_compile_definitions(HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX) +add_compile_definitions(BAGL_WIDTH=128) +add_compile_definitions(BAGL_HEIGHT=64) +endif() add_compile_definitions(HAVE_LANGUAGE_PACK) add_compile_definitions(HAVE_UNICODE_SUPPORT) add_compile_definitions(USB_SEGMENT_SIZE=64) +add_compile_definitions(HAVE_NBGL) +add_compile_definitions(WITH_STDIO) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall ${DEFINES} -g -O0 --coverage") @@ -43,20 +54,29 @@ endif() add_compile_definitions(TEST) +include_directories(.) include_directories(../../target/stax/include) include_directories(../../include) include_directories(../../lib_nbgl/include) include_directories(../../lib_ux_stax) add_executable(test_nbgl_fonts test_nbgl_fonts.c) +add_executable(test_nbgl_obj_pool test_nbgl_obj_pool.c) add_executable(test_nbgl_screen test_nbgl_screen.c) +add_executable(test_nbgl_obj test_nbgl_obj.c) -add_library(nbgl_obj_pool SHARED ../../lib_nbgl/src/nbgl_obj_pool.c) +add_library(nbgl_stubs SHARED nbgl_stubs.c) add_library(nbgl_fonts SHARED ../../lib_nbgl/src/nbgl_fonts.c) +add_library(nbgl_obj_pool SHARED ../../lib_nbgl/src/nbgl_obj_pool.c) add_library(nbgl_screen SHARED ../../lib_nbgl/src/nbgl_screen.c) +add_library(nbgl_obj SHARED ../../lib_nbgl/src/nbgl_obj.c) -target_link_libraries(test_nbgl_fonts PUBLIC cmocka gcov nbgl_fonts) -target_link_libraries(test_nbgl_screen PUBLIC cmocka gcov nbgl_screen nbgl_obj_pool) +target_link_libraries(test_nbgl_fonts PUBLIC cmocka gcov nbgl_fonts nbgl_stubs) +target_link_libraries(test_nbgl_obj_pool PUBLIC cmocka gcov nbgl_obj_pool nbgl_stubs) +target_link_libraries(test_nbgl_screen PUBLIC cmocka gcov nbgl_screen nbgl_obj_pool nbgl_stubs) +target_link_libraries(test_nbgl_obj PUBLIC cmocka gcov nbgl_obj nbgl_screen nbgl_obj_pool nbgl_fonts nbgl_stubs) add_test(test_nbgl_fonts test_nbgl_fonts) +add_test(test_nbgl_obj_pool test_nbgl_obj_pool) add_test(test_nbgl_screen test_nbgl_screen) +add_test(test_nbgl_obj test_nbgl_obj) diff --git a/unit-tests/lib_nbgl/README.md b/unit-tests/lib_nbgl/README.md index f41d4dd25..989f45baa 100644 --- a/unit-tests/lib_nbgl/README.md +++ b/unit-tests/lib_nbgl/README.md @@ -13,13 +13,29 @@ and for code coverage generation: ## Overview -In `unit-tests` folder, compile with +### For Stax + +In `unit-tests` folder, compile with: + +``` +STAX=1 cmake -Bbuild -H. && make -C build +``` + +and run tests with: + +``` +CTEST_OUTPUT_ON_FAILURE=1 make -C build test +``` + +### For Nanos + +In `unit-tests` folder, compile with: ``` cmake -Bbuild -H. && make -C build ``` -and run tests with +and run tests with: ``` CTEST_OUTPUT_ON_FAILURE=1 make -C build test diff --git a/unit-tests/lib_nbgl/bolos_pack_fr.bin b/unit-tests/lib_nbgl/bolos_pack_fr_nanos.bin similarity index 74% rename from unit-tests/lib_nbgl/bolos_pack_fr.bin rename to unit-tests/lib_nbgl/bolos_pack_fr_nanos.bin index b3cab90c7..2fcb5033a 100644 Binary files a/unit-tests/lib_nbgl/bolos_pack_fr.bin and b/unit-tests/lib_nbgl/bolos_pack_fr_nanos.bin differ diff --git a/unit-tests/lib_nbgl/bolos_pack_fr_stax.bin b/unit-tests/lib_nbgl/bolos_pack_fr_stax.bin new file mode 100644 index 000000000..fe4013422 Binary files /dev/null and b/unit-tests/lib_nbgl/bolos_pack_fr_stax.bin differ diff --git a/unit-tests/lib_nbgl/glyphs.h b/unit-tests/lib_nbgl/glyphs.h new file mode 100644 index 000000000..62f64b29e --- /dev/null +++ b/unit-tests/lib_nbgl/glyphs.h @@ -0,0 +1,35 @@ +// This file is just a stub necessary to build nbgl_obj.c for Stax +#pragma once + +#ifndef GLYPH_radio_active_32px_BPP +#define GLYPH_radio_active_32px_WIDTH 32 +#define GLYPH_radio_active_32px_HEIGHT 32 +#define GLYPH_radio_active_32px_ISFILE true +#define GLYPH_radio_active_32px_BPP 1 +extern uint8_t const C_radio_active_32px_bitmap[82]; +#ifdef HAVE_NBGL +extern const nbgl_icon_details_t C_radio_active_32px; +#endif // HAVE_NBGL +#endif // GLYPH_radio_active_32px_BPP + +#ifndef GLYPH_radio_inactive_32px_BPP +#define GLYPH_radio_inactive_32px_WIDTH 32 +#define GLYPH_radio_inactive_32px_HEIGHT 32 +#define GLYPH_radio_inactive_32px_ISFILE true +#define GLYPH_radio_inactive_32px_BPP 1 +extern uint8_t const C_radio_inactive_32px_bitmap[82]; +#ifdef HAVE_NBGL +extern const nbgl_icon_details_t C_radio_inactive_32px; +#endif // HAVE_NBGL +#endif // GLYPH_radio_inactive_32px_BPP + +#ifndef GLYPH_switch_60_40_BPP +#define GLYPH_switch_60_40_WIDTH 60 +#define GLYPH_switch_60_40_HEIGHT 40 +#define GLYPH_switch_60_40_ISFILE false +#define GLYPH_switch_60_40_BPP 1 +extern uint8_t const C_switch_60_40_bitmap[300]; +#ifdef HAVE_NBGL +extern const nbgl_icon_details_t C_switch_60_40; +#endif // HAVE_NBGL +#endif // GLYPH_switch_60_40_BPP diff --git a/unit-tests/lib_nbgl/nbgl_stubs.c b/unit-tests/lib_nbgl/nbgl_stubs.c new file mode 100644 index 000000000..fea9bb4e5 --- /dev/null +++ b/unit-tests/lib_nbgl/nbgl_stubs.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include "nbgl_fonts.h" +#include "ux_loc.h" + +void fetch_language_packs(void); + +const LANGUAGE_PACK *language_pack = NULL; + +void *pic(void *addr) +{ + return addr; +} + +void fetch_language_packs(void) +{ + // If we are looking for a language pack: + // - if the expected language is found then we'll use its begin/length range. + // - else we'll use the built-in package and need to reset allowed MMU range. + + FILE *fptr = NULL; + +#ifdef HAVE_SE_TOUCH + fptr = fopen("../bolos_pack_fr_stax.bin", "rb"); +#else // HAVE_SE_TOUCH + fptr = fopen("../bolos_pack_fr_nanos.bin", "rb"); +#endif // HAVE_SE_TOUCH + + assert_non_null(fptr); + if (fptr != NULL) { + fseek(fptr, 0, SEEK_END); + + uint32_t len = ftell(fptr); + + fseek(fptr, 0, SEEK_SET); + + uint8_t *source = (uint8_t *) malloc(len); + + assert_non_null(source); + + assert_int_equal(fread((unsigned char *) source, 1, len, fptr), len); + + fclose(fptr); + + language_pack = (LANGUAGE_PACK *) source; + } +} + +#include "nbgl_fonts.h" +#include "nbgl_font_hmalpha_mono_medium_32.inc" +#include "nbgl_font_inter_regular_24.inc" +#include "nbgl_font_inter_semibold_24.inc" +#include "nbgl_font_inter_medium_32.inc" +#include "nbgl_font_inter_regular_24_1bpp.inc" +#include "nbgl_font_inter_semibold_24_1bpp.inc" +#include "nbgl_font_inter_medium_32_1bpp.inc" +#include "nbgl_font_open_sans_extrabold_11.inc" +#include "nbgl_font_open_sans_regular_11.inc" +#include "nbgl_font_open_sans_light_16.inc" + +static const nbgl_font_t *const C_nbgl_fonts[] = { +#include "nbgl_font_rom_struct.inc" +}; +static const unsigned int C_nbgl_fonts_count = sizeof(C_nbgl_fonts) / sizeof(C_nbgl_fonts[0]); + +const nbgl_font_t *nbgl_font_getFont(unsigned int fontId) +{ + unsigned int i = C_nbgl_fonts_count; + while (i--) { + // font id match this entry (non indexed array) + if (C_nbgl_fonts[i]->font_id == fontId) { + return C_nbgl_fonts[i]; + } + } + + // id not found + return NULL; +} diff --git a/unit-tests/lib_nbgl/test_nbgl_fonts.c b/unit-tests/lib_nbgl/test_nbgl_fonts.c index 59dffe2d7..725435799 100644 --- a/unit-tests/lib_nbgl/test_nbgl_fonts.c +++ b/unit-tests/lib_nbgl/test_nbgl_fonts.c @@ -10,71 +10,9 @@ #include "nbgl_fonts.h" #include "ux_loc.h" -const LANGUAGE_PACK *language_pack = NULL; - -static void fetch_language_packs(void) -{ - // If we are looking for a language pack: - // - if the expected language is found then we'll use its begin/length range. - // - else we'll use the built-in package and need to reset allowed MMU range. - - FILE *fptr = NULL; - - fptr = fopen("../bolos_pack_fr.bin", "rb"); - - assert_non_null(fptr); - if (fptr != NULL) { - fseek(fptr, 0, SEEK_END); - - uint32_t len = ftell(fptr); - - fseek(fptr, 0, SEEK_SET); - - uint8_t *source = (uint8_t *) malloc(len); - - assert_non_null(source); - - assert_int_equal(fread((unsigned char *) source, 1, len, fptr), len); - - fclose(fptr); - - language_pack = (LANGUAGE_PACK *) source; - } -} - -#include "nbgl_fonts.h" -#include "nbgl_font_hmalpha_mono_medium_32.inc" -#include "nbgl_font_inter_regular_24.inc" -#include "nbgl_font_inter_semibold_24.inc" -#include "nbgl_font_inter_medium_32.inc" -#include "nbgl_font_inter_regular_24_1bpp.inc" -#include "nbgl_font_inter_semibold_24_1bpp.inc" -#include "nbgl_font_inter_medium_32_1bpp.inc" - -static const nbgl_font_t *const C_nbgl_fonts[] = { -#include "nbgl_font_rom_struct.inc" -}; -static const unsigned int C_nbgl_fonts_count = sizeof(C_nbgl_fonts) / sizeof(C_nbgl_fonts[0]); - -const nbgl_font_t *nbgl_font_getFont(unsigned int fontId) -{ - unsigned int i = C_nbgl_fonts_count; - while (i--) { - // font id match this entry (non indexed array) - if (C_nbgl_fonts[i]->font_id == fontId) { - return C_nbgl_fonts[i]; - } - } - - // id not found - return NULL; -} - -void *pic(void *addr) -{ - return addr; -} +void fetch_language_packs(void); +#ifdef HAVE_SE_TOUCH static void test_get_length(void **state __attribute__((unused))) { char *str_with_unicode = "çoto"; @@ -91,13 +29,13 @@ static void test_get_length(void **state __attribute__((unused))) assert_int_equal(strlen(str_with_unicode), 5); width = nbgl_getTextWidth(BAGL_FONT_INTER_REGULAR_24px, str_with_unicode); - assert_int_equal(width, 45); + assert_int_equal(width, 50); char myChar = 0x30; width = nbgl_getCharWidth(BAGL_FONT_INTER_REGULAR_24px, &myChar); assert_int_equal(width, 15); width = nbgl_getCharWidth(BAGL_FONT_INTER_REGULAR_24px, "ç"); - assert_int_equal(width, 8); + assert_int_equal(width, 13); assert_int_equal(nbgl_getTextNbLines(str_without_unicode), 1); assert_int_equal(nbgl_getTextNbLines(str_with_unicode), 1); @@ -153,7 +91,7 @@ static void test_get_length(void **state __attribute__((unused))) nbgl_getTextMaxLenAndWidth( BAGL_FONT_INTER_REGULAR_24px, "totçour\nau revoir", 50, &len, &width, false); assert_int_equal(len, 5); - assert_int_equal(width, 40); + assert_int_equal(width, 45); char textToWrap[32] = "toto"; nbgl_textWrapOnNbLines(BAGL_FONT_INTER_SEMIBOLD_24px, textToWrap, 156, 2); @@ -175,6 +113,110 @@ static void test_get_length(void **state __attribute__((unused))) = nbgl_getTextHeightInWidth(BAGL_FONT_INTER_MEDIUM_32px, "AB WWWWWWWW WWW W", 200, true); assert_int_equal(height, 160); } +#else // HAVE_SE_TOUCH +static void test_get_length(void **state __attribute__((unused))) +{ + uint16_t len; + uint16_t width; + fetch_language_packs(); + + width = nbgl_getTextWidth(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "justement ca tombe bienheureux"); + assert_int_equal(width, 0xAC); + width = nbgl_getTextWidth(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, "Setup as a"); + assert_int_equal(width, 0x35); + width = nbgl_getTextWidth(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, "new device"); + assert_int_equal(width, 0x3A); + + nbgl_getTextMaxLenAndWidth( + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, "new device", 114, &len, &width, false); + assert_int_equal(width, 0x3A); + + nbgl_getTextMaxLenAndWidth( + BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp, "la mise à jour", 114, &len, &width, false); + assert_int_equal(width, 80); + + nbgl_getTextMaxLenAndWidth( + BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp, "Confirmer", 114, &len, &width, false); + assert_int_equal(width, 58); + + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, "toto", 114, 4, &len, true); + assert_int_equal(len, 4); + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "toto\nbonjour au revoir a demain", + 114, + 4, + &len, + true); + assert_int_equal(len, strlen("toto\nbonjour au revoir a demain")); + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "toto\nbonjour au revoir a demain\njustement ca tombe bienheureux", + 114, + 4, + &len, + true); + assert_int_equal(len, strlen("toto\nbonjour au revoir a demain\njustement ca tombe ")); + + width = nbgl_getTextWidth(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "Pressing both buttons allows you"); + assert_int_equal(width, 0xAE); + + assert_int_equal( + 3, + nbgl_getTextNbPagesInWidth( + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "Pressing both buttons allows you\nto select or confirm\fNow, download Ledger Live " + "at\n\bledger.com/start\b\fFollow the instructions in Live to set up your Nano", + 4, + 114)); + nbgl_getTextMaxLenInNbLines( + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "Pressing both buttons allows you\nto select or confirm\fNow, download Ledger Live " + "at\n\bledger.com/start\b\fFollow the instructions in Live to set up your Nano", + 114, + 4, + &len, + true); + assert_int_equal(len, strlen("Pressing both buttons allows you\nto select or confirm\f")); + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "Now, download Ledger Live at\n\bledger.com/start\b\fFollow the " + "instructions in Live to set up your Nano", + 114, + 4, + &len, + true); + assert_int_equal(len, strlen("Now, download Ledger Live at\n\bledger.com/start\b\f")); + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "Follow the instructions in Live to set up your Nano", + 114, + 4, + &len, + true); + assert_int_equal(len, strlen("Follow the instructions in Live to set up your Nano")); + + width = nbgl_getTextWidth(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, "FCC Rules. Operation"); + assert_int_equal(width, 0x6E); + nbgl_getTextMaxLenInNbLines(BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "\bFCC Notes\b\nThis device complies with Part 15 of the FCC " + "Rules. Operation is subject to the following", + 114, + 4, + &len, + true); + assert_int_equal( + len, + strlen("\bFCC Notes\b\nThis device complies with Part 15 of the FCC Rules. Operation ")); + + uint8_t nbPages = nbgl_getTextNbPagesInWidth( + BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, + "Pour sélectionner ou confirmer, appuyez sur les deux boutons\fTéléchargez\nLedger " + "Live\nmaintenant sur\n\bledger.com/start\b\fSuivez les instructions dans Ledger Live pour " + "configurer\nvotre Nano", + 4, + 114); + assert_int_equal(nbPages, 3); +} +#endif // HAVE_SE_TOUCH int main(int argc, char **argv) { diff --git a/unit-tests/lib_nbgl/test_nbgl_obj.c b/unit-tests/lib_nbgl/test_nbgl_obj.c new file mode 100644 index 000000000..aa187a783 --- /dev/null +++ b/unit-tests/lib_nbgl/test_nbgl_obj.c @@ -0,0 +1,402 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include "nbgl_obj.h" +#include "nbgl_screen.h" +#include "nbgl_debug.h" +#include "ux_loc.h" + +#define UNUSED(x) (void) x + +unsigned long gLogger = 0; + +#ifdef HAVE_SE_TOUCH +#define GLYPH_switch_60_40_WIDTH 60 +#define GLYPH_switch_60_40_HEIGHT 40 +#define GLYPH_switch_60_40_ISFILE false +#define GLYPH_switch_60_40_BPP 1 +uint8_t const C_switch_60_40_bitmap[] = { + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, + 0x3f, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, + 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, + 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, + 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, + 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, + 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, + 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, + 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0x00, 0xff, 0xfc, 0x3f, 0xf8, 0x00, 0x1f, + 0xfc, 0x3f, 0xf0, 0x00, 0x0f, 0xfc, 0x3f, 0xc0, 0x00, 0x03, 0xfc, 0x3f, 0x80, 0x00, 0x01, 0xfc, + 0x3f, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x00, 0x7c, 0x3c, + 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x38, 0x00, + 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, + 0x00, 0x1c, 0x38, 0x00, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 0x00, + 0x1c, 0x38, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 0x00, 0x38, + 0x1c, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x70, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x07, + 0x00, 0x00, 0x00, 0xe0, 0x03, 0x80, 0x00, 0x01, 0xc0, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x01, 0xf0, + 0x00, 0x0f, 0x80, 0x00, 0xf8, 0x00, 0x1f, 0x00, 0x00, 0x3f, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0xff, + 0xf8, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, +}; +const nbgl_icon_details_t C_switch_60_40 = {GLYPH_switch_60_40_WIDTH, + GLYPH_switch_60_40_HEIGHT, + NBGL_BPP_1, + GLYPH_switch_60_40_ISFILE, + C_switch_60_40_bitmap}; + +#define GLYPH_radio_inactive_32px_WIDTH 32 +#define GLYPH_radio_inactive_32px_HEIGHT 32 +#define GLYPH_radio_inactive_32px_ISFILE true +#define GLYPH_radio_inactive_32px_BPP 1 +uint8_t const C_radio_inactive_32px_bitmap[] = { + 0x20, 0x00, 0x20, 0x00, 0x02, 0x4a, 0x00, 0x00, 0xc8, 0xf0, 0x6e, 0xf0, 0x2f, 0x01, + 0xef, 0x05, 0xbf, 0x07, 0x99, 0x69, 0x77, 0xc7, 0x66, 0xe6, 0x56, 0xf0, 0x16, 0x36, + 0xf0, 0x36, 0x25, 0xf0, 0x55, 0x25, 0xf0, 0x55, 0x16, 0xf0, 0x5b, 0xf0, 0x7a, 0xf0, + 0x7a, 0xf0, 0x7a, 0xf0, 0x7a, 0xf0, 0x7a, 0xf0, 0x7b, 0xf0, 0x56, 0x15, 0xf0, 0x55, + 0x25, 0xf0, 0x55, 0x26, 0xf0, 0x36, 0x36, 0xf0, 0x16, 0x56, 0xe6, 0x67, 0xc7, 0x79, + 0x69, 0x9f, 0x07, 0xbf, 0x05, 0xef, 0x01, 0xf0, 0x2e, 0xf0, 0x68, 0xc0, +}; +const nbgl_icon_details_t C_radio_inactive_32px = {GLYPH_radio_inactive_32px_WIDTH, + GLYPH_radio_inactive_32px_HEIGHT, + NBGL_BPP_1, + GLYPH_radio_inactive_32px_ISFILE, + C_radio_inactive_32px_bitmap}; + +#define GLYPH_radio_active_32px_WIDTH 32 +#define GLYPH_radio_active_32px_HEIGHT 32 +#define GLYPH_radio_active_32px_ISFILE true +#define GLYPH_radio_active_32px_BPP 1 +uint8_t const C_radio_active_32px_bitmap[] = { + 0x20, 0x00, 0x20, 0x00, 0x02, 0x4a, 0x00, 0x00, 0xc8, 0xf0, 0x6e, 0xf0, 0x2f, 0x01, + 0xef, 0x05, 0xbf, 0x07, 0x99, 0x69, 0x77, 0xc7, 0x66, 0xe6, 0x56, 0xf0, 0x16, 0x36, + 0xf0, 0x36, 0x25, 0x84, 0x85, 0x25, 0x68, 0x65, 0x16, 0x5a, 0x5b, 0x6a, 0x6a, 0x5c, + 0x5a, 0x5c, 0x5a, 0x5c, 0x5a, 0x5c, 0x5a, 0x6a, 0x6b, 0x5a, 0x56, 0x15, 0x68, 0x65, + 0x25, 0x84, 0x85, 0x26, 0xf0, 0x36, 0x36, 0xf0, 0x16, 0x56, 0xe6, 0x67, 0xc7, 0x79, + 0x69, 0x9f, 0x07, 0xbf, 0x05, 0xef, 0x01, 0xf0, 0x2e, 0xf0, 0x68, 0xc0, +}; +const nbgl_icon_details_t C_radio_active_32px = {GLYPH_radio_active_32px_WIDTH, + GLYPH_radio_active_32px_HEIGHT, + NBGL_BPP_1, + GLYPH_radio_active_32px_ISFILE, + C_radio_active_32px_bitmap}; +#else // HAVE_SE_TOUCH +#define GLYPH_bitcoin_logo_WIDTH 14 +#define GLYPH_bitcoin_logo_HEIGHT 14 +#define GLYPH_bitcoin_logo_ISFILE false +#define GLYPH_bitcoin_logo_BPP 1 +uint8_t const C_bitcoin_logo_bitmap[] = { + 0x07, 0x80, 0x7f, 0x83, 0xff, 0x1f, 0x8e, 0x70, 0x1b, 0x82, 0x7c, 0xdc, 0xfb, + 0x77, 0xc0, 0x0d, 0x80, 0x66, 0xfd, 0x8f, 0xfc, 0x1f, 0xe0, 0x1e, 0x00, +}; +const nbgl_icon_details_t C_bitcoin_logo = {GLYPH_bitcoin_logo_WIDTH, + GLYPH_bitcoin_logo_HEIGHT, + NBGL_BPP_1, + GLYPH_bitcoin_logo_ISFILE, + C_bitcoin_logo_bitmap}; +#endif // HAVE_SE_TOUCH + +static bool fatal_reached = false; + +void fetch_language_packs(void); + +void mainExit(int exitCode) +{ + fatal_reached = true; +} + +void nbgl_drawIcon(nbgl_area_t *area __attribute__((unused)), + nbgl_color_map_t color_map __attribute__((unused)), + const nbgl_icon_details_t *icon __attribute__((unused))) +{ +} +void nbgl_drawRoundedRect(const nbgl_area_t *area __attribute__((unused)), + nbgl_radius_t radius __attribute__((unused)), + color_t innerColor __attribute__((unused))) +{ +} +void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area __attribute__((unused)), + nbgl_radius_t radius __attribute__((unused)), + uint8_t stroke __attribute__((unused)), + color_t innerColor __attribute__((unused)), + color_t borderColor __attribute__((unused))) +{ +} +nbgl_font_id_e nbgl_drawText(const nbgl_area_t *area __attribute__((unused)), + const char *text __attribute__((unused)), + uint16_t textLen __attribute__((unused)), + nbgl_font_id_e fontId, + color_t fontColor __attribute__((unused))) +{ + return fontId; +} +void nbgl_drawQrCode(const nbgl_area_t *area __attribute__((unused)), + uint8_t version __attribute__((unused)), + const char *text __attribute__((unused)), + color_t backgroundColor __attribute__((unused))) +{ +} + +void nbgl_frontDrawRect(const nbgl_area_t *area __attribute__((unused))) {} +void nbgl_frontDrawHorizontalLine(const nbgl_area_t *area __attribute__((unused)), + uint8_t mask __attribute__((unused)), + color_t lineColor __attribute__((unused))) +{ +} +void nbgl_frontDrawImage(const nbgl_area_t *area __attribute__((unused)), + const uint8_t *buffer __attribute__((unused)), + nbgl_transformation_t transformation __attribute__((unused)), + nbgl_color_map_t colorMap __attribute__((unused))) +{ +} +void nbgl_frontDrawImageFile(const nbgl_area_t *area __attribute__((unused)), + const uint8_t *buffer __attribute__((unused)), + nbgl_color_map_t colorMap __attribute__((unused)), + const uint8_t *uzlib_chunk_buffer __attribute__((unused))) +{ +} +void nbgl_frontDrawImageRle(const nbgl_area_t *area __attribute__((unused)), + const uint8_t *buffer __attribute__((unused)), + uint32_t buffer_len __attribute__((unused)), + color_t fore_color __attribute__((unused)), + uint8_t nb_skipped_bytes __attribute__((unused))) +{ +} +void nbgl_frontRefreshArea(const nbgl_area_t *area __attribute__((unused)), + nbgl_refresh_mode_t mode __attribute__((unused)), + nbgl_post_refresh_t post_refresh __attribute__((unused))) +{ +} + +void nbgl_objDrawKeyboard(nbgl_keyboard_t *kbd __attribute__((unused))) {} +void nbgl_objDrawKeypad(nbgl_keypad_t *kbd __attribute__((unused))) {} + +const char *get_ux_loc_string(UX_LOC_STRINGS_INDEX index __attribute__((unused))) +{ + return NULL; +} + +uint8_t touch_exclude_borders(uint8_t excluded_borders) +{ + return excluded_borders; +} + +unsigned int nbgl_screen_reinit(void) +{ + return 0; +} + +#ifdef HAVE_SE_TOUCH +static void test_draw_obj(void **state __attribute__((unused))) +{ + nbgl_image_t *image; + nbgl_line_t *line; + nbgl_text_area_t *textArea; + nbgl_button_t *button; + nbgl_switch_t *switchObj; + nbgl_page_indicator_t *indicator; + nbgl_progress_bar_t *progress; + nbgl_radio_t *radio; + nbgl_spinner_t *spinner; + nbgl_obj_t **screenChildren = NULL; + int layer; + + fetch_language_packs(); + nbgl_objInit(); + + layer = nbgl_screenSet(&screenChildren, 9, NULL, NULL); + assert_int_equal(layer, 0); + assert_non_null(screenChildren); + + // all objects are drawn one under the other + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layer); + assert_non_null(textArea); + textArea->textColor = WHITE; + textArea->text = "TRUST YOURSELF"; + textArea->textAlignment = CENTER; + textArea->fontId = BAGL_FONT_HM_ALPHA_MONO_MEDIUM_32px; + textArea->obj.alignTo = NULL; + textArea->obj.alignment = TOP_LEFT; + textArea->obj.area.width = 340; + textArea->obj.area.height = 80; + screenChildren[0] = (nbgl_obj_t *) textArea; + + image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layer); + assert_non_null(image); + image->foregroundColor = BLACK; + image->buffer = &C_radio_active_32px; + image->obj.alignTo = (nbgl_obj_t *) textArea; + image->obj.alignment = BOTTOM_LEFT; + image->obj.area.width = 340; + image->obj.area.height = 80; + screenChildren[1] = (nbgl_obj_t *) image; + + line = (nbgl_line_t *) nbgl_objPoolGet(LINE, layer); + assert_non_null(line); + line->lineColor = BLACK; + line->direction = HORIZONTAL; + line->offset = 0; + line->thickness = 4; + line->obj.alignTo = (nbgl_obj_t *) image; + line->obj.alignment = BOTTOM_LEFT; + line->obj.area.width = 340; + line->obj.area.height = 4; + screenChildren[2] = (nbgl_obj_t *) line; + + button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layer); + assert_non_null(button); + button->fontId = BAGL_FONT_INTER_REGULAR_24px; + button->borderColor = BLACK; + button->foregroundColor = BLACK; + button->innerColor = WHITE; + button->text = "something"; + button->obj.alignTo = (nbgl_obj_t *) line; + button->obj.alignment = BOTTOM_LEFT; + button->obj.area.width = 340; + button->obj.area.height = 32; + screenChildren[3] = (nbgl_obj_t *) button; + + switchObj = (nbgl_switch_t *) nbgl_objPoolGet(SWITCH, layer); + assert_non_null(switchObj); + switchObj->offColor = LIGHT_GRAY; + switchObj->onColor = BLACK; + switchObj->state = ON_STATE; + switchObj->obj.alignTo = (nbgl_obj_t *) button; + switchObj->obj.alignment = BOTTOM_LEFT; + screenChildren[4] = (nbgl_obj_t *) switchObj; + + indicator = (nbgl_page_indicator_t *) nbgl_objPoolGet(PAGE_INDICATOR, layer); + assert_non_null(indicator); + indicator->activePage = 0; + indicator->nbPages = 8; + indicator->obj.alignTo = (nbgl_obj_t *) switchObj; + indicator->obj.alignment = BOTTOM_LEFT; + indicator->obj.area.width = 340; + screenChildren[5] = (nbgl_obj_t *) indicator; + + progress = (nbgl_progress_bar_t *) nbgl_objPoolGet(PROGRESS_BAR, layer); + assert_non_null(progress); + progress->state = 10; + progress->foregroundColor = BLACK; + progress->obj.alignTo = (nbgl_obj_t *) indicator; + progress->obj.alignment = BOTTOM_LEFT; + progress->obj.area.width = 340; + progress->obj.area.height = 32; + screenChildren[6] = (nbgl_obj_t *) progress; + + radio = (nbgl_radio_t *) nbgl_objPoolGet(RADIO_BUTTON, layer); + assert_non_null(radio); + radio->state = 10; + radio->activeColor = BLACK; + radio->borderColor = BLACK; + radio->obj.alignTo = (nbgl_obj_t *) progress; + radio->obj.alignment = BOTTOM_LEFT; + screenChildren[7] = (nbgl_obj_t *) radio; + + spinner = (nbgl_spinner_t *) nbgl_objPoolGet(SPINNER, layer); + assert_non_null(spinner); + spinner->position = 1; + spinner->obj.alignTo = (nbgl_obj_t *) radio; + spinner->obj.alignment = BOTTOM_LEFT; + screenChildren[8] = (nbgl_obj_t *) spinner; + nbgl_screenRedraw(); + + // check positions of every object + assert_int_equal(textArea->obj.area.x0, 0); + assert_int_equal(textArea->obj.area.y0, 0); + + assert_int_equal(image->obj.area.x0, 0); + assert_int_equal(image->obj.area.y0, 80); + + assert_int_equal(line->obj.area.x0, 0); + assert_int_equal(line->obj.area.y0, 112); + + assert_int_equal(button->obj.area.x0, 0); + assert_int_equal(button->obj.area.y0, 116); + + assert_int_equal(switchObj->obj.area.x0, 0); + assert_int_equal(switchObj->obj.area.y0, 148); + + assert_int_equal(indicator->obj.area.x0, 0); + assert_int_equal(indicator->obj.area.y0, 188); + + assert_int_equal(progress->obj.area.x0, 0); + assert_int_equal(progress->obj.area.y0, 192); + + assert_int_equal(radio->obj.area.x0, 0); + assert_int_equal(radio->obj.area.y0, 224); + + assert_int_equal(spinner->obj.area.x0, 0); + assert_int_equal(spinner->obj.area.y0, 256); +} +#else // HAVE_SE_TOUCH + +static void test_draw_obj(void **state __attribute__((unused))) +{ + nbgl_image_t *image; + nbgl_text_area_t *textArea; + nbgl_progress_bar_t *progress; + nbgl_obj_t **screenChildren = NULL; + int layer; + + fetch_language_packs(); + nbgl_objInit(); + + layer = nbgl_screenSet(&screenChildren, 3, NULL, NULL); + assert_int_equal(layer, 0); + assert_non_null(screenChildren); + + // all objects are drawn one under the other + textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layer); + assert_non_null(textArea); + textArea->textColor = BLACK; + textArea->text = "TRUST"; + textArea->textAlignment = CENTER; + textArea->fontId = BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp; + textArea->obj.alignTo = NULL; + textArea->obj.alignment = TOP_LEFT; + textArea->obj.area.width = 80; + textArea->obj.area.height = 16; + screenChildren[0] = (nbgl_obj_t *) textArea; + + image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layer); + assert_non_null(image); + image->foregroundColor = BLACK; + image->buffer = &C_bitcoin_logo; + image->obj.alignTo = (nbgl_obj_t *) textArea; + image->obj.alignment = BOTTOM_LEFT; + image->obj.area.width = 20; + image->obj.area.height = 80; + screenChildren[1] = (nbgl_obj_t *) image; + + progress = (nbgl_progress_bar_t *) nbgl_objPoolGet(PROGRESS_BAR, layer); + assert_non_null(progress); + progress->state = 10; + progress->foregroundColor = BLACK; + progress->obj.alignTo = (nbgl_obj_t *) image; + progress->obj.alignment = BOTTOM_LEFT; + progress->obj.area.width = 20; + progress->obj.area.height = 32; + screenChildren[2] = (nbgl_obj_t *) progress; + nbgl_screenRedraw(); + + // check positions of every object + assert_int_equal(textArea->obj.area.x0, 0); + assert_int_equal(textArea->obj.area.y0, 0); + + assert_int_equal(image->obj.area.x0, 0); + assert_int_equal(image->obj.area.y0, 16); + + assert_int_equal(progress->obj.area.x0, 0); + assert_int_equal(progress->obj.area.y0, 30); +} +#endif // HAVE_SE_TOUCH + +int main(int argc, char **argv) +{ + const struct CMUnitTest tests[] = {cmocka_unit_test(test_draw_obj)}; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/unit-tests/lib_nbgl/test_nbgl_obj_pool.c b/unit-tests/lib_nbgl/test_nbgl_obj_pool.c new file mode 100644 index 000000000..214e12a99 --- /dev/null +++ b/unit-tests/lib_nbgl/test_nbgl_obj_pool.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include "nbgl_obj.h" +#include "nbgl_debug.h" +#include "ux_loc.h" + +#define UNUSED(x) (void) x + +unsigned long gLogger = 0; + +static bool fatal_reached = false; + +void mainExit(int exitCode) +{ + fatal_reached = true; +} + +static void test_alloc_obj(void **state __attribute__((unused))) +{ + nbgl_obj_t *obj1, *obj2, *objArray[100]; + + obj1 = nbgl_objPoolGet(IMAGE, 0); + assert_non_null(obj1); + assert_int_equal(obj1->type, IMAGE); + obj2 = nbgl_objPoolGet(TEXT_AREA, 0); + assert_non_null(obj2); + assert_int_equal(obj2->type, TEXT_AREA); + + assert_ptr_equal(obj1, nbgl_objPoolGetPrevious(obj2, 0)); + + assert_int_equal(nbgl_objPoolGetArray(IMAGE, 10, 0, objArray), 0); + + assert_int_equal(nbgl_objPoolGetNbUsed(0), 12); + nbgl_objPoolRelease(0); + assert_int_equal(nbgl_objPoolGetNbUsed(0), 0); + + // try to allocate too many objects + nbgl_objPoolGetArray(IMAGE, 100, 0, objArray); + assert_true(fatal_reached); + fatal_reached = false; +} + +static void test_alloc_container(void **state __attribute__((unused))) +{ + nbgl_obj_t **container1, **container2; + + container1 = nbgl_containerPoolGet(10, 0); + assert_non_null(container1); + + container2 = nbgl_containerPoolGet(12, 0); + assert_non_null(container2); + + assert_int_equal(nbgl_containerPoolGetNbUsed(0), 22); + nbgl_containerPoolRelease(0); + assert_int_equal(nbgl_containerPoolGetNbUsed(0), 0); + + // try to allocate too many containers + nbgl_containerPoolGet(200, 0); + assert_true(fatal_reached); + fatal_reached = false; +} + +int main(int argc, char **argv) +{ + const struct CMUnitTest tests[] + = {cmocka_unit_test(test_alloc_obj), cmocka_unit_test(test_alloc_container)}; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/unit-tests/lib_nbgl/test_nbgl_screen.c b/unit-tests/lib_nbgl/test_nbgl_screen.c index 4ddce49cc..0f3744834 100644 --- a/unit-tests/lib_nbgl/test_nbgl_screen.c +++ b/unit-tests/lib_nbgl/test_nbgl_screen.c @@ -13,11 +13,7 @@ #define UNUSED(x) (void) x -unsigned long gLogger = 0 - // | (1<