diff --git a/core/embed/lib/fonts/fonts.c b/core/embed/lib/fonts/fonts.c index d2e6a7396..a1da435c3 100644 --- a/core/embed/lib/fonts/fonts.c +++ b/core/embed/lib/fonts/fonts.c @@ -22,124 +22,123 @@ #include #include #include +#include "fonts_types.h" #ifdef TRANSLATIONS #include "librust_fonts.h" #endif -#define UNICODE_BADCHAR 0xFFFD - -int font_height(int font) { - switch (font) { +// include selectively based on the SCons variables #ifdef TREZOR_FONT_NORMAL_ENABLE - case FONT_NORMAL: - return FONT_NORMAL_HEIGHT; +#include TREZOR_FONT_NORMAL_INCLUDE #endif #ifdef TREZOR_FONT_DEMIBOLD_ENABLE - case FONT_DEMIBOLD: - return FONT_DEMIBOLD_HEIGHT; +#include TREZOR_FONT_DEMIBOLD_INCLUDE #endif #ifdef TREZOR_FONT_BOLD_ENABLE - case FONT_BOLD: - return FONT_BOLD_HEIGHT; +#include TREZOR_FONT_BOLD_INCLUDE #endif #ifdef TREZOR_FONT_NORMAL_UPPER_ENABLE - case FONT_NORMAL_UPPER: - return FONT_NORMAL_UPPER_HEIGHT; +#include TREZOR_FONT_NORMAL_UPPER_INCLUDE #endif #ifdef TREZOR_FONT_BOLD_UPPER_ENABLE - case FONT_BOLD_UPPER: - return FONT_BOLD_UPPER_HEIGHT; +#include TREZOR_FONT_BOLD_UPPER_INCLUDE #endif #ifdef TREZOR_FONT_MONO_ENABLE - case FONT_MONO: - return FONT_MONO_HEIGHT; +#include TREZOR_FONT_MONO_INCLUDE #endif #ifdef TREZOR_FONT_BIG_ENABLE - case FONT_BIG: - return FONT_BIG_HEIGHT; +#include TREZOR_FONT_BIG_INCLUDE #endif #ifdef TREZOR_FONT_SUB_ENABLE - case FONT_SUB: - return FONT_SUB_HEIGHT; +#include TREZOR_FONT_SUB_INCLUDE #endif - } - return 0; -} -int font_max_height(int font) { - switch (font) { +#define PASTER(font_name) font_name##_info +#define FONT_INFO(font_name) PASTER(font_name) + + +static const font_info_t *get_font_info(font_id_t font_id) { + switch (font_id) { #ifdef TREZOR_FONT_NORMAL_ENABLE case FONT_NORMAL: - return FONT_NORMAL_MAX_HEIGHT; -#endif -#ifdef TREZOR_FONT_DEMIBOLD_ENABLE - case FONT_DEMIBOLD: - return FONT_DEMIBOLD_MAX_HEIGHT; + return &FONT_INFO(TREZOR_FONT_NORMAL_NAME); #endif #ifdef TREZOR_FONT_BOLD_ENABLE case FONT_BOLD: - return FONT_BOLD_MAX_HEIGHT; -#endif -#ifdef TREZOR_FONT_NORMAL_UPPER_ENABLE - case FONT_NORMAL_UPPER: - return FONT_NORMAL_UPPER_MAX_HEIGHT; + return &FONT_INFO(TREZOR_FONT_BOLD_NAME); #endif -#ifdef TREZOR_FONT_BOLD_UPPER_ENABLE - case FONT_BOLD_UPPER: - return FONT_BOLD_UPPER_MAX_HEIGHT; +#ifdef TREZOR_FONT_DEMIBOLD_ENABLE + case FONT_DEMIBOLD: + return &FONT_INFO(TREZOR_FONT_DEMIBOLD_NAME); #endif #ifdef TREZOR_FONT_MONO_ENABLE case FONT_MONO: - return FONT_MONO_MAX_HEIGHT; + return &FONT_INFO(TREZOR_FONT_MONO_NAME); #endif #ifdef TREZOR_FONT_BIG_ENABLE case FONT_BIG: - return FONT_BIG_MAX_HEIGHT; -#endif -#ifdef TREZOR_FONT_SUB_ENABLE - case FONT_SUB: - return FONT_SUB_MAX_HEIGHT; -#endif - } - return 0; -} - -int font_baseline(int font) { - switch (font) { -#ifdef TREZOR_FONT_NORMAL_ENABLE - case FONT_NORMAL: - return FONT_NORMAL_BASELINE; -#endif -#ifdef TREZOR_FONT_DEMIBOLD_ENABLE - case FONT_DEMIBOLD: - return FONT_DEMIBOLD_BASELINE; -#endif -#ifdef TREZOR_FONT_BOLD_ENABLE - case FONT_BOLD: - return FONT_BOLD_BASELINE; + return &FONT_INFO(TREZOR_FONT_BIG_NAME); #endif #ifdef TREZOR_FONT_NORMAL_UPPER_ENABLE case FONT_NORMAL_UPPER: - return FONT_NORMAL_UPPER_BASELINE; + return &FONT_INFO(TREZOR_FONT_NORMAL_UPPER_NAME); #endif #ifdef TREZOR_FONT_BOLD_UPPER_ENABLE case FONT_BOLD_UPPER: - return FONT_BOLD_UPPER_BASELINE; -#endif -#ifdef TREZOR_FONT_MONO_ENABLE - case FONT_MONO: - return FONT_MONO_BASELINE; -#endif -#ifdef TREZOR_FONT_BIG_ENABLE - case FONT_BIG: - return FONT_BIG_BASELINE; + return &FONT_INFO(TREZOR_FONT_BOLD_UPPER_NAME); #endif #ifdef TREZOR_FONT_SUB_ENABLE case FONT_SUB: - return FONT_SUB_BASELINE; + return &FONT_INFO(TREZOR_FONT_SUB_NAME); #endif + default: + return NULL; } - return 0; +} + +int font_height(int font_id) { + const font_info_t *font_info = get_font_info(font_id); + return font_info ? font_info->height : 0; +} + +int font_max_height(int font) { + const font_info_t *font_info = get_font_info(font); + return font_info ? font_info->max_height : 0; +} + +int font_baseline(int font) { + const font_info_t *font_info = get_font_info(font); + return font_info ? font_info->baseline : 0; +} + +const uint8_t *font_get_glyph(int font, uint16_t c) { +#ifdef TRANSLATIONS + // found UTF8 character + // it is not hardcoded in firmware fonts, it must be extracted from the + // embedded blob + if (c >= 0x7F) { + const uint8_t *g = get_utf8_glyph(c, font); + if (g != NULL) { + return g; + } + } +#endif + + // printable ASCII character + if (c >= ' ' && c < 0x7F) { + const font_info_t *font_info = get_font_info(font); + if (font_info == NULL) { + return NULL; + } + return font_info->glyph_data[c - ' ']; + } + + return font_nonprintable_glyph(font); +} + +const uint8_t *font_nonprintable_glyph(int font) { + const font_info_t *font_info = get_font_info(font); + return font_info ? font_info->glyph_nonprintable : NULL; } font_glyph_iter_t font_glyph_iter_init(const int font, const uint8_t *text, @@ -151,6 +150,7 @@ font_glyph_iter_t font_glyph_iter_init(const int font, const uint8_t *text, }; } +#define UNICODE_BADCHAR 0xFFFD #define IS_UTF8_CONTINUE(c) (((c) & 0b11000000) == 0b10000000) static uint16_t next_utf8_codepoint(font_glyph_iter_t *iter) { @@ -211,103 +211,6 @@ bool font_next_glyph(font_glyph_iter_t *iter, const uint8_t **out) { } } -const uint8_t *font_nonprintable_glyph(int font) { -#define PASTER(s) s##_glyph_nonprintable -#define NONPRINTABLE_GLYPH(s) PASTER(s) - - switch (font) { -#ifdef TREZOR_FONT_NORMAL_ENABLE - case FONT_NORMAL: - return NONPRINTABLE_GLYPH(FONT_NORMAL_DATA); -#endif -#ifdef TREZOR_FONT_DEMIBOLD_ENABLE - case FONT_DEMIBOLD: - return NONPRINTABLE_GLYPH(FONT_DEMIBOLD_DATA); -#endif -#ifdef TREZOR_FONT_BOLD_ENABLE - case FONT_BOLD: - return NONPRINTABLE_GLYPH(FONT_BOLD_DATA); -#endif -#ifdef TREZOR_FONT_NORMAL_UPPER_ENABLE - case FONT_NORMAL_UPPER: - return NONPRINTABLE_GLYPH(FONT_NORMAL_UPPER_DATA); -#endif -#ifdef TREZOR_FONT_BOLD_UPPER_ENABLE - case FONT_BOLD_UPPER: - return NONPRINTABLE_GLYPH(FONT_BOLD_UPPER_DATA); -#endif -#ifdef TREZOR_FONT_MONO_ENABLE - case FONT_MONO: - return NONPRINTABLE_GLYPH(FONT_MONO_DATA); -#endif -#ifdef TREZOR_FONT_BIG_ENABLE - case FONT_BIG: - return NONPRINTABLE_GLYPH(FONT_BIG_DATA); -#endif -#ifdef TREZOR_FONT_SUB_ENABLE - case FONT_SUB: - return NONPRINTABLE_GLYPH(FONT_SUB_DATA); -#endif - default: - return NULL; - } -} - -const uint8_t *font_get_glyph(int font, uint16_t c) { -#ifdef TRANSLATIONS - // found UTF8 character - // it is not hardcoded in firmware fonts, it must be extracted from the - // embedded blob - if (c >= 0x7F) { - const uint8_t *g = get_utf8_glyph(c, font); - if (g != NULL) { - return g; - } - } -#endif - - // printable ASCII character - if (c >= ' ' && c < 0x7F) { - switch (font) { -#ifdef TREZOR_FONT_NORMAL_ENABLE - case FONT_NORMAL: - return FONT_NORMAL_DATA[c - ' ']; -#endif -#ifdef TREZOR_FONT_DEMIBOLD_ENABLE - case FONT_DEMIBOLD: - return FONT_DEMIBOLD_DATA[c - ' ']; -#endif -#ifdef TREZOR_FONT_BOLD_ENABLE - case FONT_BOLD: - return FONT_BOLD_DATA[c - ' ']; -#endif -#ifdef TREZOR_FONT_NORMAL_UPPER_ENABLE - case FONT_NORMAL_UPPER: - return FONT_NORMAL_UPPER_DATA[c - ' ']; -#endif -#ifdef TREZOR_FONT_BOLD_UPPER_ENABLE - case FONT_BOLD_UPPER: - return FONT_BOLD_UPPER_DATA[c - ' ']; -#endif -#ifdef TREZOR_FONT_MONO_ENABLE - case FONT_MONO: - return FONT_MONO_DATA[c - ' ']; -#endif -#ifdef TREZOR_FONT_BIG_ENABLE - case FONT_BIG: - return FONT_BIG_DATA[c - ' ']; -#endif -#ifdef TREZOR_FONT_SUB_ENABLE - case FONT_SUB: - return FONT_SUB_DATA[c - ' ']; -#endif - } - return 0; - } - - return font_nonprintable_glyph(font); -} - // compute the width of the text (in pixels) int font_text_width(int font, const char *text, int textlen) { int width = 0; diff --git a/core/embed/lib/fonts/fonts.h b/core/embed/lib/fonts/fonts.h index 5172346d9..f8f5b14e9 100644 --- a/core/embed/lib/fonts/fonts.h +++ b/core/embed/lib/fonts/fonts.h @@ -23,6 +23,7 @@ #include #include "fonts/font_bitmap.h" +#include "fonts_types.h" #include TREZOR_BOARD #ifdef USE_RGB_COLORS @@ -31,140 +32,27 @@ #define TREZOR_FONT_BPP 1 #endif -#define COMPOSE(font_name, suffix) font_name##suffix -#define FONT_DEFINE(s, suffix) COMPOSE(s, suffix) - -#ifdef TREZOR_FONT_NORMAL_ENABLE -#define FONT_NORMAL (-1) -#include TREZOR_FONT_NORMAL_INCLUDE -#define FONT_NORMAL_DATA TREZOR_FONT_NORMAL_NAME -#define FONT_NORMAL_HEIGHT FONT_DEFINE(TREZOR_FONT_NORMAL_NAME, _HEIGHT) -#define FONT_NORMAL_MAX_HEIGHT FONT_DEFINE(TREZOR_FONT_NORMAL_NAME, _MAX_HEIGHT) -#define FONT_NORMAL_BASELINE FONT_DEFINE(TREZOR_FONT_NORMAL_NAME, _BASELINE) -#endif - -#ifdef TREZOR_FONT_BIG_ENABLE -#include TREZOR_FONT_BIG_INCLUDE -#define FONT_BIG (-4) -#define FONT_BIG_DATA TREZOR_FONT_BIG_NAME -#define FONT_BIG_HEIGHT FONT_DEFINE(TREZOR_FONT_BIG_NAME, _HEIGHT) -#define FONT_BIG_MAX_HEIGHT FONT_DEFINE(TREZOR_FONT_BIG_NAME, _MAX_HEIGHT) -#define FONT_BIG_BASELINE FONT_DEFINE(TREZOR_FONT_BIG_NAME, _BASELINE) -#endif - -#ifdef TREZOR_FONT_DEMIBOLD_ENABLE -#include TREZOR_FONT_DEMIBOLD_INCLUDE -#define FONT_DEMIBOLD (-5) -#define FONT_DEMIBOLD_DATA TREZOR_FONT_DEMIBOLD_NAME -#define FONT_DEMIBOLD_HEIGHT FONT_DEFINE(TREZOR_FONT_DEMIBOLD_NAME, _HEIGHT) -#define FONT_DEMIBOLD_MAX_HEIGHT \ - FONT_DEFINE(TREZOR_FONT_DEMIBOLD_NAME, _MAX_HEIGHT) -#define FONT_DEMIBOLD_BASELINE FONT_DEFINE(TREZOR_FONT_DEMIBOLD_NAME, _BASELINE) -#endif - -#ifdef TREZOR_FONT_SUB_ENABLE -#include TREZOR_FONT_SUB_INCLUDE -#define FONT_SUB (-8) -#define FONT_SUB_DATA TREZOR_FONT_SUB_NAME -#define FONT_SUB_HEIGHT FONT_DEFINE(TREZOR_FONT_SUB_NAME, _HEIGHT) -#define FONT_SUB_MAX_HEIGHT FONT_DEFINE(TREZOR_FONT_SUB_NAME, _MAX_HEIGHT) -#define FONT_SUB_BASELINE FONT_DEFINE(TREZOR_FONT_SUB_NAME, _BASELINE) -#endif - -#ifdef TREZOR_FONT_MONO_ENABLE -#include TREZOR_FONT_MONO_INCLUDE -#define FONT_MONO (-3) -#define FONT_MONO_DATA TREZOR_FONT_MONO_NAME -#define FONT_MONO_HEIGHT FONT_DEFINE(TREZOR_FONT_MONO_NAME, _HEIGHT) -#define FONT_MONO_MAX_HEIGHT FONT_DEFINE(TREZOR_FONT_MONO_NAME, _MAX_HEIGHT) -#define FONT_MONO_BASELINE FONT_DEFINE(TREZOR_FONT_MONO_NAME, _BASELINE) -#endif - -#ifdef TREZOR_FONT_BOLD_ENABLE -#include TREZOR_FONT_BOLD_INCLUDE -#define FONT_BOLD (-2) -#define FONT_BOLD_DATA TREZOR_FONT_BOLD_NAME -#define FONT_BOLD_HEIGHT FONT_DEFINE(TREZOR_FONT_BOLD_NAME, _HEIGHT) -#define FONT_BOLD_MAX_HEIGHT FONT_DEFINE(TREZOR_FONT_BOLD_NAME, _MAX_HEIGHT) -#define FONT_BOLD_BASELINE FONT_DEFINE(TREZOR_FONT_BOLD_NAME, _BASELINE) -#endif - -#ifdef TREZOR_FONT_NORMAL_UPPER_ENABLE -#include TREZOR_FONT_NORMAL_UPPER_INCLUDE -#define FONT_NORMAL_UPPER (-6) -#define FONT_NORMAL_UPPER_DATA TREZOR_FONT_NORMAL_UPPER_NAME -#define FONT_NORMAL_UPPER_HEIGHT \ - FONT_DEFINE(TREZOR_FONT_NORMAL_UPPER_NAME, _HEIGHT) -#define FONT_NORMAL_UPPER_MAX_HEIGHT \ - FONT_DEFINE(TREZOR_FONT_NORMAL_UPPER_NAME, _MAX_HEIGHT) -#define FONT_NORMAL_UPPER_BASELINE \ - FONT_DEFINE(TREZOR_FONT_NORMAL_UPPER_NAME, _BASELINE) -#endif - -#ifdef TREZOR_FONT_BOLD_UPPER_ENABLE -#include TREZOR_FONT_BOLD_UPPER_INCLUDE -#define FONT_BOLD_UPPER (-7) -#define FONT_BOLD_UPPER_DATA TREZOR_FONT_BOLD_UPPER_NAME -#define FONT_BOLD_UPPER_HEIGHT FONT_DEFINE(TREZOR_FONT_BOLD_UPPER_NAME, _HEIGHT) -#define FONT_BOLD_UPPER_MAX_HEIGHT \ - FONT_DEFINE(TREZOR_FONT_BOLD_UPPER_NAME, _MAX_HEIGHT) -#define FONT_BOLD_UPPER_BASELINE \ - FONT_DEFINE(TREZOR_FONT_BOLD_UPPER_NAME, _BASELINE) -#endif - +// Calculate the maximum height across all enabled fonts at compile time #define MAX_FONT_H(A, B) ((A) > (B) ? (A) : (B)) - -#define FONT_MAX_HEIGHT_1 0 -#ifdef TREZOR_FONT_NORMAL_ENABLE -#define FONT_MAX_HEIGHT_2 MAX_FONT_H(FONT_NORMAL_MAX_HEIGHT, FONT_MAX_HEIGHT_1) -#else -#define FONT_MAX_HEIGHT_2 FONT_MAX_HEIGHT_1 -#endif - -#ifdef TREZOR_FONT_BOLD_ENABLE -#define FONT_MAX_HEIGHT_3 MAX_FONT_H(FONT_BOLD_MAX_HEIGHT, FONT_MAX_HEIGHT_2) -#else -#define FONT_MAX_HEIGHT_3 FONT_MAX_HEIGHT_2 -#endif - -#ifdef TREZOR_FONT_BIG_ENABLE -#define FONT_MAX_HEIGHT_4 MAX_FONT_H(FONT_BIG_MAX_HEIGHT, FONT_MAX_HEIGHT_3) -#else -#define FONT_MAX_HEIGHT_4 FONT_MAX_HEIGHT_3 -#endif - -#ifdef TREZOR_FONT_DEMIBOLD_ENABLE -#define FONT_MAX_HEIGHT_5 \ - MAX_FONT_H(FONT_DEMIBOLD_MAX_HEIGHT, FONT_MAX_HEIGHT_4) -#else -#define FONT_MAX_HEIGHT_5 FONT_MAX_HEIGHT_4 -#endif - -#ifdef TREZOR_FONT_NORMAL_UPPER_ENABLE -#define FONT_MAX_HEIGHT_6 \ - MAX_FONT_H(FONT_NORMAL_UPPER_MAX_HEIGHT, FONT_MAX_HEIGHT_5) -#else -#define FONT_MAX_HEIGHT_6 FONT_MAX_HEIGHT_5 -#endif - -#ifdef TREZOR_FONT_BOLD_UPPER_ENABLE -#define FONT_MAX_HEIGHT_7 \ - MAX_FONT_H(FONT_BOLD_UPPER_MAX_HEIGHT, FONT_MAX_HEIGHT_6) -#else -#define FONT_MAX_HEIGHT_7 FONT_MAX_HEIGHT_6 -#endif - -#ifdef TREZOR_FONT_SUB_ENABLE -#define FONT_MAX_HEIGHT_8 MAX_FONT_H(FONT_SUB_MAX_HEIGHT, FONT_MAX_HEIGHT_7) -#else -#define FONT_MAX_HEIGHT_8 FONT_MAX_HEIGHT_7 -#endif - -#ifdef TREZOR_FONT_MONO_ENABLE -#define FONT_MAX_HEIGHT MAX_FONT_H(FONT_MONO_MAX_HEIGHT, FONT_MAX_HEIGHT_8) -#else -#define FONT_MAX_HEIGHT FONT_MAX_HEIGHT_8 -#endif +// clang-format off +#define FONT_MAX_HEIGHT \ + MAX_FONT_H( \ + MAX_FONT_H( \ + MAX_FONT_H( \ + MAX_FONT_H( \ + MAX_FONT_H( \ + MAX_FONT_H( \ + MAX_FONT_H( \ + MAX_FONT_H(0, \ + TREZOR_FONT_NORMAL_ENABLE ? FONT_NORMAL_MAX_HEIGHT : 0), \ + TREZOR_FONT_BOLD_ENABLE ? FONT_BOLD_MAX_HEIGHT : 0), \ + TREZOR_FONT_BIG_ENABLE ? FONT_BIG_MAX_HEIGHT : 0), \ + TREZOR_FONT_DEMIBOLD_ENABLE ? FONT_DEMIBOLD_MAX_HEIGHT : 0), \ + TREZOR_FONT_NORMAL_UPPER_ENABLE ? FONT_NORMAL_UPPER_MAX_HEIGHT : 0), \ + TREZOR_FONT_BOLD_UPPER_ENABLE ? FONT_BOLD_UPPER_MAX_HEIGHT : 0), \ + TREZOR_FONT_SUB_ENABLE ? FONT_SUB_MAX_HEIGHT : 0), \ + TREZOR_FONT_MONO_ENABLE ? FONT_MONO_MAX_HEIGHT : 0) +// clang-format on int font_height(int font); int font_max_height(int font); @@ -172,12 +60,6 @@ int font_baseline(int font); const uint8_t *font_get_glyph(int font, uint16_t c); const uint8_t *font_nonprintable_glyph(int font); -typedef struct { - const int font; - const uint8_t *text; - int remaining; -} font_glyph_iter_t; - font_glyph_iter_t font_glyph_iter_init(const int font, const uint8_t *text, const int len); bool font_next_glyph(font_glyph_iter_t *iter, const uint8_t **out); diff --git a/core/embed/lib/fonts/fonts_types.h b/core/embed/lib/fonts/fonts_types.h new file mode 100644 index 000000000..7b5ec3866 --- /dev/null +++ b/core/embed/lib/fonts/fonts_types.h @@ -0,0 +1,35 @@ +#ifndef _FONTS_TYPES_H +#define _FONTS_TYPES_H + +#include + +/// Font information structure containing metadata and pointers to font data +typedef struct { + const char* name; + int height; + int max_height; + int baseline; + const uint8_t* const* glyph_data; + const uint8_t* glyph_nonprintable; +} font_info_t; + +/// Font identifiers +typedef enum { + FONT_NORMAL = -1, + FONT_BOLD = -2, + FONT_MONO = -3, + FONT_BIG = -4, + FONT_DEMIBOLD = -5, + FONT_NORMAL_UPPER = -6, + FONT_BOLD_UPPER = -7, + FONT_SUB = -8, +} font_id_t; + +/// Font glyph iterator structure +typedef struct { + const int font; + const uint8_t* text; + int remaining; +} font_glyph_iter_t; + +#endif // _FONTS_TYPES_H diff --git a/core/embed/rust/src/ui/display/font.rs b/core/embed/rust/src/ui/display/font.rs index fd410a43b..96a6341f3 100644 --- a/core/embed/rust/src/ui/display/font.rs +++ b/core/embed/rust/src/ui/display/font.rs @@ -142,8 +142,8 @@ impl Glyph { } } -/// Font constants. Keep in sync with FONT_ definitions in -/// `core/embed/lib/fonts/fonts.h`. +/// Font constants. Keep in sync with `font_id_t` definition in +/// `core/embed/lib/fonts/fonts_types.h`. #[derive(Copy, Clone, PartialEq, Eq, FromPrimitive)] #[repr(u8)] #[allow(non_camel_case_types)]