1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-23 14:58:09 +00:00

refactor(core): change fonts organization

This commit is contained in:
tychovrahe 2022-08-18 15:12:02 +02:00 committed by TychoVrahe
parent b9647d1296
commit 223d1b20fb
36 changed files with 492 additions and 282 deletions

View File

@ -50,7 +50,8 @@ CPPPATH_MOD += [
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/display.c',
'embed/extmod/modtrezorui/font_bitmap.c',
'embed/extmod/modtrezorui/fonts/fonts.c',
'embed/extmod/modtrezorui/fonts/font_bitmap.c',
]
SOURCE_STMHAL = [

View File

@ -1,6 +1,7 @@
# pylint: disable=E0602
import os
import tools
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
@ -21,6 +22,17 @@ CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL='Font_PixelOperator_Regular_8'
FONT_MEDIUM=None
FONT_BOLD=None
FONT_MONO='Font_PixelOperatorMono_Regular_8'
if TREZOR_MODEL in ('T', ):
FONT_NORMAL='Font_Roboto_Regular_20'
FONT_MEDIUM=None
FONT_BOLD=None
FONT_MONO='Font_RobotoMono_Regular_20'
# modtrezorcrypto
CCFLAGS_MOD += '-Wno-sequence-point '
CPPPATH_MOD += [
@ -51,18 +63,11 @@ SOURCE_MOD += [
CPPPATH_MOD += [
'vendor/micropython/lib/uzlib',
]
CPPDEFINES_MOD += [
'TREZOR_FONT_NORMAL_ENABLE',
'TREZOR_FONT_MONO_ENABLE',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/display.c',
'embed/extmod/modtrezorui/font_bitmap.c',
'embed/extmod/modtrezorui/font_roboto_regular_20.c',
'embed/extmod/modtrezorui/font_robotomono_regular_20.c',
'embed/extmod/modtrezorui/font_pixeloperator_bold_8.c',
'embed/extmod/modtrezorui/font_pixeloperator_regular_8.c',
'embed/extmod/modtrezorui/font_pixeloperatormono_regular_8.c',
'embed/extmod/modtrezorui/fonts/fonts.c',
'embed/extmod/modtrezorui/fonts/font_bitmap.c',
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
@ -131,6 +136,13 @@ if TREZOR_MODEL in ('T',):
SOURCE_TREZORHAL.append('embed/trezorhal/touch.c')
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MEDIUM', FONT_MEDIUM, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')))
env.Replace(

View File

@ -1,6 +1,7 @@
# pylint: disable=E0602
import os
import tools
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
@ -21,6 +22,17 @@ CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL='Font_PixelOperator_Regular_8'
FONT_MEDIUM=None
FONT_BOLD=None
FONT_MONO='Font_PixelOperatorMono_Regular_8'
if TREZOR_MODEL in ('T', ):
FONT_NORMAL='Font_Roboto_Regular_20'
FONT_MEDIUM=None
FONT_BOLD=None
FONT_MONO='Font_RobotoMono_Regular_20'
# modtrezorcrypto
CCFLAGS_MOD += '-Wno-sequence-point '
CPPPATH_MOD += [
@ -51,15 +63,10 @@ SOURCE_MOD += [
CPPPATH_MOD += [
'vendor/micropython/lib/uzlib',
]
CPPDEFINES_MOD += [
'TREZOR_FONT_NORMAL_ENABLE',
'TREZOR_FONT_MONO_ENABLE',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/display.c',
'embed/extmod/modtrezorui/font_bitmap.c',
'embed/extmod/modtrezorui/font_roboto_regular_20.c',
'embed/extmod/modtrezorui/font_robotomono_regular_20.c',
'embed/extmod/modtrezorui/fonts/fonts.c',
'embed/extmod/modtrezorui/fonts/font_bitmap.c',
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
@ -121,6 +128,12 @@ SOURCE_TREZORHAL = [
'embed/trezorhal/vectortable.s',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MEDIUM', FONT_MEDIUM, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')))
env.Replace(

View File

@ -2,6 +2,7 @@
# fmt: off
import os
import tools
BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
EVERYTHING = BITCOIN_ONLY != '1'
@ -22,6 +23,23 @@ SOURCE_MOD = []
PYOPT = ARGUMENTS.get('PYOPT', '1')
FROZEN = True
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL='Font_PixelOperator_Regular_8'
FONT_MEDIUM='Font_PixelOperator_Regular_8'
FONT_BOLD='Font_PixelOperator_Bold_8'
FONT_MONO='Font_PixelOperatorMono_Regular_8'
if TREZOR_MODEL in ('T', ):
if UI2:
FONT_NORMAL='Font_TTHoves_Regular_18'
FONT_MEDIUM='Font_TTHoves_Medium_20'
FONT_BOLD='Font_TTHoves_Bold_16'
FONT_MONO='Font_RobotoMono_Regular_20'
else:
FONT_NORMAL='Font_Roboto_Regular_20'
FONT_MEDIUM=None
FONT_BOLD='Font_Roboto_Bold_20'
FONT_MONO='Font_RobotoMono_Regular_20'
# modtrezorconfig
CPPPATH_MOD += [
'embed/extmod/modtrezorconfig',
@ -158,20 +176,10 @@ if TREZOR_MODEL in ('T',):
CPPPATH_MOD += [
'vendor/micropython/lib/uzlib',
]
CPPDEFINES_MOD += [
'TREZOR_FONT_BOLD_ENABLE',
'TREZOR_FONT_NORMAL_ENABLE',
'TREZOR_FONT_MONO_ENABLE',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/display.c',
'embed/extmod/modtrezorui/font_bitmap.c',
'embed/extmod/modtrezorui/font_roboto_bold_20.c',
'embed/extmod/modtrezorui/font_roboto_regular_20.c',
'embed/extmod/modtrezorui/font_robotomono_regular_20.c',
'embed/extmod/modtrezorui/font_pixeloperator_bold_8.c',
'embed/extmod/modtrezorui/font_pixeloperator_regular_8.c',
'embed/extmod/modtrezorui/font_pixeloperatormono_regular_8.c',
'embed/extmod/modtrezorui/fonts/fonts.c',
'embed/extmod/modtrezorui/fonts/font_bitmap.c',
'embed/extmod/modtrezorui/modtrezorui.c',
'embed/extmod/modtrezorui/qr-code-generator/qrcodegen.c',
'vendor/micropython/lib/uzlib/adler32.c',
@ -180,14 +188,8 @@ SOURCE_MOD += [
]
if UI2:
CPPDEFINES_MOD += [
'TREZOR_FONT_MEDIUM_ENABLE',
'TREZOR_UI2',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/font_tthoves_bold_16.c',
'embed/extmod/modtrezorui/font_tthoves_medium_20.c',
'embed/extmod/modtrezorui/font_tthoves_regular_18.c',
]
# modtrezorutils
SOURCE_MOD += [
@ -415,6 +417,12 @@ if FEATURE_FLAGS["SYSTEM_VIEW"]:
CPPDEFINES_MOD += ['SYSTEM_VIEW']
CCFLAGS_MOD += '-DSYSTEM_VIEW '
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MEDIUM', FONT_MEDIUM, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_MICROPYTHON_SPEED
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s -DPYOPT=%s -DBITCOIN_ONLY=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0'), PYOPT, BITCOIN_ONLY))

View File

@ -1,6 +1,7 @@
# pylint: disable=E0602
import os
import tools
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
@ -9,6 +10,17 @@ CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL=None
FONT_MEDIUM=None
FONT_BOLD='Font_PixelOperator_Bold_8'
FONT_MONO=None
if TREZOR_MODEL in ('T', ):
FONT_NORMAL=None
FONT_MEDIUM=None
FONT_BOLD='Font_Roboto_Bold_20'
FONT_MONO=None
# modtrezorcrypto
CPPPATH_MOD += [
'vendor/trezor-crypto',
@ -25,14 +37,11 @@ SOURCE_MOD += [
CPPPATH_MOD += [
'vendor/micropython/lib/uzlib',
]
CPPDEFINES_MOD += [
'TREZOR_FONT_BOLD_ENABLE',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/display.c',
'embed/extmod/modtrezorui/font_bitmap.c',
'embed/extmod/modtrezorui/font_roboto_bold_20.c',
'embed/extmod/modtrezorui/font_pixeloperator_bold_8.c',
'embed/extmod/modtrezorui/fonts/fonts.c',
'embed/extmod/modtrezorui/fonts/font_bitmap.c',
'embed/extmod/modtrezorui/qr-code-generator/qrcodegen.c',
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
@ -88,6 +97,12 @@ SOURCE_TREZORHAL = [
'embed/trezorhal/vectortable.s',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MEDIUM', FONT_MEDIUM, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')))
env.Replace(

View File

@ -1,6 +1,7 @@
# pylint: disable=E0602
import os
import tools
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
@ -9,6 +10,17 @@ CPPPATH_MOD = []
CPPDEFINES_MOD = []
SOURCE_MOD = []
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL=None
FONT_MEDIUM=None
FONT_BOLD='Font_PixelOperator_Bold_8'
FONT_MONO=None
if TREZOR_MODEL in ('T', ):
FONT_NORMAL=None
FONT_MEDIUM=None
FONT_BOLD='Font_Roboto_Bold_20'
FONT_MONO=None
# modtrezorcrypto
CPPPATH_MOD += [
'vendor/trezor-crypto',
@ -21,13 +33,10 @@ SOURCE_MOD += [
CPPPATH_MOD += [
'vendor/micropython/lib/uzlib',
]
CPPDEFINES_MOD += [
'TREZOR_FONT_BOLD_ENABLE',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/display.c',
'embed/extmod/modtrezorui/fonts/fonts.c',
'embed/extmod/modtrezorui/font_bitmap.c',
'embed/extmod/modtrezorui/font_roboto_bold_20.c',
'vendor/micropython/lib/uzlib/adler32.c',
'vendor/micropython/lib/uzlib/crc32.c',
'vendor/micropython/lib/uzlib/tinflate.c',
@ -81,6 +90,12 @@ SOURCE_TREZORHAL = [
'embed/trezorhal/vectortable.s',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MEDIUM', FONT_MEDIUM, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')))
env.Replace(

View File

@ -2,6 +2,7 @@
# fmt: off
import os
import tools
BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
EVERYTHING = BITCOIN_ONLY != '1'
@ -23,6 +24,23 @@ PYOPT = ARGUMENTS.get('PYOPT', '1')
FROZEN = ARGUMENTS.get('TREZOR_EMULATOR_FROZEN', 0)
RASPI = os.getenv('TREZOR_EMULATOR_RASPI') == '1'
if TREZOR_MODEL in ('1', 'R'):
FONT_NORMAL='Font_PixelOperator_Regular_8'
FONT_MEDIUM='Font_PixelOperator_Regular_8'
FONT_BOLD='Font_PixelOperator_Bold_8'
FONT_MONO='Font_PixelOperatorMono_Regular_8'
if TREZOR_MODEL in ('T', ):
if UI2:
FONT_NORMAL='Font_TTHoves_Regular_18'
FONT_MEDIUM='Font_TTHoves_Medium_20'
FONT_BOLD='Font_TTHoves_Bold_16'
FONT_MONO='Font_RobotoMono_Regular_20'
else:
FONT_NORMAL='Font_Roboto_Regular_20'
FONT_MEDIUM=None
FONT_BOLD='Font_Roboto_Bold_20'
FONT_MONO='Font_RobotoMono_Regular_20'
# modtrezorconfig
CPPPATH_MOD += [
'embed/extmod/modtrezorconfig',
@ -154,20 +172,10 @@ if TREZOR_MODEL in ('T',):
CPPPATH_MOD += [
'vendor/micropython/lib/uzlib',
]
CPPDEFINES_MOD += [
'TREZOR_FONT_BOLD_ENABLE',
'TREZOR_FONT_NORMAL_ENABLE',
'TREZOR_FONT_MONO_ENABLE',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/display.c',
'embed/extmod/modtrezorui/font_bitmap.c',
'embed/extmod/modtrezorui/font_roboto_bold_20.c',
'embed/extmod/modtrezorui/font_roboto_regular_20.c',
'embed/extmod/modtrezorui/font_robotomono_regular_20.c',
'embed/extmod/modtrezorui/font_pixeloperator_bold_8.c',
'embed/extmod/modtrezorui/font_pixeloperator_regular_8.c',
'embed/extmod/modtrezorui/font_pixeloperatormono_regular_8.c',
'embed/extmod/modtrezorui/fonts/fonts.c',
'embed/extmod/modtrezorui/fonts/font_bitmap.c',
'embed/extmod/modtrezorui/modtrezorui.c',
'embed/extmod/modtrezorui/qr-code-generator/qrcodegen.c',
'vendor/micropython/lib/uzlib/adler32.c',
@ -176,14 +184,8 @@ SOURCE_MOD += [
]
if UI2:
CPPDEFINES_MOD += [
'TREZOR_FONT_MEDIUM_ENABLE',
'TREZOR_UI2',
]
SOURCE_MOD += [
'embed/extmod/modtrezorui/font_tthoves_bold_16.c',
'embed/extmod/modtrezorui/font_tthoves_medium_20.c',
'embed/extmod/modtrezorui/font_tthoves_regular_18.c',
]
if FROZEN:
CPPDEFINES_MOD += ['TREZOR_EMULATOR_FROZEN']
if RASPI:
@ -356,6 +358,13 @@ if TREZOR_MODEL in ('T',):
'embed/unix/sdcard.c',
]
# fonts
tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MEDIUM', FONT_MEDIUM, CPPDEFINES_MOD, SOURCE_MOD)
tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD)
SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_UNIX
if PYOPT == '0' or not FROZEN:

View File

@ -26,81 +26,7 @@
#include "common.h"
#include "display.h"
#include "font_bitmap.h"
#if defined TREZOR_MODEL_T
// TT new rust UI
#if TREZOR_UI2
#ifdef TREZOR_FONT_NORMAL_ENABLE
#include "font_tthoves_regular_18.h"
#define FONT_NORMAL_DATA Font_TTHoves_Regular_18
#define FONT_NORMAL_HEIGHT 18
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
#include "font_tthoves_medium_20.h"
#define FONT_MEDIUM_DATA Font_TTHoves_Medium_20
#define FONT_MEDIUM_HEIGHT 20
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
#include "font_tthoves_bold_16.h"
#define FONT_BOLD_DATA Font_TTHoves_Bold_16
#define FONT_BOLD_HEIGHT 16
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
#include "font_robotomono_regular_20.h"
#define FONT_MONO_DATA Font_RobotoMono_Regular_20
#define FONT_MONO_HEIGHT 20
#endif
// TT old python UI
#else
#ifdef TREZOR_FONT_NORMAL_ENABLE
#include "font_roboto_regular_20.h"
#define FONT_NORMAL_DATA Font_Roboto_Regular_20
#define FONT_NORMAL_HEIGHT 20
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
#include "font_roboto_bold_20.h"
#define FONT_BOLD_DATA Font_Roboto_Bold_20
#define FONT_BOLD_HEIGHT 20
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
#include "font_robotomono_regular_20.h"
#define FONT_MONO_DATA Font_RobotoMono_Regular_20
#define FONT_MONO_HEIGHT 20
#endif
#endif
#elif defined TREZOR_MODEL_1 || defined TREZOR_MODEL_R
#ifdef TREZOR_FONT_NORMAL_ENABLE
#include "font_pixeloperator_regular_8.h"
#define FONT_NORMAL_DATA Font_PixelOperator_Regular_8
#define FONT_NORMAL_HEIGHT 8
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
#include "font_pixeloperator_regular_8.h"
#define FONT_MEDIUM_DATA Font_PixelOperator_Regular_8
#define FONT_MEDIUM_HEIGHT 8
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
#include "font_pixeloperator_bold_8.h"
#define FONT_BOLD_DATA Font_PixelOperator_Bold_8
#define FONT_BOLD_HEIGHT 8
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
#include "font_pixeloperatormono_regular_8.h"
#define FONT_MONO_DATA Font_PixelOperatorMono_Regular_8
#define FONT_MONO_HEIGHT 8
#endif
#else
#error Unknown Trezor model
#endif
#include "fonts/fonts.h"
#include <stdarg.h>
#include <string.h>
@ -634,91 +560,6 @@ void display_printf(const char *fmt, ...) {
#endif // TREZOR_PRINT_DISABLE
static uint8_t convert_char(const uint8_t c) {
static char last_was_utf8 = 0;
// non-printable ASCII character
if (c < ' ') {
last_was_utf8 = 0;
return 0x7F;
}
// regular ASCII character
if (c < 0x80) {
last_was_utf8 = 0;
return c;
}
// UTF-8 handling: https://en.wikipedia.org/wiki/UTF-8#Encoding
// bytes 11xxxxxx are first bytes of UTF-8 characters
if (c >= 0xC0) {
last_was_utf8 = 1;
return 0x7F;
}
if (last_was_utf8) {
// bytes 10xxxxxx can be successive UTF-8 characters ...
return 0; // skip glyph
} else {
// ... or they are just non-printable ASCII characters
return 0x7F;
}
return 0;
}
const uint8_t *display_get_glyph(int font, uint8_t c) {
c = convert_char(c);
if (!c) return 0;
// 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_MEDIUM_ENABLE
case FONT_MEDIUM:
return FONT_MEDIUM_DATA[c - ' '];
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return FONT_BOLD_DATA[c - ' '];
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return FONT_MONO_DATA[c - ' '];
#endif
}
return 0;
}
// non-printable character
#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_MEDIUM_ENABLE
case FONT_MEDIUM:
return NONPRINTABLE_GLYPH(FONT_MEDIUM_DATA);
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return NONPRINTABLE_GLYPH(FONT_BOLD_DATA);
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return NONPRINTABLE_GLYPH(FONT_MONO_DATA);
#endif
}
return 0;
}
static void display_text_render(int x, int y, const char *text, int textlen,
int font, uint16_t fgcolor, uint16_t bgcolor) {
@ -732,7 +573,7 @@ static void display_text_render(int x, int y, const char *text, int textlen,
// render glyphs
for (int i = 0; i < textlen; i++) {
const uint8_t *g = display_get_glyph(font, (uint8_t)text[i]);
const uint8_t *g = font_get_glyph(font, (uint8_t)text[i]);
if (!g) continue;
const uint8_t w = g[0]; // width
const uint8_t h = g[1]; // height
@ -801,7 +642,7 @@ int display_text_width(const char *text, int textlen, int font) {
textlen = strlen(text);
}
for (int i = 0; i < textlen; i++) {
const uint8_t *g = display_get_glyph(font, (uint8_t)text[i]);
const uint8_t *g = font_get_glyph(font, (uint8_t)text[i]);
if (!g) continue;
const uint8_t adv = g[2]; // advance
width += adv;
@ -833,7 +674,7 @@ int display_text_split(const char *text, int textlen, int font,
if (text[i] == ' ') {
lastspace = i;
}
const uint8_t *g = display_get_glyph(font, (uint8_t)text[i]);
const uint8_t *g = font_get_glyph(font, (uint8_t)text[i]);
if (!g) continue;
const uint8_t adv = g[2]; // advance
width += adv;
@ -848,28 +689,6 @@ int display_text_split(const char *text, int textlen, int font,
return textlen;
}
int display_text_height(int font) {
switch (font) {
#ifdef TREZOR_FONT_NORMAL_ENABLE
case FONT_NORMAL:
return FONT_NORMAL_HEIGHT;
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
case FONT_MEDIUM:
return FONT_MEDIUM_HEIGHT;
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return FONT_BOLD_HEIGHT;
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return FONT_MONO_HEIGHT;
#endif
}
return 0;
}
#define QR_MAX_VERSION 9
void display_qrcode(int x, int y, const char *data, uint8_t scale) {

View File

@ -24,6 +24,7 @@
#include <stddef.h>
#include <stdint.h>
#include "fonts/fonts.h"
#if defined TREZOR_MODEL_T
// ILI9341V, GC9307 and ST7789V drivers support 240px x 320px display resolution
@ -69,19 +70,6 @@
#define COLOR_WHITE 0xFFFF
#define COLOR_BLACK 0x0000
#ifdef TREZOR_FONT_NORMAL_ENABLE
#define FONT_NORMAL (-1)
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
#define FONT_MEDIUM (-5)
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
#define FONT_BOLD (-2)
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
#define FONT_MONO (-3)
#endif
// provided by port
void display_init(void);
@ -126,7 +114,6 @@ void display_text_right(int x, int y, const char *text, int textlen, int font,
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);
int display_text_height(int font);
void display_qrcode(int x, int y, const char *data, uint8_t scale);
@ -144,8 +131,6 @@ void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void display_pixeldata(uint16_t c);
void display_pixeldata_dirty();
const uint8_t *display_get_glyph(int font, uint8_t c);
#if !(defined EMULATOR) && (defined TREZOR_MODEL_T)
extern volatile uint8_t *const DISPLAY_CMD_ADDRESS;
extern volatile uint8_t *const DISPLAY_DATA_ADDRESS;

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 1
#error Wrong TREZOR_FONT_BPP (expected 1)
#endif
#define Font_PixelOperator_Bold_8_HEIGHT 8
#define Font_PixelOperator_Bold_8_MAX_HEIGHT 8
#define Font_PixelOperator_Bold_8_BASELINE 1
extern const uint8_t* const Font_PixelOperator_Bold_8[126 + 1 - 32];
extern const uint8_t Font_PixelOperator_Bold_8_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 1
#error Wrong TREZOR_FONT_BPP (expected 1)
#endif
#define Font_PixelOperator_Regular_8_HEIGHT 8
#define Font_PixelOperator_Regular_8_MAX_HEIGHT 8
#define Font_PixelOperator_Regular_8_BASELINE 1
extern const uint8_t* const Font_PixelOperator_Regular_8[126 + 1 - 32];
extern const uint8_t Font_PixelOperator_Regular_8_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 1
#error Wrong TREZOR_FONT_BPP (expected 1)
#endif
#define Font_PixelOperatorMono_Regular_8_HEIGHT 8
#define Font_PixelOperatorMono_Regular_8_MAX_HEIGHT 8
#define Font_PixelOperatorMono_Regular_8_BASELINE 1
extern const uint8_t* const Font_PixelOperatorMono_Regular_8[126 + 1 - 32];
extern const uint8_t Font_PixelOperatorMono_Regular_8_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 4
#error Wrong TREZOR_FONT_BPP (expected 4)
#endif
#define Font_Roboto_Bold_20_HEIGHT 20
#define Font_Roboto_Bold_20_MAX_HEIGHT 22
#define Font_Roboto_Bold_20_BASELINE 5
extern const uint8_t* const Font_Roboto_Bold_20[126 + 1 - 32];
extern const uint8_t Font_Roboto_Bold_20_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 4
#error Wrong TREZOR_FONT_BPP (expected 4)
#endif
#define Font_Roboto_Regular_20_HEIGHT 20
#define Font_Roboto_Regular_20_MAX_HEIGHT 22
#define Font_Roboto_Regular_20_BASELINE 5
extern const uint8_t* const Font_Roboto_Regular_20[126 + 1 - 32];
extern const uint8_t Font_Roboto_Regular_20_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 4
#error Wrong TREZOR_FONT_BPP (expected 4)
#endif
#define Font_RobotoMono_Regular_20_HEIGHT 20
#define Font_RobotoMono_Regular_20_MAX_HEIGHT 22
#define Font_RobotoMono_Regular_20_BASELINE 5
extern const uint8_t* const Font_RobotoMono_Regular_20[126 + 1 - 32];
extern const uint8_t Font_RobotoMono_Regular_20_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 4
#error Wrong TREZOR_FONT_BPP (expected 4)
#endif
#define Font_TTHoves_Bold_16_HEIGHT 16
#define Font_TTHoves_Bold_16_MAX_HEIGHT 17
#define Font_TTHoves_Bold_16_BASELINE 4
extern const uint8_t* const Font_TTHoves_Bold_16[126 + 1 - 32];
extern const uint8_t Font_TTHoves_Bold_16_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 4
#error Wrong TREZOR_FONT_BPP (expected 4)
#endif
#define Font_TTHoves_Medium_20_HEIGHT 20
#define Font_TTHoves_Medium_20_MAX_HEIGHT 20
#define Font_TTHoves_Medium_20_BASELINE 4
extern const uint8_t* const Font_TTHoves_Medium_20[126 + 1 - 32];
extern const uint8_t Font_TTHoves_Medium_20_glyph_nonprintable[];

View File

@ -3,5 +3,8 @@
#if TREZOR_FONT_BPP != 4
#error Wrong TREZOR_FONT_BPP (expected 4)
#endif
#define Font_TTHoves_Regular_18_HEIGHT 18
#define Font_TTHoves_Regular_18_MAX_HEIGHT 19
#define Font_TTHoves_Regular_18_BASELINE 4
extern const uint8_t* const Font_TTHoves_Regular_18[126 + 1 - 32];
extern const uint8_t Font_TTHoves_Regular_18_glyph_nonprintable[];

View File

@ -0,0 +1,170 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fonts.h"
static uint8_t convert_char(const uint8_t c) {
static char last_was_utf8 = 0;
// non-printable ASCII character
if (c < ' ') {
last_was_utf8 = 0;
return 0x7F;
}
// regular ASCII character
if (c < 0x80) {
last_was_utf8 = 0;
return c;
}
// UTF-8 handling: https://en.wikipedia.org/wiki/UTF-8#Encoding
// bytes 11xxxxxx are first bytes of UTF-8 characters
if (c >= 0xC0) {
last_was_utf8 = 1;
return 0x7F;
}
if (last_was_utf8) {
// bytes 10xxxxxx can be successive UTF-8 characters ...
return 0; // skip glyph
} else {
// ... or they are just non-printable ASCII characters
return 0x7F;
}
}
int font_height(int font) {
switch (font) {
#ifdef TREZOR_FONT_NORMAL_ENABLE
case FONT_NORMAL:
return FONT_NORMAL_HEIGHT;
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
case FONT_MEDIUM:
return FONT_MEDIUM_HEIGHT;
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return FONT_BOLD_HEIGHT;
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return FONT_MONO_HEIGHT;
#endif
}
return 0;
}
int font_max_height(int font) {
switch (font) {
#ifdef TREZOR_FONT_NORMAL_ENABLE
case FONT_NORMAL:
return FONT_NORMAL_MAX_HEIGHT;
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
case FONT_MEDIUM:
return FONT_MEDIUM_MAX_HEIGHT;
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return FONT_BOLD_MAX_HEIGHT;
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return FONT_MONO_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_MEDIUM_ENABLE
case FONT_MEDIUM:
return FONT_MEDIUM_BASELINE;
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return FONT_BOLD_BASELINE;
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return FONT_MONO_BASELINE;
#endif
}
return 0;
}
const uint8_t *font_get_glyph(int font, uint8_t c) {
c = convert_char(c);
if (!c) return 0;
// 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_MEDIUM_ENABLE
case FONT_MEDIUM:
return FONT_MEDIUM_DATA[c - ' '];
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return FONT_BOLD_DATA[c - ' '];
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return FONT_MONO_DATA[c - ' '];
#endif
}
return 0;
}
// non-printable character
#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_MEDIUM_ENABLE
case FONT_MEDIUM:
return NONPRINTABLE_GLYPH(FONT_MEDIUM_DATA);
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
case FONT_BOLD:
return NONPRINTABLE_GLYPH(FONT_BOLD_DATA);
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
case FONT_MONO:
return NONPRINTABLE_GLYPH(FONT_MONO_DATA);
#endif
}
return 0;
}

View File

@ -0,0 +1,108 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FONTS_H
#define _FONTS_H
#include "fonts/font_bitmap.h"
#if defined TREZOR_MODEL_T
#define TREZOR_FONT_BPP 4
#elif defined TREZOR_MODEL_1
#define TREZOR_FONT_BPP 1
#elif defined TREZOR_MODEL_R
#define TREZOR_FONT_BPP 1
#else
#error Unknown Trezor model
#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_ENABLE
#define FONT_NORMAL_HEIGHT FONT_DEFINE(TREZOR_FONT_NORMAL_ENABLE, _HEIGHT)
#define FONT_NORMAL_MAX_HEIGHT \
FONT_DEFINE(TREZOR_FONT_NORMAL_ENABLE, _MAX_HEIGHT)
#define FONT_NORMAL_BASELINE FONT_DEFINE(TREZOR_FONT_NORMAL_ENABLE, _BASELINE)
#endif
#ifdef TREZOR_FONT_MEDIUM_ENABLE
#include TREZOR_FONT_MEDIUM_INCLUDE
#define FONT_MEDIUM (-5)
#define FONT_MEDIUM_DATA TREZOR_FONT_MEDIUM_ENABLE
#define FONT_MEDIUM_HEIGHT FONT_DEFINE(TREZOR_FONT_MEDIUM_ENABLE, _HEIGHT)
#define FONT_MEDIUM_MAX_HEIGHT \
FONT_DEFINE(TREZOR_FONT_MEDIUM_ENABLE, _MAX_HEIGHT)
#define FONT_MEDIUM_BASELINE FONT_DEFINE(TREZOR_FONT_MEDIUM_ENABLE, _BASELINE)
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
#include TREZOR_FONT_MONO_INCLUDE
#define FONT_MONO (-3)
#define FONT_MONO_DATA TREZOR_FONT_MONO_ENABLE
#define FONT_MONO_HEIGHT FONT_DEFINE(TREZOR_FONT_MONO_ENABLE, _HEIGHT)
#define FONT_MONO_MAX_HEIGHT FONT_DEFINE(TREZOR_FONT_MONO_ENABLE, _MAX_HEIGHT)
#define FONT_MONO_BASELINE FONT_DEFINE(TREZOR_FONT_MONO_ENABLE, _BASELINE)
#endif
#ifdef TREZOR_FONT_BOLD_ENABLE
#include TREZOR_FONT_BOLD_INCLUDE
#define FONT_BOLD (-2)
#define FONT_BOLD_DATA TREZOR_FONT_BOLD_ENABLE
#define FONT_BOLD_HEIGHT FONT_DEFINE(TREZOR_FONT_BOLD_ENABLE, _HEIGHT)
#define FONT_BOLD_MAX_HEIGHT FONT_DEFINE(TREZOR_FONT_BOLD_ENABLE, _MAX_HEIGHT)
#define FONT_BOLD_BASELINE FONT_DEFINE(TREZOR_FONT_BOLD_ENABLE, _BASELINE)
#endif
#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_MEDIUM_ENABLE
#define FONT_MAX_HEIGHT_4 MAX_FONT_H(FONT_MEDIUM_MAX_HEIGHT, FONT_MAX_HEIGHT_3)
#else
#define FONT_MAX_HEIGHT_4 FONT_MAX_HEIGHT_3
#endif
#ifdef TREZOR_FONT_MONO_ENABLE
#define FONT_MAX_HEIGHT MAX_FONT_H(FONT_MONO_MAX_HEIGHT, FONT_MAX_HEIGHT_4)
#else
#define FONT_MAX_HEIGHT FONT_MAX_HEIGHT_4
#endif
int font_height(int font);
int font_max_height(int font);
int font_baseline(int font);
const uint8_t *font_get_glyph(int font, uint8_t c);
#endif //_FONTS_H

View File

@ -259,7 +259,6 @@ fn generate_trezorhal_bindings() {
.allowlist_function("display_backlight")
.allowlist_function("display_text")
.allowlist_function("display_text_width")
.allowlist_function("display_text_height")
.allowlist_function("display_bar")
.allowlist_function("display_bar_radius")
.allowlist_function("display_icon")
@ -269,9 +268,11 @@ fn generate_trezorhal_bindings() {
.allowlist_function("display_pixeldata")
.allowlist_function("display_pixeldata_dirty")
.allowlist_function("display_set_window")
.allowlist_function("display_get_glyph")
.allowlist_var("DISPLAY_CMD_ADDRESS")
.allowlist_var("DISPLAY_DATA_ADDRESS")
// fonts
.allowlist_function("font_height")
.allowlist_function("font_get_glyph")
// uzlib
.allowlist_function("uzlib_uncompress_init")
.allowlist_function("uzlib_uncompress")

View File

@ -41,12 +41,12 @@ pub fn char_width(ch: char, font: i32) -> i16 {
}
pub fn get_char_glyph(ch: u8, font: i32) -> *const u8 {
unsafe { ffi::display_get_glyph(font, ch) }
unsafe { ffi::font_get_glyph(font, ch) }
}
pub fn text_height(font: i32) -> i16 {
unsafe {
ffi::display_text_height(font)
ffi::font_height(font)
.try_into()
.unwrap_or(i16::MAX)
}

View File

@ -1,5 +1,6 @@
#include "common.h"
#include "display.h"
#include "fonts/fonts.h"
#include "rgb_led.h"
#include "secbool.h"
#include "storage.h"

11
core/site_scons/tools.py Normal file
View File

@ -0,0 +1,11 @@
def add_font(font_name, font, defines, sources):
if font is not None:
defines += [
'TREZOR_FONT_' + font_name + '_ENABLE=' + font,
'TREZOR_FONT_' + font_name + '_INCLUDE=\\"' + font.lower() + '.h\\"',
]
sourcefile = 'embed/extmod/modtrezorui/fonts/' + font.lower() + '.c'
if sourcefile not in sources:
sources.append(sourcefile)

View File

@ -57,19 +57,9 @@ def process_face(name, style, size, bpp=4, shave_bearingX=0, ext="ttf"):
face = freetype.Face("fonts/%s-%s.%s" % (name, style, ext))
face.set_pixel_sizes(0, size)
fontname = "%s_%s_%d" % (name.lower(), style.lower(), size)
with open("font_%s.h" % fontname, "wt") as f:
f.write("#include <stdint.h>\n\n")
f.write("#if TREZOR_FONT_BPP != %d\n" % bpp)
f.write("#error Wrong TREZOR_FONT_BPP (expected %d)\n" % bpp)
f.write("#endif\n")
f.write(
"extern const uint8_t* const Font_%s_%s_%d[%d + 1 - %d];\n"
% (name, style, size, MAX_GLYPH, MIN_GLYPH)
)
f.write(
"extern const uint8_t Font_%s_%s_%d_glyph_nonprintable[];\n"
% (name, style, size)
)
font_ymin = 0
font_ymax = 0
with open("font_%s.c" % fontname, "wt") as f:
f.write("#include <stdint.h>\n\n")
f.write("// clang-format off\n\n")
@ -94,6 +84,7 @@ def process_face(name, style, size, bpp=4, shave_bearingX=0, ext="ttf"):
rows = bitmap.rows
advance = metrics.horiAdvance // 64
bearingX = metrics.horiBearingX // 64
# discard space on the left side
if shave_bearingX > 0:
advance -= min(advance, bearingX, shave_bearingX)
@ -148,6 +139,12 @@ def process_face(name, style, size, bpp=4, shave_bearingX=0, ext="ttf"):
)
nonprintable += " };\n"
yMin = bearingY - rows
yMax = yMin + rows
font_ymin = min(font_ymin, yMin)
font_ymax = max(font_ymax, yMax)
f.write(nonprintable)
f.write(
@ -158,6 +155,24 @@ def process_face(name, style, size, bpp=4, shave_bearingX=0, ext="ttf"):
f.write(" Font_%s_%s_%d_glyph_%d,\n" % (name, style, size, i))
f.write("};\n")
with open("font_%s.h" % fontname, "wt") as f:
f.write("#include <stdint.h>\n\n")
f.write("#if TREZOR_FONT_BPP != %d\n" % bpp)
f.write("#error Wrong TREZOR_FONT_BPP (expected %d)\n" % bpp)
f.write("#endif\n")
f.write("#define Font_%s_%s_%d_HEIGHT %d\n" % (name, style, size, size))
f.write("#define Font_%s_%s_%d_MAX_HEIGHT %d\n" % (name, style, size, font_ymax - font_ymin))
f.write("#define Font_%s_%s_%d_BASELINE %d\n" % (name, style, size, -font_ymin))
f.write(
"extern const uint8_t* const Font_%s_%s_%d[%d + 1 - %d];\n"
% (name, style, size, MAX_GLYPH, MIN_GLYPH)
)
f.write(
"extern const uint8_t Font_%s_%s_%d_glyph_nonprintable[];\n"
% (name, style, size)
)
process_face("Roboto", "Regular", 20)
process_face("Roboto", "Bold", 20)