From 28ea7029019cdb35744716bd23984519faeca105 Mon Sep 17 00:00:00 2001 From: "Peter D. Gray" Date: Thu, 7 Dec 2023 11:14:13 -0500 Subject: [PATCH] caps NFC/QR --- misc/q1font/font_iosevka.py | 7 ++++--- misc/q1font/render.py | 17 +++++++++-------- misc/q1font/sample.png | Bin 6757 -> 6767 bytes shared/flow.py | 18 +++++++++--------- shared/lcd_display.py | 17 ++++++++++------- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/misc/q1font/font_iosevka.py b/misc/q1font/font_iosevka.py index e299b381..e5ec4c2e 100644 --- a/misc/q1font/font_iosevka.py +++ b/misc/q1font/font_iosevka.py @@ -18,6 +18,7 @@ TEXT_PALETTES = [ # same, but w/o byte swapping, packing (useful for simulator) #TEXT_PALETTE = [0x0000, 0x0840, 0x18a0, 0x2900, 0x3940, 0x49a0, 0x5a00, 0x6a60, 0x7aa0, 0x8b00, 0x9b60, 0xabc0, 0xbc00, 0xdcc0, 0xed00, 0xfd60] COL_TEXT = const(0xfd60) # text foreground colour +COL_DARK_TEXT = const(0xa380) # "dark" pallette text foreground colour CELL_W = const(9) CELL_H = const(22) @@ -166,7 +167,7 @@ class FontIosevka: '┏': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xff\xff\xff\x00?\xff\xff\xf0\x03\xff\xff\xff\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00', '┛': b'\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x0f\xff\xff\xf3\x00\xff\xff\xff0\x0f\xff\xff\xf3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', '┗': b'\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xf3\x00\x00?\xff0\x00\x03\xff\xff\xff\x00?\xff\xff\xf0\x03\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', - '\x0e': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x04\xde`\x00\x0f\xf0\x00\x00\x00\x0c\xdc\xe0\x00\x0f\xf0\x00\x00\x00\r\xb3P\x00\x0f\xff\xae\xd2\x00.\xc2\x10~\xff\xff\xc7\xf9\x04\xff\xff\x82\xfc\x8f\xff`\xdc\x01^\xc5%\xf5\x0f\xff`\xdc\x00\x0e\xb0\x06\xf4\x0f\xff`\xdc\x00\x0e\xb0\x05\xf5\x0f\xff`\xdc\x00\x0e\xb0\x02\xfc\x8f\xff`\xdc\x00\x0e\xb0\x00~\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00', - '\x11': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\t\xfb\xdc\x00\x9f\x8f\x90\x0f\xf0?\xc7\xfc\x00\x9f\x9c\xf0\x0f\xf0_P\xdc\x00\x9f! \x0f\xf0o@\xdc\x00\x9f\x10\x00\x0f\xf0_P\xdc\x00\x9f\x10\x00\x0f\xf0?\xc8\xfc\x00\x9f\x10\x00\x0f\xf0\t\xfb\xdc\x00\x9f\x10\x00\x0f\xf0\x00\x00\xdc\x00\x00\x00\x00\x0f\xf0\x00\x00\xdc\x00\x00\x00\x00\x0f\xf0\x00\x00\xdc\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00', - '\t': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\rP\x00\x00\x02\xa0\x00\x0f\xf0\rP\x00\x00\x00\x99\x00\x0f\xf0\rb""",\x80\x0f\xf0\r\xff\xff\xff\xff\xff\xf4\x0f\xf0\r\x85UUU\\\xa0\x0f\xf0\rP\x00\x00\x00\x8a\x00\x0f\xf0\rP\x00\x00\x02\xb0\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00', + '\x0e': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf6\xf1\x8d\x01\xff\xfd\x0b\xfdO\xf6\xf6\x8d\x01\xf73_\\\xcf\xf6\xfb\x8d\x01\xf5\x00~\x01/\xf6\xed\x9d\x01\xff\xf4~\x00\x0f\xf6\xf9\xcd\x01\xf71~\x00\x0f\xf6\xf3\xfd\x01\xf5\x00~\x01/\xf6\xf0\xdd\x01\xf5\x00_\\\xcf\xf6\xf0\x8d\x01\xf5\x00\x0b\xfdO\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00', + '\x11': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\xaf\xd4\x06\xff\xd4\x00\x0f\xf0\x05\xf5\xbd\x06\xf3\xbc\x00\x0f\xf0\x07\xe0~\x06\xf0~\x00\x0f\xf0\x07\xe0~\x06\xf0\xad\x00\x0f\xf0\x07\xe0~\x06\xff\xf6\x00\x0f\xf0\x07\xe0~\x06\xf9\xe1\x00\x0f\xf0\x07\xe1\x8e\x06\xf1\xe7\x00\x0f\xf0\x02\xed\xe9\x06\xf0\x9d\x00\x0f\xf0\x00-\xc0\x00\x00\x00\x00\x0f\xf0\x00\x07\xfa\x00\x00\x00\x00\x0f\xf0\x00\x00"\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00', + '\t': b'\x00\x0f\xff\xff\xff\xff\xff\xf0\x00\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x0e \x00\x00\x83\x00\x00\x0f\xf0\x0e \x00\x00-\x10\x00\x0f\xf0\x0e \x00\x00\x05\xc0\x00\x0f\xf0\x0e\xff\xff\xff\xff\xf6\x00\x0f\xf0\x0eC339\x90\x00\x0f\xf0\x0e \x00\x00f\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\xf0\x00\x00\x00\x00\x00\x0f\xf0\x00\x0f\xff\xff\xff\xff\xff\xf0\x00', } diff --git a/misc/q1font/render.py b/misc/q1font/render.py index eab85d00..7e220e28 100755 --- a/misc/q1font/render.py +++ b/misc/q1font/render.py @@ -58,8 +58,8 @@ NUM_CHARS = len(CHARSET) # use a different glyph for these unicode values # - useful for multi-codepoint sequences, which we want to encode as single char REMAPS = { - KEY_NFC: 'nfc', - KEY_QR: 'qr', + KEY_NFC: 'NFC', + KEY_QR: 'QR', KEY_TAB: '↦', } @@ -100,7 +100,7 @@ def make_palette(shades, col, darken=1.0): def doit(out_fname='font_iosevka.py', cls_name='FontIosevka'): font = ImageFont.truetype(FONT, FONT_SIZE) - font2 = ImageFont.truetype(FONT, FONT_SIZE-5) + keycap_font = ImageFont.truetype(FONT, FONT_SIZE-7) # see KEY_NFC left, top, right, bottom = font.getbbox("|") char_h = bottom - top @@ -153,13 +153,13 @@ def doit(out_fname='font_iosevka.py', cls_name='FontIosevka'): if ch in KEYCAP_SYMBOLS: if ch == KEY_NFC: - x_shift += 0 + x_shift += 1 elif ch == KEY_QR: - x_shift += 2 + x_shift += 3 else: x_shift += 3 - this_y += 3 - draw.text((x_shift, y_offset + this_y), REMAPS.get(ch, ch), 'white', font2) + this_y += 5 + draw.text((x_shift, y_offset + this_y), REMAPS.get(ch, ch), 'white', keycap_font) # add a border draw.rounded_rectangle( ( 0,0, (CELL_W*2)-1, CELL_H-1), 4, outline='white') @@ -249,7 +249,7 @@ def doit(out_fname='font_iosevka.py', cls_name='FontIosevka'): BRAND_TEXT_COLOUR = (255, 176, 0) # amber phospher colour #ffb000 pal_nums, pal_vals, text_pal = make_palette(shades, BRAND_TEXT_COLOUR) _, pal_vals_inv, text_pal_inv = make_palette([255-i for i in shades], BRAND_TEXT_COLOUR) - _, _, text_pal_dark = make_palette(shades, BRAND_TEXT_COLOUR, 0.66) + pal_dark_nums, _, text_pal_dark = make_palette(shades, BRAND_TEXT_COLOUR, 0.66) with open(out_fname, 'w') as fp: tmpl = open('template.py').read() @@ -266,6 +266,7 @@ TEXT_PALETTES = [ # same, but w/o byte swapping, packing (useful for simulator) #TEXT_PALETTE = [{pal_vals}] COL_TEXT = const(0x{pal_nums[15]:04x}) # text foreground colour +COL_DARK_TEXT = const(0x{pal_dark_nums[15]:04x}) # "dark" pallette text foreground colour CELL_W = const({CELL_W}) CELL_H = const({CELL_H}) diff --git a/misc/q1font/sample.png b/misc/q1font/sample.png index 692b1a6f06e6ecccdf8e5bd0e7fd3f29c99215bd..b4eec6edb9766634b1386d9b8a4de458e439aa59 100644 GIT binary patch delta 6761 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 LNkvXXu0mjfjnaFt delta 6739 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 ACTIVE_H: + pos = ACTIVE_H - bh + self.dis.fill_rect(WIDTH-bw, TOP_MARGIN+pos, bw, bh, COL_TEXT) def fullscreen(self, msg, percent=None): # show a simple message "fullscreen".