10#include "app_config.h"
14#include "os_helpers.h"
22#define PIC_FONT(x) ((nbgl_font_t const *) PIC(x))
23#define BAGL_FONT_ID_MASK 0x0FFF
25#define IS_WORD_DELIM(c) (c == ' ' || c == '\n' || c == '\b' || c == '\f' || c == '-' || c == '_')
40static const LANGUAGE_PACK *language_pack;
42#if SMALL_FONT_HEIGHT == 24
43#include "nbgl_font_inter_regular_24.inc"
44#include "nbgl_font_inter_semibold_24.inc"
45#include "nbgl_font_inter_medium_32.inc"
46#include "nbgl_font_inter_regular_24_1bpp.inc"
47#include "nbgl_font_inter_semibold_24_1bpp.inc"
48#include "nbgl_font_inter_medium_32_1bpp.inc"
49#elif SMALL_FONT_HEIGHT == 28
50#include "nbgl_font_inter_regular_28.inc"
51#include "nbgl_font_inter_semibold_28.inc"
52#include "nbgl_font_inter_medium_36.inc"
53#include "nbgl_font_inter_regular_28_1bpp.inc"
54#include "nbgl_font_inter_semibold_28_1bpp.inc"
55#include "nbgl_font_inter_medium_36_1bpp.inc"
56#elif SMALL_FONT_HEIGHT == 18
57#include "nbgl_font_nanotext_medium_18_1bpp.inc"
58#include "nbgl_font_nanotext_bold_18_1bpp.inc"
59#include "nbgl_font_nanodisplay_semibold_24_1bpp.inc"
60#elif SMALL_FONT_HEIGHT == 11
61#include "nbgl_font_open_sans_extrabold_11.inc"
62#include "nbgl_font_open_sans_regular_11.inc"
63#include "nbgl_font_open_sans_light_16.inc"
68#include "nbgl_font_rom_struct.inc"
71__attribute__((section(
"._nbgl_fonts_"))) const
unsigned int C_nbgl_fonts_count
72 = sizeof(C_nbgl_fonts) / sizeof(C_nbgl_fonts[0]);
74#if (defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP))
77#ifdef BUILD_SCREENSHOTS
79uint16_t last_nb_lines = 0;
80uint16_t last_nb_pages = 0;
81bool last_bold_state =
false;
84bool hard_caesura =
false;
103 unsigned int i = C_nbgl_fonts_count;
108 if (
PIC_FONT(C_nbgl_fonts[i])->font_id == fontId) {
132 const uint8_t *txt = *text;
133 uint8_t cur_char = *txt++;
147 if ((cur_char >= 0xF0) && (*textLen >= 4)) {
148 unicode = (cur_char & 0x07) << 18;
149 unicode |= (*txt++ & 0x3F) << 12;
150 unicode |= (*txt++ & 0x3F) << 6;
151 unicode |= (*txt++ & 0x3F);
155 else if ((cur_char >= 0xE0) && (*textLen >= 3)) {
156 unicode = (cur_char & 0x0F) << 12;
157 unicode |= (*txt++ & 0x3F) << 6;
158 unicode |= (*txt++ & 0x3F);
163 else if ((cur_char >= 0xC2) && (*textLen >= 2)) {
164 unicode = (cur_char & 0x1F) << 6;
165 unicode |= (*txt++ & 0x3F);
171 *textLen = *textLen - (txt - *text);
184static uint8_t getCharWidth(
const nbgl_font_t *font, uint32_t unicode,
bool is_unicode)
189 if (!unicodeCharacter) {
193#ifdef SCREEN_SIZE_WALLET
202 if ((unicode < font->first_char) || (unicode > font->
last_char)) {
226#ifdef BUILD_SCREENSHOTS
227 uint16_t nb_lines = 0;
229 uint16_t line_width = 0;
230 uint16_t max_width = 0;
238 textLen =
MIN(strlen(text), maxLen);
240#ifdef BUILD_SCREENSHOTS
242 bool next_bold_state = last_bold_state;
256 if (is_unicode && !unicode_ctx) {
259 if (unicode ==
'\n') {
260 if (breakOnLineEnd) {
268 else if (unicode ==
'\b') {
273#ifdef BUILD_SCREENSHOTS
274 next_bold_state =
true;
281#ifdef BUILD_SCREENSHOTS
282 next_bold_state =
false;
287 char_width = getCharWidth(font, unicode, is_unicode);
288#ifdef BUILD_SCREENSHOTS
289 if (char_width != 0) {
291 last_bold_state = next_bold_state;
294 line_width += char_width;
296 if (line_width > max_width) {
297 max_width = line_width;
300#ifdef BUILD_SCREENSHOTS
301 if (line_width != 0) {
304 last_nb_lines = nb_lines;
319 return getTextWidth(fontId, text,
true, 0xFFFF);
333 return getTextWidth(fontId, text,
true, maxLen);
345 return getTextWidth(fontId, text,
false, 0xFFFF);
360 uint16_t textLen = 4;
367 return getCharWidth(font, unicode, is_unicode);
416 uint16_t nbLines = 1;
448 const char *origText = text;
453 else if (*text ==
'\n') {
458 return text - origText;
483 uint32_t lenAtLastDelimiter = 0, widthAtlastDelimiter = 0;
492 uint16_t curTextLen = textLen;
495 if (is_unicode && !unicode_ctx) {
499 if (!unicode || (unicode ==
'\f') || (unicode ==
'\n')) {
500 *len += curTextLen - textLen;
504 else if (unicode ==
'\b') {
515 *len += curTextLen - textLen;
519 char_width = getCharWidth(font, unicode, is_unicode);
520 if (char_width == 0) {
521 *len += curTextLen - textLen;
527 lenAtLastDelimiter = *len;
528 widthAtlastDelimiter = *width;
530 if ((*width + char_width) > maxWidth) {
531 if ((wrapping ==
true) && (widthAtlastDelimiter > 0)) {
532 *len = lenAtLastDelimiter + 1;
533 *width = widthAtlastDelimiter;
537 *len += curTextLen - textLen;
538 *width = *width + char_width;
566 const char *lastDelimiter = NULL;
567 uint32_t lenAtLastDelimiter = 0;
568 const char *origText = text;
569 const char *previousText;
576 textLen = strlen(text);
578 while ((textLen) && (maxNbLines > 0)) {
581 bool is_unicode =
false;
585 if (is_unicode && !unicode_ctx) {
590 lastDelimiter = text;
591 lenAtLastDelimiter = textLen;
595 if (unicode ==
'\n') {
598 if (maxNbLines == 0) {
601 lastDelimiter = NULL;
606 else if (unicode ==
'\f') {
611 else if (unicode ==
'\b') {
625 char_width = getCharWidth(font, unicode, is_unicode);
626 if (char_width == 0) {
630 if ((width + char_width) > maxWidth) {
631 if ((wrapping ==
true) && (lastDelimiter != NULL)) {
632 text = lastDelimiter;
633 lastDelimiter = NULL;
634 textLen = lenAtLastDelimiter;
637 textLen += text - previousText;
646 *len = text - origText;
647 return (maxNbLines == 0);
681 cur_char = text[textLen];
683 if (cur_char ==
'\n') {
689 if ((cur_char < font->first_char) || (cur_char > font->
last_char)) {
694 char_width = character->
width;
696 if ((*width + char_width) > maxWidth) {
700 *width = *width + char_width;
721#ifdef SCREEN_SIZE_NANO
722 uint16_t nbLines = 0;
724 uint16_t nbLines = 1;
727 const char *lastDelimiter = NULL;
728 uint32_t lenAtLastDelimiter = 0;
729 const char *prevText = NULL;
732#ifdef BUILD_SCREENSHOTS
733 hard_caesura =
false;
737 bool next_bold_state = last_bold_state;
743 textLen = strlen(text);
748 bool is_unicode =
false;
753 if (is_unicode && !unicode_ctx) {
759 lastDelimiter = prevText;
760 lenAtLastDelimiter = textLen;
763 if (unicode ==
'\f') {
764#ifdef BUILD_SCREENSHOTS
772 else if (unicode ==
'\n') {
774#if defined(BUILD_SCREENSHOTS) && defined(SCREEN_SIZE_NANO)
775 if (!(nbLines % 4)) {
782 lastDelimiter = NULL;
786 else if (unicode ==
'\b') {
791#ifdef BUILD_SCREENSHOTS
792 next_bold_state =
true;
799#ifdef BUILD_SCREENSHOTS
800 next_bold_state =
false;
806 char_width = getCharWidth(font, unicode, is_unicode);
807 if (char_width == 0) {
810#ifdef BUILD_SCREENSHOTS
812 last_bold_state = next_bold_state;
816 if ((width + char_width) > maxWidth) {
817 if ((wrapping ==
true) && (lastDelimiter != NULL)) {
818 text = lastDelimiter + 1;
819 lastDelimiter = NULL;
820 textLen = lenAtLastDelimiter;
824#ifdef BUILD_SCREENSHOTS
831#if defined(BUILD_SCREENSHOTS) && defined(SCREEN_SIZE_NANO)
832 if (!(nbLines % 4)) {
843#ifdef SCREEN_SIZE_NANO
848#ifdef BUILD_SCREENSHOTS
849 last_nb_lines = nbLines;
866 uint8_t nbLinesPerPage,
871 uint16_t nbLines = 0;
874 const char *lastDelimiter = NULL;
875 uint32_t lenAtLastDelimiter = 0;
876 const char *prevText = NULL;
879#ifdef BUILD_SCREENSHOTS
880 last_nb_lines = nbLines;
881 last_nb_pages = nbPages;
883 bool next_bold_state = last_bold_state;
889 textLen = strlen(text);
895 bool is_unicode =
false;
900 if (is_unicode && !unicode_ctx) {
906 lastDelimiter = prevText;
907 lenAtLastDelimiter = textLen;
910 if (unicode ==
'\f') {
912#ifdef BUILD_SCREENSHOTS
913#ifdef SCREEN_SIZE_NANO
917#ifdef SCREEN_SIZE_NANO
920 if (last_nb_lines < nbLines) {
921 last_nb_lines = nbLines;
929 else if (unicode ==
'\n') {
931#ifdef BUILD_SCREENSHOTS
932 if (last_nb_lines < nbLines) {
933 last_nb_lines = nbLines;
936 if (nbLines == nbLinesPerPage && textLen) {
942 lastDelimiter = NULL;
946 else if (unicode ==
'\b') {
951#ifdef BUILD_SCREENSHOTS
952 next_bold_state =
true;
959#ifdef BUILD_SCREENSHOTS
960 next_bold_state =
false;
966 char_width = getCharWidth(font, unicode, is_unicode);
967 if (char_width == 0) {
971#ifdef BUILD_SCREENSHOTS
973 last_bold_state = next_bold_state;
977 if ((width + char_width) > maxWidth) {
978 if (lastDelimiter != NULL) {
979 text = lastDelimiter + 1;
980 lastDelimiter = NULL;
981 textLen = lenAtLastDelimiter;
988#ifdef BUILD_SCREENSHOTS
989 if (last_nb_lines < nbLines) {
990 last_nb_lines = nbLines;
993 if (nbLines == nbLinesPerPage) {
1002#ifdef BUILD_SCREENSHOTS
1003#ifdef SCREEN_SIZE_NANO
1008 if (last_nb_lines < nbLines) {
1009 last_nb_lines = nbLines;
1011 last_nb_pages = nbPages;
1051 uint8_t currentNbLines = 1;
1052 char *lastDelimiter = NULL;
1053 uint32_t lenAtLastDelimiter = 0;
1054 char *prevText[4] = {0};
1055 uint16_t prevWidth[2] = {0};
1065 prevText[3] = prevText[2];
1066 prevText[2] = prevText[1];
1067 prevText[1] = prevText[0];
1071 if (unicode ==
'\n') {
1074 lastDelimiter = NULL;
1077 if (is_unicode && !unicode_ctx) {
1080 char_width = getCharWidth(font, unicode, is_unicode);
1081 if (char_width == 0) {
1087 lastDelimiter = prevText[0];
1088 lenAtLastDelimiter = textLen + 1;
1091 if ((width + char_width) > maxWidth) {
1094 if (currentNbLines < nbLines) {
1097 if (lastDelimiter != NULL) {
1098 *lastDelimiter++ =
'\n';
1099 text = lastDelimiter;
1100 lastDelimiter = NULL;
1101 textLen = lenAtLastDelimiter - 1;
1104 textLen += text - prevText[0];
1115 for (i = 0; i < 2; i++) {
1116 if ((prevText[i + 1] != NULL)
1117 && ((prevWidth[i] + (3 * getCharWidth(font,
'.',
false))) <= maxWidth)) {
1122 if (prevText[i + 1] != NULL) {
1123 memcpy(prevText[i + 1],
"...", 4);
1129 prevWidth[1] = prevWidth[0];
1130 prevWidth[0] = width;
1131 width += char_width;
1152 const char *origText,
1156 uint16_t reducedTextLen)
1159 uint16_t textLen = strlen(origText);
1161 uint8_t currentNbLines = 1;
1162 uint32_t i = 0, j = 0;
1165 if ((nbLines & 0x1) == 0) {
1169 while ((i < textLen) && (j < reducedTextLen)) {
1173 curChar = origText[i];
1175 char_width = getCharWidth(font, curChar,
false);
1176 if (char_width == 0) {
1177 reducedText[j] = curChar;
1184 if ((width + char_width) > maxWidth) {
1190 else if ((currentNbLines == ((nbLines / 2) + 1)) && ((width + char_width) > halfWidth)) {
1191 uint32_t halfFullWidth = (nbLines / 2) * maxWidth + halfWidth;
1192 uint32_t countDown = textLen;
1194 reducedText[j - 1] =
'.';
1195 reducedText[j] =
'.';
1196 reducedText[j + 1] =
'.';
1199 while (width < halfFullWidth) {
1201 curChar = origText[countDown];
1202 char_width = getCharWidth(font, curChar,
false);
1203 width += char_width;
1205 memcpy(&reducedText[j + 2], &origText[countDown + 1], textLen - countDown + 1);
1209 reducedText[j] = curChar;
1213 width += char_width;
1215 reducedText[j] =
'\0';
1228 if (os_sched_current_task() != TASK_BOLOS_UX) {
1231 if ((unicodeCtx.
font != NULL) && (unicodeCtx.
font->
font_id == fontId)) {
1235 const uint8_t *ptr = (
const uint8_t *) language_pack;
1239 unicodeCtx.
bitmap = (
const uint8_t *) (ptr + language_pack->bitmaps_offset);
1241 for (uint32_t i = 0; i < language_pack->nb_fonts; i++) {
1242 if (font->
font_id == fontId) {
1244 unicodeCtx.
font = font;
1251 unicodeCtx.
characters += language_pack->nb_characters;
1270 if (os_sched_current_task() != TASK_BOLOS_UX) {
1275 uint32_t n = language_pack->nb_characters;
1276 if (characters == NULL) {
1281 for (
unsigned i = 0; i < n - 1; i++, characters++) {
1285 = (characters + 1)->bitmap_offset - characters->
bitmap_offset;
1307 if (os_sched_current_task() != TASK_BOLOS_UX) {
1323 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...
const nbgl_font_unicode_character_t * nbgl_getUnicodeFontCharacter(uint32_t unicode)
Get the unicode character object matching the given unicode (a unicode character is encoded on max of...
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
void nbgl_refreshUnicodeFont(const LANGUAGE_PACK *lp)
Function to be called when a change on the current language pack is notified by the OS,...
nbgl_unicode_ctx_t * nbgl_getUnicodeFont(nbgl_font_id_e fontId)
Get the font entry for the given font id (sparse font array support)
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,...
uint32_t nbgl_getUnicodeFontCharacterByteCount(void)
Get the bitmap byte count of the latest used unicode character. (the one returned by nbgl_getUnicodeF...
__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 over_previous
flag set to 1 when displayed over previous char
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 height
height of all characters in pixels
uint8_t font_id
ID of the font, from nbgl_font_id_e.
uint8_t line_height
height of a line for all characters in pixels
const nbgl_font_unicode_character_t * characters
const nbgl_font_unicode_t * font
uint32_t unicode_character_byte_count