From df035349557f38647dab14a1055d19dea673e01e Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Fri, 17 Jul 2020 16:56:37 +0200 Subject: [PATCH] core: print inverted question mark for nonprintable characters --- core/CHANGELOG.md | 1 + core/embed/extmod/modtrezorui/display.c | 39 ++++++++-- .../extmod/modtrezorui/font_roboto_bold_20.c | 2 + .../extmod/modtrezorui/font_roboto_bold_20.h | 1 + .../modtrezorui/font_roboto_regular_20.c | 2 + .../modtrezorui/font_roboto_regular_20.h | 1 + .../modtrezorui/font_robotomono_bold_20.c | 2 + .../modtrezorui/font_robotomono_bold_20.h | 1 + .../modtrezorui/font_robotomono_regular_20.c | 2 + .../modtrezorui/font_robotomono_regular_20.h | 1 + core/tools/codegen/gen_font.py | 72 +++++++++++-------- 11 files changed, 88 insertions(+), 36 deletions(-) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index b321c8935d..3d35792ddf 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added ### Changed +- Print inverted question mark for non-printable characters. ### Deprecated diff --git a/core/embed/extmod/modtrezorui/display.c b/core/embed/extmod/modtrezorui/display.c index 9ffd3c49b0..23bd85f7b2 100644 --- a/core/embed/extmod/modtrezorui/display.c +++ b/core/embed/extmod/modtrezorui/display.c @@ -534,7 +534,7 @@ static uint8_t convert_char(const uint8_t c) { // non-printable ASCII character if (c < ' ') { last_was_utf8 = 0; - return '_'; + return 0x7F; } // regular ASCII character @@ -548,7 +548,7 @@ static uint8_t convert_char(const uint8_t c) { // bytes 11xxxxxx are first bytes of UTF-8 characters if (c >= 0xC0) { last_was_utf8 = 1; - return '_'; + return 0x7F; } if (last_was_utf8) { @@ -556,7 +556,7 @@ static uint8_t convert_char(const uint8_t c) { return 0; // skip glyph } else { // ... or they are just non-printable ASCII characters - return '_'; + return 0x7F; } return 0; @@ -565,22 +565,47 @@ static uint8_t convert_char(const uint8_t c) { static const uint8_t *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_Roboto_Regular_20[c - ' ']; +#endif +#ifdef TREZOR_FONT_BOLD_ENABLE + case FONT_BOLD: + return Font_Roboto_Bold_20[c - ' ']; +#endif +#ifdef TREZOR_FONT_MONO_ENABLE + case FONT_MONO: + return Font_RobotoMono_Regular_20[c - ' ']; +#endif +#ifdef TREZOR_FONT_MONO_BOLD_ENABLE + case FONT_MONO_BOLD: + return Font_RobotoMono_Bold_20[c - ' ']; +#endif + } + return 0; + } + + // non-printable character switch (font) { #ifdef TREZOR_FONT_NORMAL_ENABLE case FONT_NORMAL: - return Font_Roboto_Regular_20[c - ' ']; + return Font_Roboto_Regular_20_glyph_nonprintable; #endif #ifdef TREZOR_FONT_BOLD_ENABLE case FONT_BOLD: - return Font_Roboto_Bold_20[c - ' ']; + return Font_Roboto_Bold_20_glyph_nonprintable; #endif #ifdef TREZOR_FONT_MONO_ENABLE case FONT_MONO: - return Font_RobotoMono_Regular_20[c - ' ']; + return Font_RobotoMono_Regular_20_glyph_nonprintable; #endif #ifdef TREZOR_FONT_MONO_BOLD_ENABLE case FONT_MONO_BOLD: - return Font_RobotoMono_Bold_20[c - ' ']; + return Font_RobotoMono_Bold_20_glyph_nonprintable; #endif } return 0; diff --git a/core/embed/extmod/modtrezorui/font_roboto_bold_20.c b/core/embed/extmod/modtrezorui/font_roboto_bold_20.c index 657468891d..04b4c4cb39 100644 --- a/core/embed/extmod/modtrezorui/font_roboto_bold_20.c +++ b/core/embed/extmod/modtrezorui/font_roboto_bold_20.c @@ -103,6 +103,8 @@ /* } */ static const uint8_t Font_Roboto_Bold_20_glyph_125[] = { 7, 21, 7, 0, 17, 0, 0, 0, 2, 231, 0, 0, 95, 252, 0, 0, 127, 245, 0, 1, 255, 160, 0, 15, 252, 0, 0, 255, 208, 0, 15, 253, 0, 0, 239, 240, 0, 7, 255, 162, 0, 8, 255, 128, 1, 223, 248, 0, 175, 246, 0, 15, 254, 0, 0, 255, 208, 0, 15, 253, 0, 0, 255, 192, 0, 63, 249, 0, 11, 255, 48, 6, 255, 112, 0, 25, 32, 0, 0 }; /* ~ */ static const uint8_t Font_Roboto_Bold_20_glyph_126[] = { 11, 5, 13, 1, 9, 0, 52, 16, 0, 0, 0, 191, 255, 128, 2, 254, 127, 255, 255, 198, 207, 205, 248, 23, 255, 255, 244, 170, 16, 3, 207, 230, 0 }; +const uint8_t Font_Roboto_Bold_20_glyph_nonprintable[] = { 9, 15, 11, 1, 15, 253, 98, 1, 93, 252, 0, 0, 0, 29, 64, 4, 164, 0, 96, 0, 239, 224, 3, 238, 239, 254, 0, 63, 255, 255, 96, 7, 255, 255, 128, 2, 239, 255, 176, 0, 223, 255, 243, 0, 175, 255, 255, 0, 15, 255, 255, 249, 138, 255, 255, 255, 255, 255, 255, 255, 246, 9, 255, 255, 255, 0, 63, 255, 255, 246, 9, 255, 255 }; + const uint8_t * const Font_Roboto_Bold_20[126 + 1 - 32] = { Font_Roboto_Bold_20_glyph_32, Font_Roboto_Bold_20_glyph_33, diff --git a/core/embed/extmod/modtrezorui/font_roboto_bold_20.h b/core/embed/extmod/modtrezorui/font_roboto_bold_20.h index 6f48d259a7..94a72d9c07 100644 --- a/core/embed/extmod/modtrezorui/font_roboto_bold_20.h +++ b/core/embed/extmod/modtrezorui/font_roboto_bold_20.h @@ -1,3 +1,4 @@ #include extern const uint8_t* const Font_Roboto_Bold_20[126 + 1 - 32]; +extern const uint8_t Font_Roboto_Bold_20_glyph_nonprintable[]; diff --git a/core/embed/extmod/modtrezorui/font_roboto_regular_20.c b/core/embed/extmod/modtrezorui/font_roboto_regular_20.c index 05d5a869d3..c0749ee486 100644 --- a/core/embed/extmod/modtrezorui/font_roboto_regular_20.c +++ b/core/embed/extmod/modtrezorui/font_roboto_regular_20.c @@ -103,6 +103,8 @@ /* } */ static const uint8_t Font_Roboto_Regular_20_glyph_125[] = { 7, 21, 8, 0, 16, 5, 32, 0, 0, 207, 96, 0, 0, 191, 32, 0, 3, 249, 0, 0, 15, 176, 0, 0, 252, 0, 0, 15, 208, 0, 0, 253, 0, 0, 12, 242, 0, 0, 63, 233, 0, 0, 175, 240, 0, 143, 129, 0, 14, 224, 0, 0, 253, 0, 0, 15, 208, 0, 0, 252, 0, 0, 47, 160, 0, 7, 246, 0, 5, 253, 0, 0, 201, 16, 0, 0, 0, 0, 0 }; /* ~ */ static const uint8_t Font_Roboto_Regular_20_glyph_126[] = { 11, 4, 13, 1, 8, 8, 238, 144, 0, 10, 182, 253, 158, 193, 1, 252, 223, 16, 29, 233, 223, 90, 144, 0, 9, 254, 112 }; +const uint8_t Font_Roboto_Regular_20_glyph_nonprintable[] = { 8, 15, 10, 1, 15, 252, 65, 3, 191, 176, 6, 97, 11, 32, 223, 252, 3, 86, 255, 255, 32, 255, 255, 255, 17, 255, 255, 252, 4, 255, 255, 226, 11, 255, 255, 64, 127, 255, 249, 4, 255, 255, 243, 14, 255, 255, 240, 31, 255, 255, 252, 207, 255, 255, 255, 255, 255, 255, 250, 207, 255, 255, 243, 111, 255 }; + const uint8_t * const Font_Roboto_Regular_20[126 + 1 - 32] = { Font_Roboto_Regular_20_glyph_32, Font_Roboto_Regular_20_glyph_33, diff --git a/core/embed/extmod/modtrezorui/font_roboto_regular_20.h b/core/embed/extmod/modtrezorui/font_roboto_regular_20.h index fdd40eec4e..c5bef3a3c9 100644 --- a/core/embed/extmod/modtrezorui/font_roboto_regular_20.h +++ b/core/embed/extmod/modtrezorui/font_roboto_regular_20.h @@ -1,3 +1,4 @@ #include extern const uint8_t* const Font_Roboto_Regular_20[126 + 1 - 32]; +extern const uint8_t Font_Roboto_Regular_20_glyph_nonprintable[]; diff --git a/core/embed/extmod/modtrezorui/font_robotomono_bold_20.c b/core/embed/extmod/modtrezorui/font_robotomono_bold_20.c index 6e4e85c98e..579d1d4219 100644 --- a/core/embed/extmod/modtrezorui/font_robotomono_bold_20.c +++ b/core/embed/extmod/modtrezorui/font_robotomono_bold_20.c @@ -103,6 +103,8 @@ /* } */ static const uint8_t Font_RobotoMono_Bold_20_glyph_125[] = { 7, 20, 12, 3, 16, 106, 48, 0, 10, 255, 64, 0, 11, 253, 0, 0, 79, 242, 0, 3, 255, 64, 0, 47, 244, 0, 2, 255, 64, 0, 31, 247, 0, 0, 191, 228, 0, 1, 207, 251, 0, 8, 255, 176, 9, 255, 115, 0, 255, 128, 0, 47, 245, 0, 2, 255, 64, 0, 63, 244, 0, 5, 255, 32, 0, 191, 208, 0, 175, 245, 0, 7, 213, 0, 0 }; /* ~ */ static const uint8_t Font_RobotoMono_Bold_20_glyph_126[] = { 12, 5, 12, 0, 9, 0, 19, 0, 0, 0, 0, 9, 255, 248, 0, 8, 145, 95, 255, 255, 213, 111, 240, 175, 113, 94, 255, 255, 144, 54, 0, 1, 158, 249, 0 }; +const uint8_t Font_RobotoMono_Bold_20_glyph_nonprintable[] = { 10, 15, 12, 1, 15, 255, 163, 16, 38, 239, 247, 0, 0, 0, 30, 208, 1, 155, 64, 7, 144, 9, 255, 224, 4, 255, 255, 255, 224, 5, 255, 255, 255, 112, 9, 255, 255, 249, 0, 63, 255, 255, 160, 2, 239, 255, 255, 16, 46, 255, 255, 254, 0, 159, 255, 255, 255, 119, 223, 255, 255, 255, 255, 255, 255, 255, 253, 33, 207, 255, 255, 248, 0, 111, 255, 255, 253, 33, 191, 255 }; + const uint8_t * const Font_RobotoMono_Bold_20[126 + 1 - 32] = { Font_RobotoMono_Bold_20_glyph_32, Font_RobotoMono_Bold_20_glyph_33, diff --git a/core/embed/extmod/modtrezorui/font_robotomono_bold_20.h b/core/embed/extmod/modtrezorui/font_robotomono_bold_20.h index 0ef42c6930..bd4da8bc8a 100644 --- a/core/embed/extmod/modtrezorui/font_robotomono_bold_20.h +++ b/core/embed/extmod/modtrezorui/font_robotomono_bold_20.h @@ -1,3 +1,4 @@ #include extern const uint8_t* const Font_RobotoMono_Bold_20[126 + 1 - 32]; +extern const uint8_t Font_RobotoMono_Bold_20_glyph_nonprintable[]; diff --git a/core/embed/extmod/modtrezorui/font_robotomono_regular_20.c b/core/embed/extmod/modtrezorui/font_robotomono_regular_20.c index d9b4a349a2..bf9e5d44d5 100644 --- a/core/embed/extmod/modtrezorui/font_robotomono_regular_20.c +++ b/core/embed/extmod/modtrezorui/font_robotomono_regular_20.c @@ -103,6 +103,8 @@ /* } */ static const uint8_t Font_RobotoMono_Regular_20_glyph_125[] = { 7, 20, 12, 3, 16, 68, 0, 0, 12, 251, 0, 0, 9, 246, 0, 0, 15, 192, 0, 0, 223, 0, 0, 12, 240, 0, 0, 207, 0, 0, 11, 242, 0, 0, 111, 128, 0, 0, 175, 182, 0, 3, 239, 192, 2, 253, 48, 0, 159, 64, 0, 11, 241, 0, 0, 207, 0, 0, 12, 240, 0, 0, 238, 0, 0, 95, 144, 0, 127, 226, 0, 10, 194, 0, 0 }; /* ~ */ static const uint8_t Font_RobotoMono_Regular_20_glyph_126[] = { 12, 4, 12, 0, 8, 3, 223, 197, 0, 0, 115, 30, 216, 223, 144, 1, 245, 111, 16, 9, 253, 141, 224, 54, 0, 0, 93, 252, 32 }; +const uint8_t Font_RobotoMono_Regular_20_glyph_nonprintable[] = { 10, 15, 12, 1, 15, 255, 180, 16, 42, 255, 250, 1, 102, 32, 127, 241, 30, 255, 242, 14, 247, 159, 255, 246, 12, 255, 255, 255, 244, 13, 255, 255, 255, 208, 47, 255, 255, 254, 32, 175, 255, 255, 243, 7, 255, 255, 255, 96, 127, 255, 255, 255, 17, 255, 255, 255, 255, 53, 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 255, 255, 255, 254, 1, 255, 255, 255, 254, 19, 255, 255 }; + const uint8_t * const Font_RobotoMono_Regular_20[126 + 1 - 32] = { Font_RobotoMono_Regular_20_glyph_32, Font_RobotoMono_Regular_20_glyph_33, diff --git a/core/embed/extmod/modtrezorui/font_robotomono_regular_20.h b/core/embed/extmod/modtrezorui/font_robotomono_regular_20.h index bf86bf34b7..bc4a1657a9 100644 --- a/core/embed/extmod/modtrezorui/font_robotomono_regular_20.h +++ b/core/embed/extmod/modtrezorui/font_robotomono_regular_20.h @@ -1,3 +1,4 @@ #include extern const uint8_t* const Font_RobotoMono_Regular_20[126 + 1 - 32]; +extern const uint8_t Font_RobotoMono_Regular_20_glyph_nonprintable[]; diff --git a/core/tools/codegen/gen_font.py b/core/tools/codegen/gen_font.py index 9eebbd27a0..abc7e4ab49 100755 --- a/core/tools/codegen/gen_font.py +++ b/core/tools/codegen/gen_font.py @@ -13,16 +13,36 @@ FONT_BPP = 4 # metrics explanation: https://www.freetype.org/freetype2/docs/glyphs/metrics.png -def process_face(name, style, size): +def process_bitmap_buffer(buf): + res = buf[:] + if FONT_BPP == 2: + for _ in range(4 - len(res) % 4): + res.append(0) + res = [ + ((a & 0xC0) | ((b & 0xC0) >> 2) | ((c & 0xC0) >> 4) | ((d & 0xC0) >> 6)) + for a, b, c, d in [res[i : i + 4] for i in range(0, len(res), 4)] + ] + elif FONT_BPP == 4: + if len(res) % 2 > 0: + res.append(0) + res = [ + ((a & 0xF0) | (b >> 4)) + for a, b in [res[i : i + 2] for i in range(0, len(res), 2)] + ] + return res + + +def process_face(dirprefix, name, style, size): print("Processing ... %s %s %s" % (name, style, size)) - face = freetype.Face("/usr/share/fonts/truetype/%s-%s.ttf" % (name, style)) + face = freetype.Face("%s/share/fonts/truetype/%s-%s.ttf" % (dirprefix, name, style)) 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 \n\n") f.write( "extern const uint8_t* const Font_%s_%s_%d[%d + 1 - %d];\n" - % (name, style, size, MAX_GLYPH, MIN_GLYPH) + "extern const uint8_t Font_%s_%s_%d_glyph_nonprintable[];\n" + % (name, style, size, MAX_GLYPH, MIN_GLYPH, name, style, size) ) with open("font_%s.c" % fontname, "wt") as f: f.write('#include "font_%s.h"\n\n' % fontname) @@ -77,29 +97,23 @@ def process_face(name, style, size): ) buf = list(bitmap.buffer) if len(buf) > 0: - if FONT_BPP == 2: - for _ in range(4 - len(buf) % 4): - buf.append(0) - buf = [ - ( - (a & 0xC0) - | ((b & 0xC0) >> 2) - | ((c & 0xC0) >> 4) - | ((d & 0xC0) >> 6) - ) - for a, b, c, d in [ - buf[i : i + 4] for i in range(0, len(buf), 4) - ] - ] - elif FONT_BPP == 4: - if len(buf) % 2 > 0: - buf.append(0) - buf = [ - ((a & 0xF0) | (b >> 4)) - for a, b in [buf[i : i + 2] for i in range(0, len(buf), 2)] - ] - f.write(", " + ", ".join(["%d" % x for x in buf])) + f.write( + ", " + ", ".join(["%d" % x for x in process_bitmap_buffer(buf)]) + ) f.write(" };\n") + + if i == ord("?"): + nonprintable = ( + "\nconst uint8_t Font_%s_%s_%d_glyph_nonprintable[] = { %d, %d, %d, %d, %d" + % (name, style, size, width, rows, advance, bearingX, bearingY) + ) + nonprintable += ", " + ", ".join( + ["%d" % (x ^ 0xFF) for x in process_bitmap_buffer(buf)] + ) + nonprintable += " };\n" + + f.write(nonprintable) + f.write( "\nconst uint8_t * const Font_%s_%s_%d[%d + 1 - %d] = {\n" % (name, style, size, MAX_GLYPH, MIN_GLYPH) @@ -109,7 +123,7 @@ def process_face(name, style, size): f.write("};\n") -process_face("Roboto", "Regular", 20) -process_face("Roboto", "Bold", 20) -process_face("RobotoMono", "Regular", 20) -process_face("RobotoMono", "Bold", 20) +process_face("/usr", "Roboto", "Regular", 20) +process_face("/usr", "Roboto", "Bold", 20) +process_face("/usr", "RobotoMono", "Regular", 20) +process_face("/usr", "RobotoMono", "Bold", 20)