diff --git a/core/embed/extmod/modtrezorui/display.c b/core/embed/extmod/modtrezorui/display.c index e938b67ee..825eb9b3a 100644 --- a/core/embed/extmod/modtrezorui/display.c +++ b/core/embed/extmod/modtrezorui/display.c @@ -692,6 +692,37 @@ int display_text_width(const char *text, int textlen, int font) { return width; } +// Returns how many characters of the string can be used before exceeding +// the requested width. Tries to avoid breaking words if possible. +int display_text_split(const char *text, int textlen, int font, + int requested_width) { + int width = 0; + int lastspace = 0; +#if TREZOR_MODEL == T + // determine text length if not provided + if (textlen < 0) { + textlen = strlen(text); + } + for (int i = 0; i < textlen; i++) { + if (text[i] == ' ') { + lastspace = i; + } + const uint8_t *g = get_glyph(font, (uint8_t)text[i]); + if (!g) continue; + const uint8_t adv = g[2]; // advance + width += adv; + if (width > requested_width) { + if (lastspace > 0) { + return lastspace; + } else { + return i; + } + } + } +#endif + return textlen; +} + #define QR_MAX_VERSION 9 void display_qrcode(int x, int y, const char *data, uint32_t datalen, diff --git a/core/embed/extmod/modtrezorui/display.h b/core/embed/extmod/modtrezorui/display.h index 1145cfa2f..c34b27e51 100644 --- a/core/embed/extmod/modtrezorui/display.h +++ b/core/embed/extmod/modtrezorui/display.h @@ -103,6 +103,8 @@ void display_text_center(int x, int y, const char *text, int textlen, int font, void display_text_right(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor); int display_text_width(const char *text, int textlen, int font); +int display_text_split(const char *text, int textlen, int font, + int requested_width); void display_qrcode(int x, int y, const char *data, uint32_t datalen, uint8_t scale); diff --git a/core/embed/extmod/modtrezorui/modtrezorui-display.h b/core/embed/extmod/modtrezorui/modtrezorui-display.h index 234187fe0..c703e9a44 100644 --- a/core/embed/extmod/modtrezorui/modtrezorui-display.h +++ b/core/embed/extmod/modtrezorui/modtrezorui-display.h @@ -414,6 +414,25 @@ STATIC mp_obj_t mod_trezorui_Display_text_width(mp_obj_t self, mp_obj_t text, STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorui_Display_text_width_obj, mod_trezorui_Display_text_width); +/// def text_split(self, text: str, font: int, requested_width: int) -> int: +/// """ +/// Returns how many characters of the string can be used before exceeding +/// the requested width. Tries to avoid breaking words if possible. Font +/// font is used for rendering. +/// """ +STATIC mp_obj_t mod_trezorui_Display_text_split(size_t n_args, + const mp_obj_t *args) { + mp_buffer_info_t text; + mp_get_buffer_raise(args[1], &text, MP_BUFFER_READ); + mp_int_t font = mp_obj_get_int(args[2]); + mp_int_t requested_width = mp_obj_get_int(args[3]); + int chars = display_text_split(text.buf, text.len, font, requested_width); + return mp_obj_new_int(chars); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_text_split_obj, + 4, 4, + mod_trezorui_Display_text_split); + /// def qrcode(self, x: int, y: int, data: bytes, scale: int) -> None: /// """ /// Renders data encoded as a QR code centered at position (x,y). @@ -563,6 +582,8 @@ STATIC const mp_rom_map_elem_t mod_trezorui_Display_locals_dict_table[] = { MP_ROM_PTR(&mod_trezorui_Display_text_right_obj)}, {MP_ROM_QSTR(MP_QSTR_text_width), MP_ROM_PTR(&mod_trezorui_Display_text_width_obj)}, + {MP_ROM_QSTR(MP_QSTR_text_split), + MP_ROM_PTR(&mod_trezorui_Display_text_split_obj)}, {MP_ROM_QSTR(MP_QSTR_qrcode), MP_ROM_PTR(&mod_trezorui_Display_qrcode_obj)}, {MP_ROM_QSTR(MP_QSTR_orientation), MP_ROM_PTR(&mod_trezorui_Display_orientation_obj)}, diff --git a/core/mocks/generated/trezorui.pyi b/core/mocks/generated/trezorui.pyi index a421b7fa0..57de8d748 100644 --- a/core/mocks/generated/trezorui.pyi +++ b/core/mocks/generated/trezorui.pyi @@ -157,6 +157,13 @@ class Display: Returns a width of text in pixels. Font font is used for rendering. """ + def text_split(self, text: str, font: int, requested_width: int) -> int: + """ + Returns how many characters of the string can be used before exceeding + the requested width. Tries to avoid breaking words if possible. Font + font is used for rendering. + """ + def qrcode(self, x: int, y: int, data: bytes, scale: int) -> None: """ Renders data encoded as a QR code centered at position (x,y).