From 88369627ccb1c0e1317d30a38fbf44113ade5e73 Mon Sep 17 00:00:00 2001 From: Matthew Wilkes Date: Mon, 30 May 2022 18:38:58 +0100 Subject: [PATCH 1/3] Add brand colours to tidal.py This adds all the brand colours to the tidal interface, including a utility to adjust RGB to a color565 entry that looks a closer match perceptually. This also moves the HSV utilities out of the torch and into a utility module mimicing colorsys. --- modules/colorsys.py | 47 ++++++++++++++++++++++++++++++++++++ modules/textwindow.py | 4 ++-- modules/tidal.py | 18 ++++++++++++++ modules/torch/__init__.py | 50 ++------------------------------------- 4 files changed, 69 insertions(+), 50 deletions(-) create mode 100644 modules/colorsys.py diff --git a/modules/colorsys.py b/modules/colorsys.py new file mode 100644 index 0000000..9e76ae7 --- /dev/null +++ b/modules/colorsys.py @@ -0,0 +1,47 @@ + +# Ported from https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c +def hsv_to_rgb(h, s, v): + i = int(h * 6) + f = h * 6 - i + p = v * (1 - s) + q = v * (1 - f * s) + t = v * (1 - (1 - f) * s) + mod = i % 6 + if mod == 0: + r = v; g = t; b = p + elif mod == 1: + r = q; g = v; b = p + elif mod == 2: + r = p; g = v; b = t + elif mod == 3: + r = p; g = q; b = v + elif mod == 4: + r = t; g = p; b = v + elif mod == 5: + r = v; g = p; b = q + + return (int(r * 255), int(g * 255), int(b * 255)) + +def rgb_to_hsv(r, g, b): + r = r / 255 + g = g / 255 + b = b / 255 + max_val = max(r, g, b) + min_val = min(r, g, b) + v = max_val + d = max_val - min_val + s = 0 if max_val == 0 else d / max_val + + if max_val == min_val: + h = 0 # achromatic + else: + if max_val == r: + h = (g - b) / d + (6 if g < b else 0) + elif max_val == g: + h = (b - r) / d + 2 + elif max_val == b: + h = (r - g) / d + 4 + h /= 6 + + return (h, s, v) + diff --git a/modules/textwindow.py b/modules/textwindow.py index cbc5360..965d45b 100644 --- a/modules/textwindow.py +++ b/modules/textwindow.py @@ -8,7 +8,7 @@ class TextWindow: RIGHT_ARROW = '\x1A' LEFT_ARROW = '\x1B' - DEFAULT_BG = tidal.color565(0, 0, 0x60) + DEFAULT_BG = tidal.BRAND_NAVY DEFAULT_FG = tidal.WHITE def __init__(self, bg=None, fg=None, title=None, font=None, buttons=None): @@ -163,7 +163,7 @@ def flow_lines(self, text, font=None): class Menu(TextWindow): DEFAULT_FOCUS_FG = tidal.BLACK - DEFAULT_FOCUS_BG = tidal.CYAN + DEFAULT_FOCUS_BG = tidal.BRAND_CYAN def __init__(self, bg, fg, focus_bg, focus_fg, title, choices, font=None, buttons=None): super().__init__(bg, fg, title, font, buttons) diff --git a/modules/tidal.py b/modules/tidal.py index 4edac24..8cca82b 100644 --- a/modules/tidal.py +++ b/modules/tidal.py @@ -3,12 +3,30 @@ from machine import Pin from machine import SPI from neopixel import NeoPixel +from colorsys import hsv_to_rgb, rgb_to_hsv import st7789 from st7789 import BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, WHITE, color565 import _tidal_usb as usb import tidal_helpers +# Boost the saturation massively to match better on the LCD +def perceptual_adjust(r, g, b): + h, s, v = rgb_to_hsv(r, g, b) + s *= 1.6 + s = min(s, 1.0) + r, g, b = hsv_to_rgb(h, s, v) + return color565(r, g, b) + +BRAND_NAVY = perceptual_adjust(21, 23, 53) +BRAND_MID_BLUE = perceptual_adjust(18, 63, 139) +BRAND_CYAN = perceptual_adjust(144, 204, 214) +BRAND_YELLOW = perceptual_adjust(242, 222, 27) +BRAND_ORANGE = perceptual_adjust(246, 163, 24) +BRAND_PINK = perceptual_adjust(228, 20, 126) +ADDITIONAL_PURPLE = perceptual_adjust(118, 34, 114) +ADDITIONAL_RED = perceptual_adjust(230, 43, 39) +ADDITIONAL_DEEP_ORANGE = perceptual_adjust(235, 107, 16) """ NOTE: If you are using the automatic lightsleep (on by default) you should never diff --git a/modules/torch/__init__.py b/modules/torch/__init__.py index cdfb1d9..e515f11 100644 --- a/modules/torch/__init__.py +++ b/modules/torch/__init__.py @@ -1,4 +1,5 @@ from tidal import * +from colorsys import hsv_to_rgb from app import TextApp BRIGHTNESS_STEP = 0.8 @@ -27,53 +28,6 @@ (MORSE_WORD, HUE_WHITE, 0)]) ] -# Ported from https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c -def hsvToRgb(h, s, v): - i = int(h * 6) - f = h * 6 - i - p = v * (1 - s) - q = v * (1 - f * s) - t = v * (1 - (1 - f) * s) - mod = i % 6 - if mod == 0: - r = v; g = t; b = p - elif mod == 1: - r = q; g = v; b = p - elif mod == 2: - r = p; g = v; b = t - elif mod == 3: - r = p; g = q; b = v - elif mod == 4: - r = t; g = p; b = v - elif mod == 5: - r = v; g = p; b = q - - return (int(r * 255), int(g * 255), int(b * 255)) - -def rgbToHsv(r, g, b): - r = r / 255 - g = g / 255 - b = b / 255 - max_val = max(r, g, b) - min_val = min(r, g, b) - v = max_val - d = max_val - min_val - s = 0 if max_val == 0 else d / max_val - - if max_val == min_val: - h = 0 # achromatic - else: - if max_val == r: - h = (g - b) / d + (6 if g < b else 0) - elif max_val == g: - h = (b - r) / d + 2 - elif max_val == b: - h = (r - g) / d + 4 - h /= 6 - - return (h, s, v) - - class Torch(TextApp): TITLE = "Torch" @@ -133,7 +87,7 @@ def update_led(self): # print("LED h={} s={} v={}".format(hue, saturation, led_v)) led_power_on(self.state) if self.state: - self.led[0] = hsvToRgb(hue, saturation, self.led_v) + self.led[0] = hsv_to_rgb(hue, saturation, self.led_v) else: self.led[0] = (0, 0, 0) self.led.write() From 013658feb826dd3f7e50a1a56c818e55a0eebe45 Mon Sep 17 00:00:00 2001 From: Matthew Wilkes Date: Mon, 30 May 2022 18:40:15 +0100 Subject: [PATCH 2/3] Add raleway fonts This adds the brand font in two sizes. One approximately equal to the vga 8x8 font (which is probably too small) and one approximately equal to the intro logo size in the sponsors app) --- modules/raleway14.py | 121 ++++++++++++++++++++ modules/raleway24.py | 260 ++++++++++++++++++++++++++++++++++++++++++ modules/textwindow.py | 28 ++++- 3 files changed, 404 insertions(+), 5 deletions(-) create mode 100644 modules/raleway14.py create mode 100644 modules/raleway24.py diff --git a/modules/raleway14.py b/modules/raleway14.py new file mode 100644 index 0000000..24ff169 --- /dev/null +++ b/modules/raleway14.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +# Converted from /home/matthewwilkes/Downloads/Raleway-VariableFont_wght.ttf using: +# font2bitmap.py /home/matthewwilkes/Downloads/Raleway-VariableFont_wght.ttf 14 -s '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#$%&()*+,-./:;<=>?@[\]^_{|}~ \n\r\t@£$€' + +MAP = ( + 'j+rD?R>€}@28YJ [,/]6BgdQ_PEaO3S4' + 'L)tcvV7k~UA$Np{x.-1q9X:fI#(mlHZM' + '%bnzTw=£^ui&Wy|\\C5eGKhosF*<0;' +) +BPP = 1 +HEIGHT = 15 +MAX_WIDTH = 15 +_WIDTHS = \ + b'\x05\x06\x05\x0a\x07\x09\x07\x0b\x03\x0c\x07\x08\x09\x07\x04\x03'\ + b'\x04\x08\x03\x08\x09\x08\x08\x0b\x07\x09\x09\x07\x0b\x07\x08\x07'\ + b'\x08\x03\x04\x08\x07\x09\x07\x07\x06\x0b\x09\x09\x0b\x08\x03\x07'\ + b'\x02\x06\x05\x08\x08\x09\x02\x05\x03\x09\x03\x0d\x03\x0a\x09\x0c'\ + b'\x09\x08\x08\x07\x08\x0b\x06\x07\x07\x08\x03\x09\x0f\x08\x03\x07'\ + b'\x0a\x08\x08\x0a\x09\x08\x08\x07\x08\x04\x07\x09\x02' + +OFFSET_WIDTH = 2 +_OFFSETS = \ + b'\x00\x00\x00\x4b\x00\xa5\x00\xf0\x01\x86\x01\xef\x02\x76\x02\xdf'\ + b'\x03\x84\x03\xb1\x04\x65\x04\xce\x05\x46\x05\xcd\x06\x36\x06\x72'\ + b'\x06\x9f\x06\xdb\x07\x53\x07\x80\x07\xf8\x08\x7f\x08\xf7\x09\x6f'\ + b'\x0a\x14\x0a\x7d\x0b\x04\x0b\x8b\x0b\xf4\x0c\x99\x0d\x02\x0d\x7a'\ + b'\x0d\xe3\x0e\x5b\x0e\x88\x0e\xc4\x0f\x3c\x0f\xa5\x10\x2c\x10\x95'\ + b'\x10\xfe\x11\x58\x11\xfd\x12\x84\x13\x0b\x13\xb0\x14\x28\x14\x55'\ + b'\x14\xbe\x14\xdc\x15\x36\x15\x81\x15\xf9\x16\x71\x16\xf8\x17\x16'\ + b'\x17\x61\x17\x8e\x18\x15\x18\x42\x19\x05\x19\x32\x19\xc8\x1a\x4f'\ + b'\x1b\x03\x1b\x8a\x1c\x02\x1c\x7a\x1c\xe3\x1d\x5b\x1e\x00\x1e\x5a'\ + b'\x1e\xc3\x1f\x2c\x1f\xa4\x1f\xd1\x20\x58\x21\x39\x21\xb1\x21\xde'\ + b'\x22\x47\x22\xdd\x23\x55\x23\xcd\x24\x63\x24\xea\x25\x62\x25\xda'\ + b'\x26\x43\x26\xbb\x26\xf7\x27\x60\x27\xe7' + +_BITMAPS =\ + b'\x00\x80\x01\x08\x42\x10\x84\x21\x70\x00\x00\x00\x00\x00\x41\x80'\ + b'\x00\x00\x00\x00\x00\x00\x00\x11\x08\x42\x10\x80\x00\x00\x00\x1f'\ + b'\x84\x11\x02\x40\x90\x24\x09\x02\x40\x90\x24\x11\xf8\x00\x00\x00'\ + b'\x00\x03\xc0\x40\x81\x06\x10\x40\x80\x00\x04\x00\x00\x00\x00\x7e'\ + b'\x20\x90\x48\x24\x12\x09\xe8\x88\x42\x20\x90\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x20\x30\x18\x08\x63\x08\x00\x00\x00\x00\x03\xe0\x80'\ + b'\x20\x04\x00\xf8\x10\x07\xc0\x40\x04\x00\x82\x0f\x80\x00\x00\x00'\ + b'\x00\x02\x49\x24\x90\x00\x00\x00\x00\x00\x00\x00\x0f\x81\x04\x27'\ + b'\xa2\x09\x20\x92\x79\x28\x92\x89\x27\x61\x00\x0f\x80\x00\x00\x00'\ + b'\x1c\x04\x08\x31\x84\x08\x1e\x00\x00\x00\x00\x00\xf1\x09\x08\x88'\ + b'\xf1\x09\x09\x09\x08\xf0\x00\x00\x00\x00\x00\x41\x21\x08\x82\x81'\ + b'\x40\x40\x20\x10\x08\x04\x00\x00\x00\x00\x00\x01\x02\x04\x08\x10'\ + b'\x20\x40\x81\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x49'\ + b'\x24\x92\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x81'\ + b'\x01\x02\x02\x04\x08\x08\x00\x00\x00\x00\x00\x04\x92\x49\x24\x00'\ + b'\x00\x00\x3c\x40\x40\x7c\x42\x41\x41\x41\x42\x3c\x00\x00\x00\x00'\ + b'\x3f\x10\x48\x24\x12\x09\xf8\x82\x41\x20\x90\x4f\xe0\x00\x00\x00'\ + b'\x00\x00\x00\x00\x78\x84\x84\x84\x84\x84\x84\x7c\x04\x04\x78\x00'\ + b'\x00\x04\x04\x7c\x84\x84\x84\x84\x84\x84\x78\x00\x00\x00\x00\x07'\ + b'\xc1\x04\x40\x88\x09\x01\x20\x24\x04\x80\x90\x21\x04\x1f\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x38\x00\x00'\ + b'\x01\xf8\x82\x41\x20\x90\x48\x27\xe2\x01\x00\x80\x40\x00\x00\x00'\ + b'\x00\x03\xf1\x00\x80\x40\x20\x1f\x08\x04\x02\x01\x00\xfc\x00\x00'\ + b'\x00\x00\x00\x00\x00\x70\x10\x27\xc8\x91\x22\x78\x00\x00\x00\x00'\ + b'\x3e\x08\x22\x04\x40\x48\x09\x01\x20\x24\x04\x81\x08\x20\xf8\x00'\ + b'\x00\x00\x00\x00\x00\x00\x01\xc0\x40\x40\x82\x0c\x04\x08\x13\xc0'\ + b'\x00\x0f\x90\x10\x10\x18\x07\x00\x80\x40\x40\x4f\x80\x00\x00\x00'\ + b'\x00\x00\x00\x10\x61\x44\x89\x22\xfc\x08\x10\x20\x00\x08\x08\x08'\ + b'\x08\x08\x08\x08\x08\x08\x08\x0f\xc0\x00\x00\x00\x04\x89\x25\x20'\ + b'\x00\x04\x44\x44\x44\x44\x46\x00\x00\x00\x00\x00\x03\xc4\x24\x04'\ + b'\x04\x04\x04\x03\xc0\x00\x00\x00\x00\x00\x00\x02\x85\x12\x22\x85'\ + b'\x04\x08\x00\x00\x00\x02\x01\x01\x40\xa0\x88\x44\x42\x20\x90\x50'\ + b'\x10\x08\x00\x00\x00\x00\x00\x00\x00\x3e\x04\x10\x20\x81\x04\x08'\ + b'\x20\x00\x00\x00\x08\x10\x20\x44\x91\x43\x44\x48\x80\x80\x00\x00'\ + b'\x00\x00\x00\x00\x18\x18\x00\x00\x00\x00\x00\x00\x08\x01\x02\x20'\ + b'\x44\x08\x81\x10\x22\x04\x40\x88\x10\x82\x0f\x80\x00\x00\x00\x00'\ + b'\x00\x20\x28\x14\x0a\x08\x84\x42\x22\xe9\x05\x01\x80\x80\x00\x00'\ + b'\x00\x01\xf1\x20\x90\x48\x34\x07\x01\x60\x90\x48\x24\x7c\x00\x00'\ + b'\x00\x00\x01\x00\x30\x45\x08\xa1\x12\x22\x24\x42\x88\x51\x06\x20'\ + b'\x44\x08\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\x41\x41\x41\x41'\ + b'\x42\x7c\x40\x40\x00\x01\x24\x92\x49\x20\x00\x00\x00\x00\x00\x44'\ + b'\x50\xc0\x82\x88\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x08\x21\x08\x42\x11\x80\x00'\ + b'\x00\x00\x00\x00\x1e\x21\x21\x21\x21\x21\x21\x1f\x01\x01\x00\x00'\ + b'\x00\x00\x00\x1e\x21\x21\x21\x21\x21\x1f\x01\x21\x1e\x00\x00\x00'\ + b'\x08\x22\x21\x20\x50\x10\x14\x12\x08\x88\x20\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x07\x42\x18\x84\x21\x08\x42\x00\x00\x04\x92\x49\x24'\ + b'\x90\x00\x00\x00\x01\x08\x8f\xc2\x42\x21\x10\x88\x78\x44\x20\x00'\ + b'\x00\x00\x00\x05\x24\x92\x48\x80\x00\x00\x00\x00\x00\x00\x00\xf7'\ + b'\x88\x42\x42\x12\x10\x90\x84\x84\x24\x21\x01\x08\x00\x00\x00\x00'\ + b'\x00\x49\x24\x92\x49\x00\x00\x04\x01\x02\x40\x90\x24\x09\xfe\x40'\ + b'\x90\x24\x09\x02\x40\x00\x00\x00\x00\x00\x3f\x80\x40\x40\x40\x20'\ + b'\x20\x20\x20\x10\x10\x1f\xc0\x00\x00\x00\x00\x08\x04\x80\x4c\x0c'\ + b'\xa0\xca\x14\x92\x49\x24\x8c\x48\x04\x80\x48\x00\x00\x00\x00\x00'\ + b'\x00\x07\x02\x49\x28\xe4\x04\x04\x04\x02\xe2\x4a\x25\x1c\x00\x00'\ + b'\x00\x00\x00\x10\x10\x1f\x10\x90\x50\x50\x50\x50\x8f\x00\x00\x00'\ + b'\x00\x00\x00\x00\x07\x18\x90\x90\x90\x90\x90\x80\x00\x00\x00\x00'\ + b'\x00\x00\x00\xf0\x20\x82\x04\x10\x41\xf0\x00\x00\x00\x0f\xc1\x01'\ + b'\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x14\x52\x8a\x22\x44\x44\x90\xaa\x09\x41\x10\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x1c\x44\x81\x02'\ + b'\x03\x04\x08\x10\x20\xf0\x00\x00\x00\x04\x14\x28\x89\x10\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x24\x24\x24\x24\x24'\ + b'\x23\xc0\x00\x00\x00\x00\x09\x24\x90\x00\x00\x0f\x08\x84\x41\x20'\ + b'\xe0\x60\x48\x22\x90\x88\x63\xc0\x00\x00\x00\x00\x01\x00\x01\x0a'\ + b'\x12\x14\x24\x30\x84\x21\x08\x44\x11\x48\x12\x90\x29\x40\x21\x80'\ + b'\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x22\x22\x12'\ + b'\x14\x08\x08\x08\x08\x10\x04\x92\x49\x24\x92\x40\x00\x04\x08\x08'\ + b'\x08\x10\x10\x20\x20\x40\x40\x00\x00\x00\x0f\x84\x12\x00\x80\x20'\ + b'\x08\x02\x00\x80\x20\x04\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x01'\ + b'\xe2\x02\x02\x03\xe0\x10\x10\x10\x11\xe0\x00\x00\x00\x00\x01\xe2'\ + b'\x12\x0b\xfa\x02\x02\x01\xe0\x00\x00\x00\x00\x3e\x10\x48\x02\x00'\ + b'\x80\x20\x48\x02\x04\x81\x10\x43\xe0\x00\x00\x00\x00\x04\x02\x11'\ + b'\x10\x88\x48\x2c\x19\x08\x84\x22\x09\x00\x00\x00\x00\x00\x00\x10'\ + b'\x10\x1f\x10\x90\x90\x90\x90\x90\x80\x00\x00\x00\x00\x00\x00\x00'\ + b'\x0f\x10\x90\x50\x50\x50\x50\x8f\x00\x00\x00\x00\x00\x00\x00\xf2'\ + b'\x04\x06\x03\x02\x04\xf0\x00\x00\x00\x0f\xc8\x08\x08\x08\x0f\x88'\ + b'\x08\x08\x08\x08\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x01\x0c\x61\x01\x80\xc0\x40\x00\x00\x00\x00\x00\x00'\ + b'\x03\xc2\x11\x04\x82\x41\x20\x90\x87\x80\x00\x00\x00\x00\x00\x00'\ + b'\x00' + +WIDTHS = memoryview(_WIDTHS) +OFFSETS = memoryview(_OFFSETS) +BITMAPS = memoryview(_BITMAPS) diff --git a/modules/raleway24.py b/modules/raleway24.py new file mode 100644 index 0000000..099d3ab --- /dev/null +++ b/modules/raleway24.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# Converted from /home/matthewwilkes/Downloads/Raleway-VariableFont_wght.ttf using: +# font2bitmap.py /home/matthewwilkes/Downloads/Raleway-VariableFont_wght.ttf 24 -s '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#$%&()*+,-./:;<=>?@[\]^_{|}~ \n\r\t@£$€' + +MAP = ( + 'O-mXQop(_uW\\PSn€+C%3}k#FrHy|6>A' + 'c^8?EdlRVL 9x*g):NhZ]D/;wsIK5qbM' + '72=£z{40j1,efitTY~vJBa$&[.@GU<' +) +BPP = 1 +HEIGHT = 24 +MAX_WIDTH = 25 +_WIDTHS = \ + b'\x12\x0a\x16\x0f\x12\x0e\x0e\x06\x0d\x0e\x19\x0c\x0f\x0e\x0e\x14'\ + b'\x0a\x11\x10\x0d\x06\x0c\x10\x0e\x08\x12\x0d\x05\x0e\x0c\x10\x0d'\ + b'\x0c\x0e\x0b\x0f\x0f\x06\x0f\x10\x0e\x06\x0e\x0c\x07\x0e\x06\x04'\ + b'\x13\x0e\x0f\x05\x11\x0d\x04\x13\x0b\x05\x0f\x0d\x0e\x0e\x15\x0d'\ + b'\x0c\x0a\x0b\x0c\x06\x0c\x0f\x08\x09\x06\x0e\x08\x05\x07\x0e\x0f'\ + b'\x0b\x0c\x0b\x10\x0d\x0f\x0f\x05\x04\x14\x11\x12\x0c' + +OFFSET_WIDTH = 2 +_OFFSETS = \ + b'\x00\x00\x01\xb0\x02\xa0\x04\xb0\x06\x18\x07\xc8\x09\x18\x0a\x68'\ + b'\x0a\xf8\x0c\x30\x0d\x80\x0f\xd8\x10\xf8\x12\x60\x13\xb0\x15\x00'\ + b'\x16\xe0\x17\xd0\x19\x68\x1a\xe8\x1c\x20\x1c\xb0\x1d\xd0\x1f\x50'\ + b'\x20\xa0\x21\x60\x23\x10\x24\x48\x24\xc0\x26\x10\x27\x30\x28\xb0'\ + b'\x29\xe8\x2b\x08\x2c\x58\x2d\x60\x2e\xc8\x30\x30\x30\xc0\x32\x28'\ + b'\x33\xa8\x34\xf8\x35\x88\x36\xd8\x37\xf8\x38\xa0\x39\xf0\x3a\x80'\ + b'\x3a\xe0\x3c\xa8\x3d\xf8\x3f\x60\x3f\xd8\x41\x70\x42\xa8\x43\x08'\ + b'\x44\xd0\x45\xd8\x46\x50\x47\xb8\x48\xf0\x4a\x40\x4b\x90\x4d\x88'\ + b'\x4e\xc0\x4f\xe0\x50\xd0\x51\xd8\x52\xf8\x53\x88\x54\xa8\x56\x10'\ + b'\x56\xd0\x57\xa8\x58\x38\x59\x88\x5a\x48\x5a\xc0\x5b\x68\x5c\xb8'\ + b'\x5e\x20\x5f\x28\x60\x48\x61\x50\x62\xd0\x64\x08\x65\x70\x66\xd8'\ + b'\x67\x50\x67\xb0\x69\x90\x6b\x28\x6c\xd8' + +_BITMAPS =\ + b'\x00\x00\x00\x00\x00\x3f\x00\x30\x30\x10\x02\x04\x00\x42\x00\x11'\ + b'\x00\x02\x40\x00\x90\x00\x24\x00\x09\x00\x02\x40\x00\x90\x00\x22'\ + b'\x00\x10\x80\x04\x10\x02\x03\x03\x00\x3f\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x02\x7c\x3c\x0a\x0b\x08\x30\x28\x10\x80\x40\x42'\ + b'\x02\x01\x08\x08\x04\x20\x20\x10\x80\x80\x42\x02\x01\x08\x08\x04'\ + b'\x20\x20\x10\x80\x80\x42\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12\x00\x22\x00\x82'\ + b'\x02\x02\x08\x04\x20\x04\x40\x05\x00\x04\x00\x14\x00\x48\x00\x88'\ + b'\x02\x08\x08\x08\x20\x08\x80\x11\x00\x10\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x30\x30\x10\x02\x04\x00'\ + b'\x42\x00\x11\x00\x02\x40\x00\x90\x00\x24\x00\x09\x00\x02\x40\x00'\ + b'\x90\x00\x22\x00\x90\x80\x14\x10\x02\x03\x03\x80\x3f\x10\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\xfc\x04\x08\x20\x10\x80\x44\x00\x90\x02\x40\x09'\ + b'\x00\x24\x00\x88\x04\x20\x10\x40\x80\xfc\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x7c\x0e'\ + b'\x08\x20\x10\x80\x22\x00\x88\x02\x20\x08\x80\x22\x00\x88\x02\x30'\ + b'\x10\xa0\x82\x7c\x08\x00\x20\x00\x80\x02\x00\x08\x00\x00\x00\x84'\ + b'\x10\x82\x08\x41\x04\x10\x41\x04\x08\x20\x41\x02\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x80'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x01\x08\x04\x20\x10\x80\x42\x01\x08\x04\x20\x10\x80\x42\x01'\ + b'\x08\x04\x20\x30\x41\x40\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x20\x10\x40\x48\x04\x40\x24\x02\x20\x11'\ + b'\x01\x20\x10\x80\x50\x08\x20\x28\x08\x10\x08\x04\x08\x04\x04\x02'\ + b'\x05\x02\x01\x02\x81\x00\x42\x41\x00\x21\x10\x80\x08\x88\x80\x04'\ + b'\x82\x40\x01\x41\x40\x00\xc0\x60\x00\x20\x20\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x04'\ + b'\x00\x20\x01\x00\x10\x00\x80\x08\x00\x40\x02\x00\x20\x01\x00\x08'\ + b'\x00\x80\x04\x00\x40\x02\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\xff\xc1\x00\x42\x00\x44\x00\x88\x01\x10\x02\x20\x04'\ + b'\x40\x08\x80\x21\xff\x82\x00\x04\x00\x08\x00\x10\x00\x20\x00\x40'\ + b'\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\xfe\x04\x04\x20\x01\x00\x04\x00\x10\x00\x20\x00\x60\x00\x78\x00'\ + b'\x1c\x00\x08\x00\x10\x00\x40\x01\x40\x08\xc0\x60\xfe\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x02\x7c\x0a\x08\x30\x10\x80\x42\x01\x08\x04\x20\x10\x80\x42\x01'\ + b'\x08\x04\x20\x10\x80\x42\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\xfe\x00\x10\x10\x02\x00\x80\x40\x04\x08'\ + b'\x00\x00\x80\x00\x08\x00\x01\xff\x80\x10\x00\x01\x00\x00\x2f\xf0'\ + b'\x00\x80\x00\x08\x00\x00\x40\x04\x02\x00\x80\x10\x10\x00\xfe\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x20\x08\x02\x03\xf0\x20\x08\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc'\ + b'\x01\x81\x81\x00\x21\x00\x10\x80\x00\x80\x00\x40\x00\x20\x00\x10'\ + b'\x00\x08\x00\x04\x00\x02\x00\x00\x80\x00\x20\x02\x10\x02\x06\x06'\ + b'\x00\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x1c\x02\x22\x04\x41\x08\x41\x08\x41\x10\x22\x20\x1c\x40\x00'\ + b'\x80\x00\x80\x01\x00\x02\x3c\x04\x42\x08\x82\x08\x82\x10\x82\x20'\ + b'\x42\x40\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x0f\xc0\x81\x08\x04\x00\x20\x01\x00\x08\x00'\ + b'\x40\x04\x01\xc0\x01\x00\x04\x00\x20\x01\x00\x08\x00\x44\x02\x10'\ + b'\x20\x7e\x00\x00\x00\x82\x08\x20\x82\x08\x20\x81\x08\x20\x82\x08'\ + b'\x20\x82\x08\x00\x00\x00\x00\x02\x00\x20\x02\x00\x20\x02\x00\x20'\ + b'\x22\x04\x20\x82\x10\x22\x02\x40\x2a\x03\x10\x20\x82\x08\x20\x42'\ + b'\x02\x20\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x08'\ + b'\x02\x08\x02\x08\x04\x08\x1f\xfc\x04\x10\x04\x10\x08\x10\x08\x20'\ + b'\x08\x20\x08\x20\x37\xf8\x10\x40\x10\x40\x10\x40\x20\x40\x20\x80'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xff\x08'\ + b'\x00\x20\x00\x80\x02\x00\x08\x00\x20\x00\x80\x03\xfe\x08\x00\x20'\ + b'\x00\x80\x02\x00\x08\x00\x20\x00\x80\x02\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x28\x20\x20\x20\x20'\ + b'\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x02\x00\x00\x80\x08\x20\x02\x08\x00\x82\x00\x20\x80\x08\x20\x02'\ + b'\x08\x00\x83\xff\xe0\x80\x08\x20\x02\x08\x00\x82\x00\x20\x80\x08'\ + b'\x20\x02\x08\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x48\x02\x40'\ + b'\x21\x01\x08\x08\x20\x81\x04\x04\x40\x22\x00\xa0\x05\x00\x10\x00'\ + b'\x80\x04\x00\x40\x02\x00\x20\x03\x00\x21\x08\x42\x10\x84\x21\x08'\ + b'\x42\x10\x84\x21\x08\x42\x10\x00\x00\x00\x00\x00\x7c\x02\x08\x10'\ + b'\x10\x80\x02\x00\x08\x00\x47\xc1\x60\x86\x01\x10\x02\x40\x09\x00'\ + b'\x24\x00\x88\x02\x20\x10\x40\xc0\xfc\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x30\x00'\ + b'\xc0\x03\x00\x08\x00\x60\x06\x00\x80\x30\x0c\x03\x00\x40\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x80\x02\x40'\ + b'\x02\x40\x02\x40\x04\x20\x04\x20\x08\x10\x08\x10\x10\x08\x1f\xf8'\ + b'\x10\x08\x20\x04\x20\x04\x40\x02\x40\x02\x80\x01\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x3f\x02\x04\x20\x12\x00\x10\x00\x80\x04\x00\x20\x01\x00\x04\x00'\ + b'\x20\x10\x81\x03\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x02\x00\x60\x09\x00\x90\x10\x81\x08\x10\x42\x04\x20\x24\x02\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\xfc\x04\x08\x20\x10\x80\x42\x01\x08\x04\x20'\ + b'\x20\x61\x00\xfc\x04\x08\x20\x11\x00\x24\x00\x90\x02\x20\x10\x40'\ + b'\x80\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x10'\ + b'\x44\x04\x00\x80\x10\x02\x00\x40\x10\x0c\x02\x00\x80\x10\x02\x00'\ + b'\x00\x00\x01\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\xff\xc1\x00\x02\x00\x04\x00\x08\x00\x10\x00\x20\x00\x40\x00\xff'\ + b'\x81\x00\x02\x00\x04\x00\x08\x00\x10\x00\x20\x00\x40\x00\xff\xe0'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00'\ + b'\x40\x00\x80\x01\x03\xf2\x08\x14\x20\x10\x40\x11\x00\x22\x00\x44'\ + b'\x00\x88\x01\x10\x02\x10\x04\x20\x10\x20\x50\x3f\x20\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x82\x08\x20\x82\x08\x20\x82\x08\x20'\ + b'\x82\x08\x20\x81\xc0\x00\x00\x00\x00\x00\x00\x00\xff\xc1\x00\x42'\ + b'\x00\x44\x00\x88\x01\x10\x02\x20\x04\x40\x08\x80\x21\xfd\x82\x04'\ + b'\x04\x04\x08\x04\x10\x08\x20\x08\x40\x10\x80\x10\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x40\x02\x40\x02\x20'\ + b'\x02\x20\x04\x10\x04\x10\x08\x10\x08\x08\x10\x08\x10\x04\x20\x04'\ + b'\x20\x02\x20\x02\x40\x01\x40\x01\x80\x00\x80\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00\x20\x00\x80\x02'\ + b'\x00\x08\x00\x20\x00\x80\x02\x00\x08\x00\x20\x00\x80\x02\x00\x08'\ + b'\x00\x20\x00\x80\x03\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x01\x02\x08\x04\x40'\ + b'\x11\x00\x24\x00\x90\x02\x40\x09\x00\x22\x01\x84\x0a\x0f\xc8\x00'\ + b'\x40\x01\x00\x04\x20\x20\x41\x00\xf8\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x40\x24\x04\x20\x81\x08\x09\x00\xa0\x04\x00\x60'\ + b'\x09\x01\x08\x20\x84\x04\x40\x20\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x41\xe1\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc'\ + b'\x04\x0c\x20\x10\x80\x44\x01\x10\x04\x40\x11\x00\x44\x01\x08\x04'\ + b'\x20\x10\x40\xc0\xfd\x00\x04\x00\x10\x80\x41\x02\x03\xf0\x00\x04'\ + b'\x10\x20\x81\x04\x10\x41\x04\x10\x41\x04\x20\x84\x10\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x80\x00\x18\x00\x82\x80\x10\x48\x02\x08\x80\x41\x10\x08\x21'\ + b'\x01\x04\x10\x20\x81\x04\x10\x10\x82\x02\x10\x40\x22\x08\x02\x41'\ + b'\x00\x28\x20\x03\x04\x00\x60\x80\x04\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x80\x02\x00\x08\x00\x20\x00\x80\x02'\ + b'\x7c\x0a\x08\x30\x20\x80\x42\x01\x08\x04\x20\x10\x80\x42\x01\x08'\ + b'\x04\x20\x10\x80\x42\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\xff\xf0\x00\x20\x00\x80\x02\x00\x08\x00\x20\x00\x40'\ + b'\x01\x00\x04\x00\x10\x00\x40\x00\x80\x02\x00\x08\x00\x20\x00\x80'\ + b'\x01\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x08\x42\x10'\ + b'\x84\x21\x08\x42\x10\x84\x21\x08\x40\x00\x00\x00\x00\x00\x00\x0f'\ + b'\xf8\x04\x03\x02\x00\x41\x00\x10\x80\x08\x40\x02\x20\x01\x10\x00'\ + b'\x88\x00\x44\x00\x22\x00\x11\x00\x08\x80\x08\x40\x04\x20\x04\x10'\ + b'\x04\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x04\x00\x40\x02\x00\x20\x02\x00\x10\x01\x00\x08\x00\x80'\ + b'\x08\x00\x40\x04\x00\x40\x02\x00\x20\x02\x00\x10\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10'\ + b'\x44\x12\x04\x82\x40\xa0\x44\x14\x10\x81\x02\x08\x20\x81\x0a\x10'\ + b'\x21\x42\x02\x28\x80\x48\x90\x05\x14\x00\xc1\x80\x08\x20\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x07\xe1\x02\x40\x08\x00\x80\x18\x00\xf0\x01\x00\x10\x02'\ + b'\x00\x4c\x08\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x08\x42\x10\x84'\ + b'\x21\x08\x42\x10\x84\x21\x08\x00\x00\x00\x00\x00\x00\x00\x80\x11'\ + b'\x00\x42\x01\x04\x04\x08\x10\x10\x40\x21\x00\x44\x00\x94\x01\x44'\ + b'\x03\x04\x04\x04\x08\x08\x10\x08\x20\x08\x40\x08\x80\x08\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f'\ + b'\xe0\x40\x04\x00\x20\x01\x00\x08\x00\x40\x04\xf8\x38\x21\x00\x80'\ + b'\x02\x00\x10\x00\x80\x04\x00\x24\x02\x10\x20\x7e\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x04\x0c\x20\x10\x80\x44'\ + b'\x01\x10\x04\x40\x11\x00\x44\x01\x08\x04\x20\x10\x40\xc0\xfd\x00'\ + b'\x04\x00\x10\x00\x40\x01\x00\x00\x00\x00\x80\x02\x00\x08\x00\x20'\ + b'\x00\x80\x02\x7c\x0a\x08\x30\x10\x80\x22\x00\x88\x02\x20\x08\x80'\ + b'\x22\x00\x88\x02\x20\x10\xe0\x82\x7c\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x08\x00\x08\x60\x00\x43\x00\x06\x14'\ + b'\x00\x50\x90\x02\x84\x80\x24\x22\x02\x21\x10\x11\x08\x41\x08\x41'\ + b'\x08\x42\x08\x82\x10\x28\x10\x81\x40\x84\x04\x04\x20\x00\x21\x00'\ + b'\x01\x08\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xf8\x00\x40\x04\x00\x20'\ + b'\x02\x00\x10\x01\x00\x08\x00\x80\x04\x00\x40\x02\x00\x20\x01\x00'\ + b'\x10\x01\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'\ + b'\xf8\x20\x40\x04\x00\x40\x04\x00\x40\x18\x06\x00\x80\x30\x02\x00'\ + b'\x40\x04\x00\x7f\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x08\x42'\ + b'\x04\x40\x08\x01\x00\x10\x02\x00\xfc\x04\x00\x80\x10\x02\x00\x40'\ + b'\x10\x04\x01\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x3f\xe0\x04\x00\x40\x08\x01\x00\x20\x04\x00\x40'\ + b'\x08\x01\x00\x20\x04\x00\x7f\xc0\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x82\x08\x20\x82\x08\x20\x82\x08\x20\x82\x08\x20\x82\x08\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\xc0\x14\x02\x40\x24'\ + b'\x04\x40\x84\x10\x41\x04\x20\x44\x04\xff\xe0\x04\x00\x40\x04\x00'\ + b'\x40\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8'\ + b'\x06\x08\x10\x08\x20\x08\x80\x11\x00\x22\x00\x44\x00\x88\x01\x10'\ + b'\x02\x10\x04\x20\x10\x30\x40\x1f\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x04\x04\x00\x00\x00\x04\x04\x04\x04\x04\x04\x04\x04'\ + b'\x04\x04\x04\x04\x04\x04\x04\x08\x70\x00\x00\x00\x00\x00\x00\x00'\ + b'\x60\xd0\x88\x04\x02\x01\x00\x80\x40\x20\x10\x08\x04\x02\x07\xc0'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\xfc\x04\x08\x20\x10\x80\x44\x00\x90\x02\x7f\xf9\x00\x04'\ + b'\x00\x08\x00\x20\x10\x40\x80\xfc\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x0f\x10\x20\x20\x20\x3c\x20\x20\x20\x20\x20\x20\x20\x20'\ + b'\x20\x20\x20\x20\x00\x00\x00\x00\x00\x01\x08\x00\x00\x84\x21\x08'\ + b'\x42\x10\x84\x21\x08\x00\x00\x00\x00\x00\x81\x02\x04\x0e\x10\x20'\ + b'\x40\x81\x02\x04\x08\x10\x20\x40\x78\x00\x00\x00\x00\x00\x00\x00'\ + b'\x07\xff\x80\x40\x01\x00\x04\x00\x10\x00\x40\x01\x00\x04\x00\x10'\ + b'\x00\x40\x01\x00\x04\x00\x10\x00\x40\x01\x00\x04\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x0a\x00\x22\x00'\ + b'\x82\x01\x04\x04\x04\x10\x04\x20\x08\x80\x0a\x00\x0c\x00\x10\x00'\ + b'\x20\x00\x40\x00\x80\x01\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x0c\x02\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x14'\ + b'\x02\x40\x22\x02\x20\x41\x04\x10\x81\x08\x08\x80\x90\x05\x00\x60'\ + b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x08'\ + b'\x01\x00\x20\x04\x00\x80\x10\x02\x00\x40\x08\x01\x00\x20\x04\x00'\ + b'\x80\x21\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\xf0'\ + b'\x20\x08\x20\x04\x20\x04\x20\x04\x20\x04\x20\x04\x20\x08\x3f\xf0'\ + b'\x20\x08\x20\x04\x20\x02\x20\x02\x20\x02\x20\x04\x20\x04\x3f\xf8'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x7e\x04\x08\x00\x40\x01\x00\x08\x00\x41\xfe\x10'\ + b'\x11\x00\x88\x04\x40\x21\x07\x07\xc8\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x01\x00\x02\x00\x3f\x80\x88\x82\x10\x04\x20\x10\x40\x10\x80'\ + b'\x21\x00\x32\x00\x17\x00\x09\x80\x10\x80\x20\x80\x41\x00\x82\x41'\ + b'\x04\x62\x10\x1f\xc0\x08\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x3e\x00\x82\x01\x04\x04\x08\x04\x10\x08\x40\x09\x00\x0c'\ + b'\x00\x28\x00\x88\x02\x08\x48\x09\x10\x0a\x20\x08\x40\x18\x40\x48'\ + b'\x7f\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x08\x42\x10\x84'\ + b'\x21\x08\x42\x10\x84\x21\x08\x40\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x1f\x80\x06\x06\x00\x80\x10\x10\x00\x82\x1f\x08\x20'\ + b'\x08\x44\x00\x44\x40\x04\x44\x1f\xc4\x42\x04\x44\x20\x44\x42\x04'\ + b'\x42\x20\xc4\x21\xf4\x41\x00\x38\x08\x00\x00\x40\x00\x03\xf8\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\xfc\x01\x81\x81\x00\x21\x00\x00\x80'\ + b'\x00\x80\x00\x40\x00\x20\x00\x10\x03\x88\x00\x24\x00\x12\x00\x08'\ + b'\x80\x04\x20\x02\x10\x03\x06\x06\x80\xfc\x40\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x80\x04\x20\x01'\ + b'\x08\x00\x42\x00\x10\x80\x04\x20\x01\x08\x00\x42\x00\x10\x80\x04'\ + b'\x20\x01\x08\x00\x42\x00\x10\x40\x08\x10\x02\x03\x03\x00\x3f\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x02\x00\xc0\x30\x0c\x01\x00\x60\x06\x00'\ + b'\x10\x00\xc0\x03\x00\x0c\x00\x20\x00\x00\x00\x00\x00\x00\x00' + +WIDTHS = memoryview(_WIDTHS) +OFFSETS = memoryview(_OFFSETS) +BITMAPS = memoryview(_BITMAPS) diff --git a/modules/textwindow.py b/modules/textwindow.py index 965d45b..6fbc289 100644 --- a/modules/textwindow.py +++ b/modules/textwindow.py @@ -35,7 +35,14 @@ def height(self): return self.display.height() def width_chars(self, font=None): - return self.display.width() // (font or self.font).WIDTH + font = font or self.font + if hasattr(font, "WIDTH"): + # Fixed-width fonts have an inherent width + font_width = font.WIDTH + else: + # 1em is a decent approximation for variable + font_width = self.display.write_len(font, "m") + return self.display.width() // font_width def height_chars(self, font=None): return self.display.height() // (font or self.font).HEIGHT @@ -81,18 +88,29 @@ def println(self, text="", y=None, fg=None, bg=None, centre=False): self.draw_line(text, ypos, fg, bg, centre) def draw_line(self, text, ypos, fg, bg, centre): - text_width = len(text) * self.font.WIDTH + if hasattr(self.font, "WIDTH"): + text_width = len(text) * self.font.WIDTH + else: + text_width = self.display.write_len(self.font, text) w = self.width() if centre: xpos = (w - text_width) // 2 - else: + else if hasattr(self.font, "WIDTH"): xpos = (w - self.width_chars() * self.font.WIDTH) // 2 + else: + xpos = 0 self.display.fill_rect(0, ypos, w, self.line_height(), bg) self.draw_text(text, xpos, ypos, fg, bg) def draw_text(self, text, xpos, ypos, fg, bg, font=None): - btext = to_cp437(text) - self.display.text(font or self.font, btext, xpos, ypos, fg, bg) + font = font or self.font + if hasattr(font, "WIDTH"): + # This is a monospace font + btext = to_cp437(text) + self.display.text(font or self.font, btext, xpos, ypos, fg, bg) + else: + # Proportional + self.display.write(font or self.font, text, xpos, ypos, fg, bg) def draw_title(self): if self.title: From 00f3718de31e8faf1380e61fd7e96b0547246463 Mon Sep 17 00:00:00 2001 From: Matthew Wilkes Date: Mon, 30 May 2022 18:47:36 +0100 Subject: [PATCH 3/3] elif in Python, else if in C --- modules/textwindow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/textwindow.py b/modules/textwindow.py index 6fbc289..1b05824 100644 --- a/modules/textwindow.py +++ b/modules/textwindow.py @@ -95,7 +95,7 @@ def draw_line(self, text, ypos, fg, bg, centre): w = self.width() if centre: xpos = (w - text_width) // 2 - else if hasattr(self.font, "WIDTH"): + elif hasattr(self.font, "WIDTH"): xpos = (w - self.width_chars() * self.font.WIDTH) // 2 else: xpos = 0