10#include "app_config.h"
14#include "os_helpers.h"
16#if defined(HAVE_LANGUAGE_PACK)
23#define PIC_FONT(x) ((nbgl_font_t const *) PIC(x))
24#define BAGL_FONT_ID_MASK 0x0FFF
26#define IS_WORD_DELIM(c) (c == ' ' || c == '\n' || c == '\b' || c == '\f' || c == '-' || c == '_')
35#ifdef HAVE_UNICODE_SUPPORT
43#ifdef HAVE_LANGUAGE_PACK
47#if SMALL_FONT_HEIGHT == 24
48#include "nbgl_font_inter_regular_24.inc"
49#include "nbgl_font_inter_semibold_24.inc"
50#include "nbgl_font_inter_medium_32.inc"
51#include "nbgl_font_inter_regular_24_1bpp.inc"
52#include "nbgl_font_inter_semibold_24_1bpp.inc"
53#include "nbgl_font_inter_medium_32_1bpp.inc"
54#elif SMALL_FONT_HEIGHT == 28
55#include "nbgl_font_inter_regular_28.inc"
56#include "nbgl_font_inter_semibold_28.inc"
57#include "nbgl_font_inter_medium_36.inc"
58#include "nbgl_font_inter_regular_28_1bpp.inc"
59#include "nbgl_font_inter_semibold_28_1bpp.inc"
60#include "nbgl_font_inter_medium_36_1bpp.inc"
61#elif SMALL_FONT_HEIGHT == 18
62#include "nbgl_font_nanotext_medium_18_1bpp.inc"
63#include "nbgl_font_nanotext_bold_18_1bpp.inc"
64#include "nbgl_font_nanodisplay_semibold_24_1bpp.inc"
65#elif SMALL_FONT_HEIGHT == 11
66#include "nbgl_font_open_sans_extrabold_11.inc"
67#include "nbgl_font_open_sans_regular_11.inc"
68#include "nbgl_font_open_sans_light_16.inc"
73#include "nbgl_font_rom_struct.inc"
76__attribute__((section(
"._nbgl_fonts_"))) const
unsigned int C_nbgl_fonts_count
77 = sizeof(C_nbgl_fonts) / sizeof(C_nbgl_fonts[0]);
79#if (defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP))
80#if !defined(HAVE_LANGUAGE_PACK)
83#include "nbgl_font_unicode_rom_struct.inc"
88const unsigned int C_unicode_characters_count
89 = (
sizeof(charactersOPEN_SANS_REGULAR_11PX_UNICODE)
90 /
sizeof(charactersOPEN_SANS_REGULAR_11PX_UNICODE[0]));
95#ifdef BUILD_SCREENSHOTS
97uint16_t last_nb_lines = 0;
98uint16_t last_nb_pages = 0;
99bool last_bold_state =
false;
102bool hard_caesura =
false;
121 unsigned int i = C_nbgl_fonts_count;
126 if (
PIC_FONT(C_nbgl_fonts[i])->font_id == fontId) {
146 const uint8_t *txt = *text;
147 uint8_t cur_char = *txt++;
161 if ((cur_char >= 0xF0) && (*textLen >= 4)) {
162 unicode = (cur_char & 0x07) << 18;
163 unicode |= (*txt++ & 0x3F) << 12;
164 unicode |= (*txt++ & 0x3F) << 6;
165 unicode |= (*txt++ & 0x3F);
169 else if ((cur_char >= 0xE0) && (*textLen >= 3)) {
170 unicode = (cur_char & 0x0F) << 12;
171 unicode |= (*txt++ & 0x3F) << 6;
172 unicode |= (*txt++ & 0x3F);
177 else if ((cur_char >= 0xC2) && (*textLen >= 2)) {
178 unicode = (cur_char & 0x1F) << 6;
179 unicode |= (*txt++ & 0x3F);
185 *textLen = *textLen - (txt - *text);
198static uint8_t getCharWidth(
const nbgl_font_t *font, uint32_t unicode,
bool is_unicode)
201#ifdef HAVE_UNICODE_SUPPORT
203 = nbgl_getUnicodeFontCharacter(unicode);
204 if (!unicodeCharacter) {
214 if ((unicode < font->first_char) || (unicode > font->
last_char)) {
238#ifdef BUILD_SCREENSHOTS
239 uint16_t nb_lines = 0;
241 uint16_t line_width = 0;
242 uint16_t max_width = 0;
244 uint16_t textLen =
MIN(strlen(text), maxLen);
245#ifdef HAVE_UNICODE_SUPPORT
249#ifdef BUILD_SCREENSHOTS
251 bool next_bold_state = last_bold_state;
261#ifdef HAVE_UNICODE_SUPPORT
262 if (is_unicode && !unicode_ctx) {
263 unicode_ctx = nbgl_getUnicodeFont(fontId);
266 if (unicode ==
'\n') {
267 if (breakOnLineEnd) {
275 else if (unicode ==
'\b') {
278#ifdef HAVE_UNICODE_SUPPORT
282#ifdef BUILD_SCREENSHOTS
283 next_bold_state =
true;
288#ifdef HAVE_UNICODE_SUPPORT
292#ifdef BUILD_SCREENSHOTS
293 next_bold_state =
false;
298 char_width = getCharWidth(font, unicode, is_unicode);
299#ifdef BUILD_SCREENSHOTS
300 if (char_width != 0) {
302 last_bold_state = next_bold_state;
305 line_width += char_width;
307 if (line_width > max_width) {
308 max_width = line_width;
311#ifdef BUILD_SCREENSHOTS
312 if (line_width != 0) {
315 last_nb_lines = nb_lines;
330 return getTextWidth(fontId, text,
true, 0xFFFF);
344 return getTextWidth(fontId, text,
true, maxLen);
356 return getTextWidth(fontId, text,
false, 0xFFFF);
371 uint16_t textLen = 4;
372#ifdef HAVE_UNICODE_SUPPORT
377#ifdef HAVE_UNICODE_SUPPORT
378 if (is_unicode && !unicode_ctx) {
379 unicode_ctx = nbgl_getUnicodeFont(fontId);
383 return getCharWidth(font, unicode, is_unicode);
418 uint16_t nbLines = 1;
450 const char *origText = text;
455 else if (*text ==
'\n') {
460 return text - origText;
485 uint32_t lenAtLastDelimiter = 0, widthAtlastDelimiter = 0;
486#ifdef HAVE_UNICODE_SUPPORT
496 uint16_t curTextLen = textLen;
499#ifdef HAVE_UNICODE_SUPPORT
500 if (is_unicode && !unicode_ctx) {
501 unicode_ctx = nbgl_getUnicodeFont(fontId);
505 if ((unicode ==
'\f') || (unicode ==
'\n')) {
506 *len += curTextLen - textLen;
510 else if (unicode ==
'\b') {
513#ifdef HAVE_UNICODE_SUPPORT
520#ifdef HAVE_UNICODE_SUPPORT
525 *len += curTextLen - textLen;
529 char_width = getCharWidth(font, unicode, is_unicode);
530 if (char_width == 0) {
531 *len += curTextLen - textLen;
537 lenAtLastDelimiter = *len;
538 widthAtlastDelimiter = *width;
540 if ((*width + char_width) > maxWidth) {
541 if ((wrapping ==
true) && (widthAtlastDelimiter > 0)) {
542 *len = lenAtLastDelimiter + 1;
543 *width = widthAtlastDelimiter;
547 *len += curTextLen - textLen;
548 *width = *width + char_width;
574 uint16_t textLen = strlen(text);
576 const char *lastDelimiter = NULL;
577 uint32_t lenAtLastDelimiter = 0;
578 const char *origText = text;
579 const char *previousText;
580#ifdef HAVE_UNICODE_SUPPORT
584 while ((textLen) && (maxNbLines > 0)) {
591#ifdef HAVE_UNICODE_SUPPORT
592 if (is_unicode && !unicode_ctx) {
593 unicode_ctx = nbgl_getUnicodeFont(fontId);
598 lastDelimiter = text;
599 lenAtLastDelimiter = textLen;
603 if (unicode ==
'\n') {
606 if (maxNbLines == 0) {
609 lastDelimiter = NULL;
614 else if (unicode ==
'\f') {
619 else if (unicode ==
'\b') {
622#ifdef HAVE_UNICODE_SUPPORT
629#ifdef HAVE_UNICODE_SUPPORT
637 char_width = getCharWidth(font, unicode, is_unicode);
638 if (char_width == 0) {
642 if ((width + char_width) > maxWidth) {
643 if ((wrapping ==
true) && (lastDelimiter != NULL)) {
644 text = lastDelimiter;
645 lastDelimiter = NULL;
646 textLen = lenAtLastDelimiter;
649 textLen += text - previousText;
658 *len = text - origText;
659 return (maxNbLines == 0);
693 cur_char = text[textLen];
695 if (cur_char ==
'\n') {
701 if ((cur_char < font->first_char) || (cur_char > font->
last_char)) {
706 char_width = character->
width;
708 if ((*width + char_width) > maxWidth) {
712 *width = *width + char_width;
733#ifdef SCREEN_SIZE_NANO
734 uint16_t nbLines = 0;
736 uint16_t nbLines = 1;
738 uint16_t textLen = strlen(text);
739 const char *lastDelimiter = NULL;
740 uint32_t lenAtLastDelimiter = 0;
741 const char *prevText = NULL;
742#ifdef HAVE_UNICODE_SUPPORT
746#ifdef BUILD_SCREENSHOTS
747 hard_caesura =
false;
751 bool next_bold_state = last_bold_state;
763#ifdef HAVE_UNICODE_SUPPORT
764 if (is_unicode && !unicode_ctx) {
765 unicode_ctx = nbgl_getUnicodeFont(fontId);
771 lastDelimiter = prevText;
772 lenAtLastDelimiter = textLen;
775 if (unicode ==
'\f') {
776#ifdef BUILD_SCREENSHOTS
784 else if (unicode ==
'\n') {
786#if defined(BUILD_SCREENSHOTS) && defined(SCREEN_SIZE_NANO)
787 if (!(nbLines % 4)) {
794 lastDelimiter = NULL;
798 else if (unicode ==
'\b') {
801#ifdef HAVE_UNICODE_SUPPORT
805#ifdef BUILD_SCREENSHOTS
806 next_bold_state =
true;
811#ifdef HAVE_UNICODE_SUPPORT
815#ifdef BUILD_SCREENSHOTS
816 next_bold_state =
false;
822 char_width = getCharWidth(font, unicode, is_unicode);
823 if (char_width == 0) {
826#ifdef BUILD_SCREENSHOTS
828 last_bold_state = next_bold_state;
832 if ((width + char_width) > maxWidth) {
833 if ((wrapping ==
true) && (lastDelimiter != NULL)) {
834 text = lastDelimiter + 1;
835 lastDelimiter = NULL;
836 textLen = lenAtLastDelimiter;
840#ifdef BUILD_SCREENSHOTS
847#if defined(BUILD_SCREENSHOTS) && defined(SCREEN_SIZE_NANO)
848 if (!(nbLines % 4)) {
859#ifdef SCREEN_SIZE_NANO
864#ifdef BUILD_SCREENSHOTS
865 last_nb_lines = nbLines;
882 uint8_t nbLinesPerPage,
887 uint16_t nbLines = 0;
889 uint16_t textLen = strlen(text);
890 const char *lastDelimiter = NULL;
891 uint32_t lenAtLastDelimiter = 0;
892 const char *prevText = NULL;
893#ifdef HAVE_UNICODE_SUPPORT
897#ifdef BUILD_SCREENSHOTS
898 last_nb_lines = nbLines;
899 last_nb_pages = nbPages;
901 bool next_bold_state = last_bold_state;
912#ifdef HAVE_UNICODE_SUPPORT
913 if (is_unicode && !unicode_ctx) {
914 unicode_ctx = nbgl_getUnicodeFont(fontId);
920 lastDelimiter = prevText;
921 lenAtLastDelimiter = textLen;
924 if (unicode ==
'\f') {
926#ifdef BUILD_SCREENSHOTS
927#ifdef SCREEN_SIZE_NANO
931#ifdef SCREEN_SIZE_NANO
934 if (last_nb_lines < nbLines) {
935 last_nb_lines = nbLines;
943 else if (unicode ==
'\n') {
945#ifdef BUILD_SCREENSHOTS
946 if (last_nb_lines < nbLines) {
947 last_nb_lines = nbLines;
950 if (nbLines == nbLinesPerPage && textLen) {
956 lastDelimiter = NULL;
960 else if (unicode ==
'\b') {
963#ifdef HAVE_UNICODE_SUPPORT
967#ifdef BUILD_SCREENSHOTS
968 next_bold_state =
true;
973#ifdef HAVE_UNICODE_SUPPORT
977#ifdef BUILD_SCREENSHOTS
978 next_bold_state =
false;
984 char_width = getCharWidth(font, unicode, is_unicode);
985 if (char_width == 0) {
989#ifdef BUILD_SCREENSHOTS
991 last_bold_state = next_bold_state;
995 if ((width + char_width) > maxWidth) {
996 if (lastDelimiter != NULL) {
997 text = lastDelimiter + 1;
998 lastDelimiter = NULL;
999 textLen = lenAtLastDelimiter;
1006#ifdef BUILD_SCREENSHOTS
1007 if (last_nb_lines < nbLines) {
1008 last_nb_lines = nbLines;
1011 if (nbLines == nbLinesPerPage) {
1017 width += char_width;
1020#ifdef BUILD_SCREENSHOTS
1021#ifdef SCREEN_SIZE_NANO
1026 if (last_nb_lines < nbLines) {
1027 last_nb_lines = nbLines;
1029 last_nb_pages = nbPages;
1068 uint8_t currentNbLines = 1;
1069 char *lastDelimiter = NULL;
1070 uint32_t lenAtLastDelimiter = 0;
1071 char *prevText[4] = {0};
1072 uint16_t prevWidth[2] = {0};
1074#ifdef HAVE_UNICODE_SUPPORT
1085 prevText[3] = prevText[2];
1086 prevText[2] = prevText[1];
1087 prevText[1] = prevText[0];
1091 if (unicode ==
'\n') {
1094 lastDelimiter = NULL;
1097#ifdef HAVE_UNICODE_SUPPORT
1098 if (is_unicode && !unicode_ctx) {
1099 unicode_ctx = nbgl_getUnicodeFont(fontId);
1102 char_width = getCharWidth(font, unicode, is_unicode);
1103 if (char_width == 0) {
1109 lastDelimiter = prevText[0];
1110 lenAtLastDelimiter = textLen + 1;
1113 if ((width + char_width) > maxWidth) {
1116 if (currentNbLines < nbLines) {
1119 if (lastDelimiter != NULL) {
1120 *lastDelimiter++ =
'\n';
1121 text = lastDelimiter;
1122 lastDelimiter = NULL;
1123 textLen = lenAtLastDelimiter - 1;
1126 textLen += text - prevText[0];
1137 for (i = 0; i < 2; i++) {
1138 if ((prevText[i + 1] != NULL)
1139 && ((prevWidth[i] + (3 * getCharWidth(font,
'.',
false))) <= maxWidth)) {
1144 if (prevText[i + 1] != NULL) {
1145 memcpy(prevText[i + 1],
"...", 4);
1151 prevWidth[1] = prevWidth[0];
1152 prevWidth[0] = width;
1153 width += char_width;
1173 const char *origText,
1177 uint16_t reducedTextLen)
1180 uint16_t textLen = strlen(origText);
1182 uint8_t currentNbLines = 1;
1183 uint32_t i = 0, j = 0;
1186 if ((nbLines & 0x1) == 0) {
1190 while ((i < textLen) && (j < reducedTextLen)) {
1194 curChar = origText[i];
1196 char_width = getCharWidth(font, curChar,
false);
1197 if (char_width == 0) {
1198 reducedText[j] = curChar;
1205 if ((width + char_width) > maxWidth) {
1211 else if ((currentNbLines == ((nbLines / 2) + 1)) && ((width + char_width) > halfWidth)) {
1212 uint32_t halfFullWidth = (nbLines / 2) * maxWidth + halfWidth;
1213 uint32_t countDown = textLen;
1215 reducedText[j - 1] =
'.';
1216 reducedText[j] =
'.';
1217 reducedText[j + 1] =
'.';
1220 while (width < halfFullWidth) {
1222 curChar = origText[countDown];
1223 char_width = getCharWidth(font, curChar,
false);
1224 width += char_width;
1226 memcpy(&reducedText[j + 2], &origText[countDown + 1], textLen - countDown + 1);
1230 reducedText[j] = curChar;
1234 width += char_width;
1236 reducedText[j] =
'\0';
1239#ifdef HAVE_UNICODE_SUPPORT
1249 if ((unicodeCtx.
font != NULL) && (unicodeCtx.
font->
font_id == fontId)) {
1252#if defined(HAVE_LANGUAGE_PACK)
1254 const uint8_t *ptr = (
const uint8_t *) language_pack;
1258 unicodeCtx.
bitmap = (
const uint8_t *) (ptr + language_pack->bitmaps_offset);
1260 for (uint32_t i = 0; i < language_pack->nb_fonts; i++) {
1261 if (font->
font_id == fontId) {
1263 unicodeCtx.
font = font;
1270 unicodeCtx.
characters += language_pack->nb_characters;
1289#if defined(HAVE_LANGUAGE_PACK)
1292 uint32_t n = language_pack->nb_characters;
1293 if (characters == NULL) {
1298 for (
unsigned i = 0; i < n - 1; i++, characters++) {
1302 = (characters + 1)->bitmap_offset - characters->
bitmap_offset;
1326uint32_t nbgl_getUnicodeFontCharacterByteCount(
void)
1328#ifdef HAVE_LANGUAGE_PACK
1335#ifdef HAVE_LANGUAGE_PACK
1346 unicodeCtx.
font = NULL;
#define LOG_FATAL(__logger,...)
Middle Level API of the new BOLOS Graphical Library.
void nbgl_textWrapOnNbLines(nbgl_font_id_e fontId, char *text, uint16_t maxWidth, uint8_t nbLines)
Modifies the given text to wrap it on the given max width (in pixels), in the given nbLines If possib...
void nbgl_getTextMaxLenAndWidth(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t *len, uint16_t *width, bool wrapping)
compute the max width of the first line of the given text fitting in maxWidth
uint16_t nbgl_getTextNbLines(const char *text)
return the number of lines in the given text, according to the found ' 's
uint8_t nbgl_getTextNbPagesInWidth(nbgl_font_id_e fontId, const char *text, uint8_t nbLinesPerPage, uint16_t maxWidth)
compute the number of pages of nbLinesPerPage lines per page of the given text fitting in the given m...
uint16_t nbgl_getSingleLineTextWidth(nbgl_font_id_e fontId, const char *text)
return the max width in pixels of the given text until the first or \0 is encountered
uint8_t nbgl_getCharWidth(nbgl_font_id_e fontId, const char *text)
return the width in pixels of the given UTF-8 character
bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t maxNbLines, uint16_t *len, bool wrapping)
compute the len of the given text (in bytes) fitting in the given maximum nb lines,...
bool nbgl_getTextMaxLenAndWidthFromEnd(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t *len, uint16_t *width)
compute the len and width of the given text fitting in the maxWidth, starting from end of text
uint8_t nbgl_getFontHeight(nbgl_font_id_e fontId)
return the height in pixels of the font with the given font ID
void nbgl_textReduceOnNbLines(nbgl_font_id_e fontId, const char *origText, uint16_t maxWidth, uint8_t nbLines, char *reducedText, uint16_t reducedTextLen)
Create a reduced version of given ASCII text to wrap it on the given max width (in pixels),...
uint32_t nbgl_popUnicodeChar(const uint8_t **text, uint16_t *textLen, bool *is_unicode)
Get the coming unicode value on the given UTF-8 string. If the value is a simple ASCII character,...
uint16_t nbgl_getTextWidth(nbgl_font_id_e fontId, const char *text)
return the max width in pixels of the given text (can be multiline)
uint16_t nbgl_getTextHeightInWidth(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, bool wrapping)
return the height of the given multiline text, with the given font.
#define BAGL_FONT_ID_MASK
uint16_t nbgl_getTextLength(const char *text)
return the number of bytes of the given text, excluding final ' ' or '\0'
uint16_t nbgl_getTextNbLinesInWidth(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, bool wrapping)
compute the number of lines of the given text fitting in the given maxWidth
uint16_t nbgl_getTextHeight(nbgl_font_id_e fontId, const char *text)
return the height of the given multiline text, with the given font.
uint8_t nbgl_getFontLineHeight(nbgl_font_id_e fontId)
return the height in pixels of the line of font with the given font ID
uint16_t nbgl_getSingleLineTextWidthInLen(nbgl_font_id_e fontId, const char *text, uint16_t maxLen)
return the max width in pixels of the given text until the first or \0 is encountered,...
__attribute__((section("._nbgl_fonts_"))) const
return the non-unicode font corresponding to the given font ID
@ BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
@ BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp
const nbgl_font_t * nbgl_getFont(nbgl_font_id_e fontId)
fonts nicknames to be used for various wallet size targets (non-Nano)
uint32_t width
width of character in pixels
structure defining an ASCII font
uint8_t char_kerning
kerning for the font
uint8_t first_char
ASCII code of the first character in bitmap and in characters fields.
const nbgl_font_character_t *const characters
array containing definitions of all characters
uint8_t height
height of all characters in pixels
uint8_t line_height
height of a line for all characters in pixels
uint8_t last_char
ASCII code of the last character in bitmap and in characters fields.
structure defining a unicode character (except the bitmap)
uint32_t char_unicode
plane value from 0 to 16 then 16-bit code.
uint32_t width
width of character in pixels
uint32_t bitmap_offset
offset of this character in chars buffer
structure defining a unicode font
uint16_t bitmap_len
Size in bytes of all characters bitmaps.
uint8_t font_id
ID of the font, from nbgl_font_id_e.
const nbgl_font_unicode_character_t * characters
const nbgl_font_unicode_t * font
uint32_t unicode_character_byte_count