From 72db945fbc0ebad12516e66749ded60936700d18 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Tue, 21 Mar 2017 11:40:12 +0000 Subject: [PATCH] SSD1306/writer.py uses blit method --- SSD1306/freesans20.py | 464 +++++++++++++++++++++------------------ SSD1306/ssd1306_test.py | 3 +- SSD1306/writer.py | 32 ++- data_to_py/data_to_py.py | 153 +++++++++++++ 4 files changed, 434 insertions(+), 218 deletions(-) create mode 100755 data_to_py/data_to_py.py diff --git a/SSD1306/freesans20.py b/SSD1306/freesans20.py index 53007c9..a35eb84 100644 --- a/SSD1306/freesans20.py +++ b/SSD1306/freesans20.py @@ -1,6 +1,6 @@ # Code generated by font-to-py.py. # Font: FreeSans.ttf -version = '0.1' +version = '0.2' def height(): return 20 @@ -9,7 +9,7 @@ def max_width(): return 20 def hmap(): - return False + return True def reverse(): return False @@ -17,222 +17,254 @@ def reverse(): def monospaced(): return False +def min_ch(): + return 32 + +def max_ch(): + return 126 + _font =\ -b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x07\x00\xfe\xcf\x00\xfe\xcf\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x7c\x00\x00\x3c\x00\x00'\ -b'\x00\x00\x00\x7c\x00\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x0b'\ -b'\x00\x00\x0c\x00\x60\x0c\x00\x60\xfc\x00\xe0\x3f\x00\xfc\x0c\x00'\ -b'\x64\x0c\x00\x60\xfc\x00\xe0\x3f\x00\xfc\x0c\x00\x64\x0c\x00\x60'\ -b'\x00\x00\x0b\x00\xf8\x30\x00\xfc\x71\x00\x8e\xe1\x00\x06\xc3\x00'\ -b'\xff\xff\x01\x06\xc3\x00\x06\xc2\x00\x0c\x66\x00\x3c\x7e\x00\x38'\ -b'\x3c\x00\x00\x00\x00\x12\x00\x70\x00\x00\xf8\x00\x00\x8c\x01\x00'\ -b'\x8c\x01\x00\x8c\x81\x00\xf8\x60\x00\x70\x18\x00\x00\x06\x00\x80'\ -b'\x01\x00\xc0\x38\x00\x30\x7c\x00\x0c\xee\x00\x00\xc6\x00\x00\xc6'\ -b'\x00\x00\xee\x00\x00\x7c\x00\x00\x38\x00\x00\x00\x00\x0d\x00\x00'\ -b'\x3c\x00\x00\x7e\x00\x70\xe6\x00\xf8\xc3\x00\x8c\xc1\x00\x8c\xc3'\ -b'\x00\x8c\xc6\x00\xf8\x6c\x00\x70\x38\x00\x00\x7e\x00\x00\xc6\x00'\ -b'\x00\x80\x00\x00\x00\x00\x04\x00\x7c\x00\x00\x3c\x00\x00\x00\x00'\ -b'\x00\x00\x00\x00\x07\x00\x80\x3f\x00\xe0\xff\x00\x38\x80\x03\x06'\ -b'\x00\x0e\x00\x00\x08\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x08'\ -b'\x06\x00\x0e\x38\x80\x03\xe0\xff\x00\x80\x3f\x00\x00\x00\x00\x00'\ -b'\x00\x00\x08\x00\x08\x00\x00\x68\x00\x00\x1e\x00\x00\x68\x00\x00'\ -b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x0c'\ -b'\x00\x00\x0c\x00\x00\x0c\x00\x80\xff\x00\x80\xff\x00\x00\x0c\x00'\ -b'\x00\x0c\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x00\x06\x00\x00\xc0\x04\x00\xc0\x03\x00\x00\x00\x00\x00\x00'\ -b'\x00\x00\x00\x00\x00\x00\x07\x00\x00\x06\x00\x00\x06\x00\x00\x06'\ -b'\x00\x00\x06\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00'\ -b'\xc0\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00'\ -b'\x00\xc0\x00\x00\x78\x00\x00\x0f\x00\xe0\x01\x00\x3c\x00\x00\x06'\ -b'\x00\x00\x0b\x00\xe0\x1f\x00\xf8\x7f\x00\x3c\xf0\x00\x0c\xc0\x00'\ -b'\x0c\xc0\x00\x0c\xc0\x00\x3c\xf0\x00\xf8\x7f\x00\xe0\x1f\x00\x00'\ -b'\x00\x00\x00\x00\x00\x0b\x00\x30\x00\x00\x30\x00\x00\xf8\xff\x00'\ -b'\xfc\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x30\xe0\x00\x38\xf0\x00'\ -b'\x1c\xd8\x00\x0c\xcc\x00\x0c\xc6\x00\x0c\xc6\x00\x1c\xc3\x00\xf8'\ -b'\xc1\x00\xf0\xc0\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x30\x30\x00'\ -b'\x38\x70\x00\x1c\xe0\x00\x0c\xc0\x00\x8c\xc1\x00\x8c\xc1\x00\x9c'\ -b'\xe3\x00\xf8\x7f\x00\x70\x3e\x00\x00\x00\x00\x00\x00\x00\x0b\x00'\ -b'\x00\x1c\x00\x00\x1b\x00\x80\x18\x00\x60\x18\x00\x30\x18\x00\xfc'\ -b'\xff\x00\xfc\xff\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x0b\x00\xc0\x21\x00\xfc\x61\x00\xbc\xc1\x00\xcc\xc0\x00\xcc'\ -b'\xc0\x00\xcc\xc0\x00\xcc\xe1\x00\x8c\x7f\x00\x00\x1f\x00\x00\x00'\ -b'\x00\x00\x00\x00\x0b\x00\xc0\x1f\x00\xf0\x7f\x00\x38\xe3\x00\x8c'\ -b'\xc1\x00\x8c\xc1\x00\x8c\xc1\x00\x9c\xe3\x00\x38\x7f\x00\x20\x3e'\ -b'\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x0c\x00\x00\x0c\x00\x00\x0c'\ -b'\xc0\x00\x0c\xf8\x00\x0c\x1e\x00\x8c\x03\x00\xec\x00\x00\x3c\x00'\ -b'\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x1c\x00\x70'\ -b'\x7e\x00\xf8\x63\x00\x8c\xc1\x00\x8c\xc1\x00\x8c\xc1\x00\xf8\x63'\ -b'\x00\x70\x7e\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x0b\x00\xf0'\ -b'\x21\x00\xf8\x63\x00\x1c\xe7\x00\x0c\xc6\x00\x0c\xc6\x00\x0c\xc6'\ -b'\x00\x1c\x73\x00\xf8\x3f\x00\xe0\x0f\x00\x00\x00\x00\x00\x00\x00'\ -b'\x05\x00\x60\xc0\x00\x60\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x05\x00\xc0\xc0\x04\xc0\xc0\x03\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x00\x0c\x00\x00\x0c\x00\x00\x1c\x00\x00\x1e\x00\x00\x12\x00'\ -b'\x00\x32\x00\x00\x23\x00\x00\x61\x00\x80\x61\x00\x80\x40\x00\xc0'\ -b'\xc0\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x33\x00\x00\x33\x00'\ -b'\x00\x33\x00\x00\x33\x00\x00\x33\x00\x00\x33\x00\x00\x33\x00\x00'\ -b'\x33\x00\x00\x33\x00\x00\x33\x00\x00\x00\x00\x00\x00\x00\x0c\x00'\ -b'\x80\xc0\x00\x80\x41\x00\x80\x61\x00\x00\x61\x00\x00\x23\x00\x00'\ -b'\x32\x00\x00\x16\x00\x00\x1c\x00\x00\x0c\x00\x00\x0c\x00\x00\x00'\ -b'\x00\x00\x00\x00\x0b\x00\x18\x00\x00\x1c\x00\x00\x06\x00\x00\x06'\ -b'\xcc\x00\x06\xcf\x00\x8e\x01\x00\xfc\x00\x00\x78\x00\x00\x00\x00'\ -b'\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x1f\x00\xe0\x7f\x00\xf0'\ -b'\xe0\x01\x38\x80\x01\x1c\x1f\x03\x8c\x3f\x03\xce\x71\x06\xe6\x60'\ -b'\x06\x66\x60\x06\x66\x30\x06\x66\x38\x06\x86\x7f\x06\xcc\x63\x02'\ -b'\x0c\x60\x00\x18\x70\x00\x78\x38\x00\xf0\x1f\x00\xc0\x07\x00\x00'\ -b'\x00\x00\x00\x00\x00\x0d\x00\x00\x80\x00\x00\xe0\x00\x00\x7c\x00'\ -b'\x80\x1f\x00\xf0\x0d\x00\x3e\x0c\x00\x0e\x0c\x00\x3e\x0c\x00\xf8'\ -b'\x0d\x00\xc0\x0f\x00\x00\x7e\x00\x00\xf0\x00\x00\xc0\x00\x0d\x00'\ -b'\xfe\xff\x00\xfe\xff\x00\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00\x86'\ -b'\xc1\x00\x86\xc1\x00\xce\xc1\x00\x7c\xe3\x00\x78\x7e\x00\x00\x3c'\ -b'\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xe0\x0f\x00\xf8\x3f\x00\x3c'\ -b'\x78\x00\x0c\x60\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0'\ -b'\x00\x06\xc0\x00\x0c\x70\x00\x1c\x78\x00\x10\x18\x00\x00\x00\x00'\ -b'\x00\x00\x00\x0e\x00\xfe\xff\x00\xfe\xff\x00\x06\xc0\x00\x06\xc0'\ -b'\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x0e\xe0\x00\x1c\x70\x00'\ -b'\xf8\x3f\x00\xe0\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d'\ -b'\x00\xfe\xff\x00\xfe\xff\x00\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00'\ -b'\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00\x06\xc0\x00\x00'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\xfe\xff\x00\xfe\xff\x00'\ -b'\x86\x01\x00\x86\x01\x00\x86\x01\x00\x86\x01\x00\x86\x01\x00\x86'\ -b'\x01\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00'\ -b'\xc0\x0f\x00\xf0\x3f\x00\x3c\x78\x00\x0c\x60\x00\x0e\xe0\x00\x06'\ -b'\xc0\x00\x06\xc0\x00\x06\xc3\x00\x06\xc3\x00\x06\x63\x00\x0c\x33'\ -b'\x00\x1c\x7f\x00\x10\xff\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xfe'\ -b'\xff\x00\xfe\xff\x00\x80\x01\x00\x80\x01\x00\x80\x01\x00\x80\x01'\ -b'\x00\x80\x01\x00\x80\x01\x00\x80\x01\x00\xfe\xff\x00\xfe\xff\x00'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\xfe\xff\x00\xfe\xff'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00'\ -b'\x38\x00\x00\x78\x00\x00\xe0\x00\x00\xc0\x00\x00\xc0\x00\x00\xe0'\ -b'\x00\xfe\x7f\x00\xfe\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x0d\x00\xfe\xff\x00\xfe\xff\x00\x00\x03\x00\x80\x01\x00\xc0\x00'\ -b'\x00\xe0\x03\x00\x30\x07\x00\x18\x1c\x00\x0c\x38\x00\x06\xe0\x00'\ -b'\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x0b\x00\xfe\xff\x00\xfe\xff'\ -b'\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00'\ -b'\x00\xc0\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x11\x00\xfe\xff'\ -b'\x00\xfe\xff\x00\x1e\x00\x00\xf8\x00\x00\xc0\x07\x00\x00\x3e\x00'\ -b'\x00\xf0\x00\x00\xe0\x00\x00\x3e\x00\xc0\x07\x00\xf8\x00\x00\x1e'\ -b'\x00\x00\xfe\xff\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x0f\x00\xfe\xff\x00\xfe\xff\x00\x1e\x00\x00\x78\x00\x00\xe0'\ -b'\x00\x00\x80\x03\x00\x00\x0e\x00\x00\x38\x00\x00\xf0\x00\xfe\xff'\ -b'\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ -b'\x10\x00\xc0\x07\x00\xf0\x1f\x00\x38\x38\x00\x0c\x60\x00\x0e\xe0'\ -b'\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x0e\xe0\x00'\ -b'\x0c\x60\x00\x38\x38\x00\xf0\x1f\x00\xe0\x0f\x00\x00\x00\x00\x00'\ -b'\x00\x00\x0d\x00\xfe\xff\x00\xfe\xff\x00\x06\x03\x00\x06\x03\x00'\ -b'\x06\x03\x00\x06\x03\x00\x06\x03\x00\x8e\x03\x00\xfc\x01\x00\xf8'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xc0\x07\x00'\ -b'\xf0\x1f\x00\x38\x38\x00\x0c\x60\x00\x0e\xe0\x00\x06\xc0\x00\x06'\ -b'\xc0\x00\x06\xc0\x00\x06\xd0\x00\x0e\x70\x00\x0c\x60\x00\x38\xf8'\ -b'\x00\xf0\xdf\x01\xe0\x07\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xfe'\ -b'\xff\x00\xfe\xff\x00\x06\x03\x00\x06\x03\x00\x06\x03\x00\x06\x03'\ -b'\x00\x06\x03\x00\x06\x03\x00\x8e\x07\x00\xfc\xfe\x00\x78\xfc\x00'\ -b'\x00\x80\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x78\x18\x00\xfc\x78'\ -b'\x00\xcc\x61\x00\x86\xe1\x00\x86\xc1\x00\x06\xc1\x00\x06\xc3\x00'\ -b'\x06\xc3\x00\x06\xc3\x00\x0c\x66\x00\x1c\x7e\x00\x18\x1c\x00\x00'\ -b'\x00\x00\x0d\x00\x06\x00\x00\x06\x00\x00\x06\x00\x00\x06\x00\x00'\ -b'\xfe\xff\x00\xfe\xff\x00\x06\x00\x00\x06\x00\x00\x06\x00\x00\x06'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xfe\x1f\x00'\ -b'\xfe\x7f\x00\x00\x60\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00'\ -b'\xc0\x00\x00\xc0\x00\x00\x60\x00\xfe\x7f\x00\xfe\x1f\x00\x00\x00'\ -b'\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x02\x00\x00\x0e\x00\x00\x7c'\ -b'\x00\x00\xe0\x03\x00\x00\x1f\x00\x00\xf8\x00\x00\xe0\x00\x00\xf8'\ -b'\x00\x00\x1f\x00\xe0\x03\x00\x7e\x00\x00\x0e\x00\x00\x00\x00\x00'\ -b'\x13\x00\x02\x00\x00\x3e\x00\x00\xfc\x03\x00\xc0\x3f\x00\x00\xf8'\ -b'\x00\x00\xf8\x00\x00\x7f\x00\xf0\x0f\x00\xfe\x00\x00\x1e\x00\x00'\ -b'\xfc\x00\x00\xe0\x0f\x00\x00\x7e\x00\x00\xe0\x00\x00\xfc\x00\xe0'\ -b'\x1f\x00\xfe\x01\x00\x1e\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x00'\ -b'\x02\xc0\x00\x0e\xe0\x00\x1c\x78\x00\x70\x1c\x00\xe0\x07\x00\x80'\ -b'\x03\x00\xc0\x07\x00\x70\x1c\x00\x3c\x38\x00\x0e\xf0\x00\x06\xc0'\ -b'\x00\x00\x80\x00\x0e\x00\x00\x00\x00\x06\x00\x00\x0e\x00\x00\x3c'\ -b'\x00\x00\xf0\x00\x00\xc0\x01\x00\x80\xff\x00\x80\xff\x00\xc0\x01'\ -b'\x00\xf0\x00\x00\x3c\x00\x00\x0e\x00\x00\x06\x00\x00\x00\x00\x00'\ -b'\x0c\x00\x06\xe0\x00\x06\xf0\x00\x06\xdc\x00\x06\xce\x00\x06\xc7'\ -b'\x00\x86\xc3\x00\xe6\xc0\x00\x76\xc0\x00\x3e\xc0\x00\x0e\xc0\x00'\ -b'\x06\xc0\x00\x00\x00\x00\x06\x00\xfe\xff\x0f\xfe\xff\x0f\x06\x00'\ -b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x06\x00\x00\x3c'\ -b'\x00\x00\xe0\x01\x00\x00\x0f\x00\x00\x78\x00\x00\xc0\x00\x06\x00'\ -b'\x06\x00\x0c\xfe\xff\x0f\xfe\xff\x0f\x00\x00\x00\x00\x00\x00\x00'\ -b'\x00\x00\x09\x00\x00\x03\x00\xc0\x01\x00\x78\x00\x00\x0c\x00\x00'\ -b'\x3c\x00\x00\xe0\x00\x00\x80\x03\x00\x00\x00\x00\x00\x00\x00\x0c'\ -b'\x00\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01'\ -b'\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00'\ -b'\x00\x01\x00\x00\x01\x05\x00\x02\x00\x00\x06\x00\x00\x0c\x00\x00'\ -b'\x08\x00\x00\x00\x00\x00\x0b\x00\xc0\x78\x00\xc0\xf8\x00\x60\xcc'\ -b'\x00\x60\xcc\x00\x60\xc4\x00\x60\x44\x00\x60\x64\x00\xc0\x7f\x00'\ -b'\xc0\xff\x00\x00\xc0\x00\x00\x00\x00\x0b\x00\xfe\xff\x00\xfe\xff'\ -b'\x00\xc0\x60\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00'\ -b'\xe0\x60\x00\xc0\x7f\x00\x00\x1f\x00\x00\x00\x00\x0a\x00\x00\x1f'\ -b'\x00\xc0\x7f\x00\xc0\xe0\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00'\ -b'\x60\xe0\x00\xc0\x70\x00\x80\x30\x00\x00\x00\x00\x0b\x00\x00\x1f'\ -b'\x00\xc0\x7f\x00\xe0\xe0\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00'\ -b'\xc0\x60\x00\xfe\xff\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x0b'\ -b'\x00\x00\x1f\x00\xc0\x7f\x00\xe0\xe6\x00\x60\xc6\x00\x60\xc6\x00'\ -b'\x60\xc6\x00\xe0\xe6\x00\xc0\x67\x00\x00\x27\x00\x00\x00\x00\x00'\ -b'\x00\x00\x06\x00\x60\x00\x00\xfc\xff\x00\xfe\xff\x00\x66\x00\x00'\ -b'\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x1f\x02\xc0\x7f\x06\xe0\xe0'\ -b'\x0c\x60\xc0\x0c\x60\xc0\x0c\x60\xc0\x0c\xc0\x60\x0e\xe0\xff\x07'\ -b'\xe0\xff\x03\x00\x00\x00\x00\x00\x00\x0b\x00\xfe\xff\x00\xfe\xff'\ -b'\x00\x80\x00\x00\x60\x00\x00\x60\x00\x00\x60\x00\x00\xe0\x00\x00'\ -b'\xe0\xff\x00\xc0\xff\x00\x00\x00\x00\x00\x00\x00\x04\x00\xe6\xff'\ -b'\x00\xe6\xff\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x0c\x00'\ -b'\x00\x0c\xe6\xff\x0f\xe6\xff\x07\x00\x00\x00\x0a\x00\xfe\xff\x00'\ -b'\xfe\xff\x00\x00\x06\x00\x00\x03\x00\x80\x0f\x00\xc0\x1c\x00\x60'\ -b'\x78\x00\x20\xe0\x00\x00\x80\x00\x00\x00\x00\x04\x00\xfe\xff\x00'\ -b'\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x10\x00\xe0\xff\x00\xe0\xff'\ -b'\x00\xc0\x00\x00\x60\x00\x00\x60\x00\x00\x60\x00\x00\xe0\xff\x00'\ -b'\x80\xff\x00\xc0\x00\x00\x60\x00\x00\x60\x00\x00\x60\x00\x00\xe0'\ -b'\xff\x00\xc0\xff\x00\x00\x00\x00\x00\x00\x00\x0b\x00\xe0\xff\x00'\ -b'\xe0\xff\x00\x80\x00\x00\x40\x00\x00\x60\x00\x00\x60\x00\x00\xe0'\ -b'\x00\x00\xe0\xff\x00\xc0\xff\x00\x00\x00\x00\x00\x00\x00\x0b\x00'\ -b'\x00\x1f\x00\xc0\x7f\x00\xe0\xe0\x00\x60\xc0\x00\x60\xc0\x00\x60'\ -b'\xc0\x00\xe0\xe0\x00\xc0\x7f\x00\x00\x1f\x00\x00\x00\x00\x00\x00'\ -b'\x00\x0b\x00\xe0\xff\x07\xe0\xff\x07\xc0\x60\x00\x60\xc0\x00\x60'\ -b'\xc0\x00\x60\xc0\x00\x60\xc0\x00\xc0\x60\x00\xc0\x7f\x00\x00\x1f'\ -b'\x00\x00\x00\x00\x0b\x00\x00\x1f\x00\xc0\x7f\x00\xe0\xe0\x00\x60'\ -b'\xc0\x00\x60\xc0\x00\x60\xc0\x00\xc0\x60\x00\xe0\xff\x07\xe0\xff'\ -b'\x07\x00\x00\x00\x00\x00\x00\x07\x00\xe0\xff\x00\xe0\xff\x00\xc0'\ -b'\x00\x00\x60\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00'\ -b'\x80\x63\x00\xc0\xe7\x00\x60\xc6\x00\x60\xc6\x00\x60\xcc\x00\x60'\ -b'\xcc\x00\xc0\x7c\x00\xc0\x38\x00\x00\x00\x00\x00\x00\x00\x06\x00'\ -b'\x60\x00\x00\xf8\xff\x00\xf8\xff\x00\x60\xc0\x00\x00\x00\x00\x00'\ -b'\x00\x00\x0b\x00\xe0\x7f\x00\xe0\xff\x00\x00\xe0\x00\x00\xc0\x00'\ -b'\x00\xc0\x00\x00\x40\x00\x00\x20\x00\xe0\xff\x00\xe0\xff\x00\x00'\ -b'\x00\x00\x00\x00\x00\x0a\x00\x20\x00\x00\xe0\x01\x00\xc0\x0f\x00'\ -b'\x00\x7c\x00\x00\xe0\x00\x00\xf0\x00\x00\x3e\x00\xc0\x07\x00\xe0'\ -b'\x00\x00\x20\x00\x00\x0e\x00\x60\x00\x00\xe0\x03\x00\x80\x3f\x00'\ -b'\x00\xf8\x00\x00\xf0\x00\x00\x3f\x00\xe0\x03\x00\xe0\x01\x00\xc0'\ -b'\x1f\x00\x00\xfc\x00\x00\xe0\x00\x00\x7e\x00\xe0\x07\x00\xe0\x00'\ -b'\x00\x0a\x00\x00\x00\x00\x60\xc0\x00\xe0\x60\x00\x80\x3b\x00\x00'\ -b'\x0f\x00\x00\x1f\x00\xc0\x71\x00\xe0\xe0\x00\x20\x80\x00\x00\x00'\ -b'\x00\x0a\x00\x20\x00\x00\xe0\x01\x0c\x80\x0f\x0c\x00\x7c\x0e\x00'\ -b'\xe0\x07\x00\xf0\x00\x00\x1e\x00\xc0\x07\x00\xe0\x00\x00\x00\x00'\ -b'\x00\x0a\x00\x60\xe0\x00\x60\xf0\x00\x60\xd8\x00\x60\xcc\x00\x60'\ -b'\xc6\x00\xe0\xc3\x00\xe0\xc1\x00\x60\xc0\x00\x00\x00\x00\x00\x00'\ -b'\x00\x07\x00\x00\x04\x00\x00\x0e\x00\xfc\xfb\x07\xfe\xfb\x0f\x06'\ -b'\x00\x0c\x00\x00\x00\x00\x00\x00\x05\x00\xfe\xff\x0f\xfe\xff\x0f'\ -b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x06\x00\x0c\xfe\xfb'\ -b'\x0f\xfc\xfb\x07\x00\x0e\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'\ -b'\x0a\x00\x00\x03\x00\x80\x01\x00\x80\x01\x00\x00\x03\x00\x00\x02'\ -b'\x00\x00\x06\x00\x00\x06\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0b\x00\x00\x00\x3c\x00\x7e\x00\xc7\x00\xc3\x00\x03\x00\x03\x00'\ +b'\x06\x00\x0c\x00\x08\x00\x18\x00\x18\x00\x00\x00\x00\x00\x18\x00'\ +b'\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x07\x00\x00\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x00\x00'\ +b'\xc0\xc0\x00\x00\x00\x00\x07\x00\x00\x00\xd8\xd8\xd8\xd8\x90\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00'\ +b'\x00\x00\x0c\xc0\x08\x80\x08\x80\x7f\xe0\x7f\xe0\x19\x80\x11\x00'\ +b'\x11\x00\xff\xc0\xff\xc0\x33\x00\x33\x00\x22\x00\x22\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0b\x00\x08\x00\x3e\x00\x7f\x80\xe9\xc0'\ +b'\xc8\xc0\xc8\xc0\xc8\x00\xe8\x00\x7c\x00\x1f\x80\x09\xc0\x08\xc0'\ +b'\xc8\xc0\xe9\xc0\x7f\x80\x3e\x00\x08\x00\x00\x00\x00\x00\x00\x00'\ +b'\x12\x00\x00\x00\x00\x00\x00\x00\x38\x10\x00\x7c\x10\x00\xc6\x20'\ +b'\x00\xc6\x20\x00\xc6\x40\x00\x7c\xc0\x00\x38\x80\x00\x01\x1e\x00'\ +b'\x01\x3f\x00\x02\x73\x80\x02\x61\x80\x04\x73\x80\x04\x3f\x00\x08'\ +b'\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00'\ +b'\x00\x00\x00\x00\x0e\x00\x1f\x00\x31\x80\x31\x80\x31\x80\x1f\x00'\ +b'\x1c\x00\x76\x60\xe3\x60\xc1\xc0\xc0\xc0\xe1\xc0\x7f\x60\x3e\x30'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\xc0\xc0\xc0\xc0'\ +b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00'\ +b'\x00\x10\x10\x20\x20\x60\x40\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x40\x60'\ +b'\x20\x30\x10\x18\x07\x00\x00\x40\x40\x20\x20\x30\x10\x18\x18\x18'\ +b'\x18\x18\x18\x18\x10\x30\x20\x60\x40\xc0\x08\x00\x00\x20\x20\xf8'\ +b'\x20\x50\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x18\x00\x18\x00\x18\x00\xff\x00\xff\x00\x18\x00\x18\x00\x18\x00'\ +b'\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xc0\x40\x40\x80\x00'\ +b'\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xf8\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x06\x00\x00\x04'\ +b'\x0c\x08\x08\x18\x10\x10\x30\x20\x20\x60\x40\x40\xc0\x80\x00\x00'\ +b'\x00\x00\x0b\x00\x00\x00\x00\x00\x3e\x00\x7f\x00\x63\x00\xe3\x80'\ +b'\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xe3\x80\x63\x00'\ +b'\x7f\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00'\ +b'\x00\x00\x10\x00\x30\x00\xf0\x00\xf0\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x3e\x00\x7f\x00'\ +b'\xe3\x80\xc1\x80\x01\x80\x01\x80\x03\x00\x0e\x00\x1c\x00\x30\x00'\ +b'\x60\x00\xc0\x00\xff\x80\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0b\x00\x00\x00\x00\x00\x3e\x00\x7f\x00\xe3\x80\xc1\x80\x01\x80'\ +b'\x0f\x00\x0f\x00\x03\x80\x01\x80\x01\x80\xc1\x80\xe3\x80\x7f\x00'\ +b'\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00'\ +b'\x06\x00\x06\x00\x0e\x00\x1e\x00\x16\x00\x26\x00\x46\x00\x46\x00'\ +b'\x86\x00\xff\x00\xff\x00\x06\x00\x06\x00\x06\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x7f\x00\x7f\x00\x60\x00'\ +b'\x60\x00\xde\x00\xff\x00\xe3\x80\x01\x80\x01\x80\x01\x80\x01\x80'\ +b'\xc3\x00\x7f\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00'\ +b'\x00\x00\x00\x00\x1e\x00\x3f\x00\x63\x00\x61\x80\xc0\x00\xde\x00'\ +b'\xff\x00\xe3\x80\xc1\x80\xc1\x80\xc1\x80\x63\x80\x7f\x00\x3e\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\xff\x80'\ +b'\xff\x80\x01\x00\x03\x00\x02\x00\x06\x00\x04\x00\x0c\x00\x08\x00'\ +b'\x18\x00\x18\x00\x10\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0b\x00\x00\x00\x00\x00\x1c\x00\x3e\x00\x63\x00\x63\x00'\ +b'\x63\x00\x3e\x00\x3e\x00\x63\x00\xc1\x80\xc1\x80\xc1\x80\x63\x00'\ +b'\x7f\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00'\ +b'\x00\x00\x3e\x00\x7f\x00\xe3\x00\xc1\x80\xc1\x80\xc1\x80\xe3\x80'\ +b'\x7f\x80\x3d\x80\x01\x80\x03\x00\xe3\x00\x7e\x00\x3c\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\xc0\xc0\x00'\ +b'\x00\x00\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x05\x00\x00\x00'\ +b'\x00\x00\x00\x00\xc0\xc0\x00\x00\x00\x00\x00\x00\xc0\xc0\x40\x40'\ +b'\x80\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x40\x01\xc0\x07\x00\x3c\x00\xe0\x00\xe0\x00\x78\x00\x0f\x00'\ +b'\x03\xc0\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc0'\ +b'\xff\xc0\x00\x00\x00\x00\xff\xc0\xff\xc0\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\xe0\x00\x78\x00\x0e\x00\x03\xc0\x01\xc0'\ +b'\x07\x00\x3c\x00\xf0\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0b\x00\x00\x00\x3c\x00\x7e\x00\xc7\x00\xc3\x00\x03\x00\x03\x00'\ +b'\x06\x00\x0c\x00\x08\x00\x18\x00\x18\x00\x00\x00\x00\x00\x18\x00'\ +b'\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x03'\ +b'\xf0\x00\x0f\xfc\x00\x1e\x0f\x00\x38\x03\x80\x71\xe1\x80\x63\xe9'\ +b'\xc0\x67\x18\xc0\xce\x18\xc0\xcc\x18\xc0\xcc\x10\xc0\xcc\x31\x80'\ +b'\xce\x73\x80\x67\xff\x00\x63\x9e\x00\x30\x00\x00\x3c\x00\x00\x0f'\ +b'\xf8\x00\x03\xf0\x00\x00\x00\x00\x0d\x00\x00\x00\x07\x00\x07\x00'\ +b'\x07\x80\x0d\x80\x0d\x80\x08\xc0\x18\xc0\x18\xc0\x10\x60\x3f\xe0'\ +b'\x3f\xe0\x30\x30\x60\x30\x60\x38\xc0\x18\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0d\x00\x00\x00\xff\x00\xff\x80\xc1\xc0\xc0\xc0\xc0\xc0'\ +b'\xc1\xc0\xff\x00\xff\x80\xc0\xc0\xc0\x60\xc0\x60\xc0\x60\xc0\xe0'\ +b'\xff\xc0\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00'\ +b'\x0f\x80\x3f\xe0\x70\x60\x60\x30\xe0\x00\xc0\x00\xc0\x00\xc0\x00'\ +b'\xc0\x00\xc0\x00\xe0\x30\x60\x70\x70\x60\x3f\xe0\x0f\x80\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\xff\x00\xff\x80\xc1\xc0'\ +b'\xc0\xc0\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60'\ +b'\xc0\xc0\xc1\xc0\xff\x80\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0d\x00\x00\x00\xff\xc0\xff\xc0\xc0\x00\xc0\x00\xc0\x00\xc0\x00'\ +b'\xff\x80\xff\x80\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xff\xc0'\ +b'\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\xff\x80'\ +b'\xff\x80\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xff\x00\xff\x00\xc0\x00'\ +b'\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\xc0\x3f\xf0\x38\x30\x60\x18'\ +b'\x60\x00\xc0\x00\xc0\x00\xc1\xf8\xc1\xf8\xc0\x18\xe0\x18\x60\x38'\ +b'\x78\x78\x3f\xd8\x0f\x88\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00'\ +b'\x00\x00\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xff\xe0'\ +b'\xff\xe0\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\xc0\xc0\xc0\xc0\xc0'\ +b'\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x00\x00\x00\x00\x0b\x00'\ +b'\x00\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00'\ +b'\x03\x00\x03\x00\x03\x00\xc3\x00\xc3\x00\xe7\x00\x7e\x00\x3c\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\xc0\x60\xc0\xc0'\ +b'\xc1\x80\xc3\x00\xc6\x00\xcc\x00\xdc\x00\xf6\x00\xe6\x00\xc3\x00'\ +b'\xc1\x80\xc1\x80\xc0\xc0\xc0\x60\xc0\x60\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0b\x00\x00\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00'\ +b'\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00'\ +b'\xff\x80\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00'\ +b'\x00\xe0\x1c\x00\xe0\x1c\x00\xf0\x3c\x00\xf0\x3c\x00\xd0\x2c\x00'\ +b'\xd8\x6c\x00\xd8\x6c\x00\xc8\x4c\x00\xcc\xcc\x00\xcc\xcc\x00\xc4'\ +b'\x8c\x00\xc6\x8c\x00\xc7\x8c\x00\xc3\x0c\x00\xc3\x0c\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\xe0\x60'\ +b'\xe0\x60\xf0\x60\xf0\x60\xd8\x60\xd8\x60\xcc\x60\xc4\x60\xc6\x60'\ +b'\xc2\x60\xc3\x60\xc1\xe0\xc1\xe0\xc0\xe0\xc0\xe0\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x10\x00\x00\x00\x0f\xc0\x1f\xe0\x38\x70\x60\x18'\ +b'\x60\x1c\xc0\x0c\xc0\x0c\xc0\x0c\xc0\x0c\xc0\x0c\x60\x1c\x60\x18'\ +b'\x38\x70\x1f\xe0\x0f\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00'\ +b'\x00\x00\xff\x00\xff\x80\xc1\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc1\xc0'\ +b'\xff\x80\xff\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x0f\xc0\x1f\xe0'\ +b'\x38\x70\x60\x18\x60\x1c\xc0\x0c\xc0\x0c\xc0\x0c\xc0\x0c\xc0\x0c'\ +b'\x60\x18\x60\xd8\x38\x70\x1f\xf8\x0f\x98\x00\x08\x00\x00\x00\x00'\ +b'\x00\x00\x0e\x00\x00\x00\xff\x80\xff\xc0\xc0\xe0\xc0\x60\xc0\x60'\ +b'\xc0\x60\xc0\xc0\xff\x80\xff\xc0\xc0\xe0\xc0\x60\xc0\x60\xc0\x60'\ +b'\xc0\x60\xc0\x70\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00'\ +b'\x1f\x80\x7f\xe0\xe0\x70\xc0\x30\xc0\x00\xe0\x00\x78\x00\x3f\x80'\ +b'\x03\xe0\x00\x70\xc0\x30\xc0\x30\x70\x60\x7f\xe0\x1f\x80\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\xff\xc0\xff\xc0\x0c\x00'\ +b'\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00'\ +b'\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0e\x00\x00\x00\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60'\ +b'\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\xc0\x60\x60\xc0\x7f\xc0'\ +b'\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\xc0\x30'\ +b'\x60\x30\x60\x30\x20\x20\x30\x60\x30\x60\x10\x40\x18\xc0\x18\xc0'\ +b'\x08\x80\x0d\x80\x0d\x80\x07\x00\x07\x00\x07\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x13\x00\x00\x00\x00\xc0\xc0\xc0\x60\xe0\xc0\x60'\ +b'\xe0\xc0\x61\xe0\xc0\x61\xb1\x80\x31\xb1\x80\x31\xb1\x80\x33\x11'\ +b'\x80\x33\x19\x00\x13\x1b\x00\x1f\x1b\x00\x1e\x0b\x00\x1e\x0e\x00'\ +b'\x0e\x0e\x00\x0c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0d\x00\x00\x00\x60\x30\x30\x70\x30\x60\x18\xc0\x0c\xc0'\ +b'\x0d\x80\x07\x00\x07\x00\x07\x00\x0d\x80\x18\xc0\x18\xe0\x30\x60'\ +b'\x70\x30\x60\x38\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00'\ +b'\x60\x18\x70\x38\x30\x30\x18\x60\x18\x60\x0c\xc0\x0f\xc0\x07\x80'\ +b'\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\xff\xe0\xff\xe0\x00\xc0'\ +b'\x01\x80\x03\x80\x03\x00\x06\x00\x0c\x00\x1c\x00\x38\x00\x30\x00'\ +b'\x60\x00\xc0\x00\xff\xe0\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x06\x00\x00\xe0\xe0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0'\ +b'\xc0\xc0\xc0\xc0\xe0\xe0\x06\x00\x00\x80\xc0\x40\x40\x60\x20\x20'\ +b'\x30\x10\x10\x18\x08\x08\x0c\x04\x00\x00\x00\x00\x06\x00\x00\xe0'\ +b'\xe0\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60'\ +b'\xe0\xe0\x09\x00\x00\x00\x00\x00\x18\x00\x38\x00\x28\x00\x2c\x00'\ +b'\x64\x00\x46\x00\xc2\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\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\xff\xf0'\ +b'\x00\x00\x00\x00\x00\x00\x05\x00\x00\xc0\x60\x30\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x3e\x00\xff\x80\xc1\x80\x01\x80'\ +b'\x01\x80\x3f\x80\xf1\x80\xc1\x80\xc3\x80\xff\xc0\x78\xc0\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\xc0\x00\xc0\x00\xc0\x00'\ +b'\xc0\x00\xdf\x00\xff\x80\xe1\x80\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0'\ +b'\xc0\xc0\xe1\x80\xff\x80\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x7f\x00'\ +b'\x61\x80\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc1\x80\x63\x80\x7f\x00'\ +b'\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x01\x80'\ +b'\x01\x80\x01\x80\x01\x80\x3d\x80\x7f\x80\x63\x80\xc1\x80\xc1\x80'\ +b'\xc1\x80\xc1\x80\xc1\x80\x63\x80\x7f\x80\x3d\x80\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x3e\x00\x7f\x00\x63\x00\xc1\x80\xff\x80\xff\x80\xc0\x00\xc0\x00'\ +b'\x63\x80\x7f\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00'\ +b'\x00\x30\x70\x60\x60\xf0\xf0\x60\x60\x60\x60\x60\x60\x60\x60\x60'\ +b'\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x3d\x80\x7f\x80\x63\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80'\ +b'\x63\x80\x7f\x80\x3d\x80\x01\x80\xc3\x80\x7f\x00\x3e\x00\x0b\x00'\ +b'\x00\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xdf\x00\xdf\x80\xe3\x80'\ +b'\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\xc0\xc0\x00\x00\xc0'\ +b'\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x00\x00\x00\x00\x05\x00'\ +b'\x00\x30\x30\x00\x00\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30'\ +b'\x30\x30\xf0\xe0\x0a\x00\x00\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00'\ +b'\xc3\x00\xc6\x00\xcc\x00\xd8\x00\xf8\x00\xec\x00\xce\x00\xc6\x00'\ +b'\xc3\x00\xc3\x00\xc1\x80\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00'\ +b'\x00\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0'\ +b'\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\xde\x78\xfe\xfc\xe3\x8c\xc3\x0c\xc3\x0c\xc3\x0c\xc3\x0c\xc3\x0c'\ +b'\xc3\x0c\xc3\x0c\xc3\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\x00\xdf\x80\xe3\x80'\ +b'\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xc1\x80'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x3e\x00\x7f\x00\x63\x00\xc1\x80\xc1\x80\xc1\x80'\ +b'\xc1\x80\xc1\x80\x63\x00\x7f\x00\x3e\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\x00'\ +b'\xff\x80\xe1\x80\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xe1\x80'\ +b'\xff\x80\xde\x00\xc0\x00\xc0\x00\xc0\x00\x00\x00\x0b\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x3d\x80\x7f\x80\x63\x80\xc1\x80'\ +b'\xc1\x80\xc1\x80\xc1\x80\xc1\x80\x63\x80\x7f\x80\x3d\x80\x01\x80'\ +b'\x01\x80\x01\x80\x00\x00\x07\x00\x00\x00\x00\x00\x00\xd8\xf8\xe0'\ +b'\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x00\x00\x00\x00\x0a\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x00\x7f\x00\xc3\x00\xc0\x00'\ +b'\xf0\x00\x7e\x00\x0f\x00\x03\x00\xc3\x00\xfe\x00\x7c\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x60\x60\xf0\xf0\x60'\ +b'\x60\x60\x60\x60\x60\x60\x70\x70\x00\x00\x00\x00\x0b\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x80\xc1\x80\xc1\x80\xc1\x80'\ +b'\xc1\x80\xc1\x80\xc1\x80\xc1\x80\xe3\x80\xfd\x80\x79\x80\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\xc0\xc0\x61\x80\x61\x80\x61\x00\x23\x00\x33\x00\x32\x00'\ +b'\x16\x00\x1e\x00\x1c\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\x0c\xc3\x8c'\ +b'\x63\x8c\x67\x88\x66\x98\x24\xd8\x34\xd0\x3c\xd0\x3c\x70\x18\x70'\ +b'\x18\x60\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x61\x80\x63\x00\x33\x00\x1e\x00\x1c\x00'\ +b'\x0c\x00\x1c\x00\x16\x00\x33\x00\x63\x00\x41\x80\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\xc0\x80\x41\x80\x61\x80\x61\x00\x23\x00\x33\x00\x32\x00\x16\x00'\ +b'\x1c\x00\x1c\x00\x0c\x00\x08\x00\x18\x00\x78\x00\x70\x00\x0a\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\xff\x00\x06\x00'\ +b'\x06\x00\x0c\x00\x18\x00\x30\x00\x60\x00\xc0\x00\xff\x00\xff\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x18\x38\x30\x30\x30'\ +b'\x30\x30\x30\x70\xc0\x70\x30\x30\x30\x30\x30\x30\x38\x18\x05\x00'\ +b'\x00\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0'\ +b'\xc0\xc0\xc0\xc0\x07\x00\x00\xc0\xe0\x60\x60\x60\x60\x60\x60\x70'\ +b'\x18\x70\x60\x60\x60\x60\x60\x60\xe0\xc0\x0a\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\xf1\x00\x9f\x00'\ +b'\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00' _index =\ -b'\x00\x00\x11\x00\x28\x00\x3f\x00\x62\x00\x85\x00\xbd\x00\xe6\x00'\ -b'\xf4\x00\x0b\x01\x22\x01\x3c\x01\x62\x01\x76\x01\x8d\x01\x9e\x01'\ -b'\xb2\x01\xd5\x01\xf8\x01\x1b\x02\x3e\x02\x61\x02\x84\x02\xa7\x02'\ -b'\xca\x02\xed\x02\x10\x03\x21\x03\x32\x03\x58\x03\x7e\x03\xa4\x03'\ -b'\xc7\x03\x05\x04\x2e\x04\x57\x04\x83\x04\xaf\x04\xd8\x04\xfe\x04'\ -b'\x2d\x05\x59\x05\x6d\x05\x90\x05\xb9\x05\xdc\x05\x11\x06\x40\x06'\ -b'\x72\x06\x9b\x06\xcd\x06\xf9\x06\x22\x07\x4b\x07\x77\x07\xa0\x07'\ -b'\xdb\x07\x04\x08\x30\x08\x56\x08\x6a\x08\x7e\x08\x92\x08\xaf\x08'\ -b'\xd5\x08\xe6\x08\x09\x09\x2c\x09\x4c\x09\x6f\x09\x92\x09\xa6\x09'\ -b'\xc9\x09\xec\x09\xfa\x09\x0b\x0a\x2b\x0a\x39\x0a\x6b\x0a\x8e\x0a'\ -b'\xb1\x0a\xd4\x0a\xf7\x0a\x0e\x0b\x2e\x0b\x42\x0b\x65\x0b\x85\x0b'\ -b'\xb1\x0b\xd1\x0b\xf1\x0b\x11\x0c\x28\x0c\x39\x0c\x50\x0c\x70\x0c'\ - +b'\x00\x00\x2a\x00\x40\x00\x56\x00\x6c\x00\x96\x00\xc0\x00\xfe\x00'\ +b'\x28\x01\x3e\x01\x54\x01\x6a\x01\x80\x01\xaa\x01\xc0\x01\xd6\x01'\ +b'\xec\x01\x02\x02\x2c\x02\x56\x02\x80\x02\xaa\x02\xd4\x02\xfe\x02'\ +b'\x28\x03\x52\x03\x7c\x03\xa6\x03\xbc\x03\xd2\x03\xfc\x03\x26\x04'\ +b'\x50\x04\x7a\x04\xb8\x04\xe2\x04\x0c\x05\x36\x05\x60\x05\x8a\x05'\ +b'\xb4\x05\xde\x05\x08\x06\x1e\x06\x48\x06\x72\x06\x9c\x06\xda\x06'\ +b'\x04\x07\x2e\x07\x58\x07\x82\x07\xac\x07\xd6\x07\x00\x08\x2a\x08'\ +b'\x54\x08\x92\x08\xbc\x08\xe6\x08\x10\x09\x26\x09\x3c\x09\x52\x09'\ +b'\x7c\x09\xa6\x09\xbc\x09\xe6\x09\x10\x0a\x3a\x0a\x64\x0a\x8e\x0a'\ +b'\xa4\x0a\xce\x0a\xf8\x0a\x0e\x0b\x24\x0b\x4e\x0b\x64\x0b\x8e\x0b'\ +b'\xb8\x0b\xe2\x0b\x0c\x0c\x36\x0c\x4c\x0c\x76\x0c\x8c\x0c\xb6\x0c'\ +b'\xe0\x0c\x0a\x0d\x34\x0d\x5e\x0d\x88\x0d\x9e\x0d\xb4\x0d\xca\x0d'\ +b'\xf4\x0d' +_mvfont = memoryview(_font) def _chr_addr(ordch): offset = 2 * (ordch - 32) @@ -240,9 +272,9 @@ def _chr_addr(ordch): def get_ch(ch): ordch = ord(ch) - ordch = ordch if ordch >= 32 and ordch <= 126 else ord('?') + ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 offset = _chr_addr(ordch) width = int.from_bytes(_font[offset:offset + 2], 'little') next_offs = _chr_addr(ordch +1) - return memoryview(_font[offset + 2:next_offs]), 20, width + return _mvfont[offset + 2:next_offs], 20, width diff --git a/SSD1306/ssd1306_test.py b/SSD1306/ssd1306_test.py index 17ab102..b524ede 100644 --- a/SSD1306/ssd1306_test.py +++ b/SSD1306/ssd1306_test.py @@ -70,9 +70,10 @@ else: # I2C #wri = Writer(ssd, freeserif19) wri2 = Writer(ssd, freesans20) Writer.set_clip(True, True) +#Writer.set_textpos(20, 20) +#wri2.printstring('Tues') wri2.printstring('Tuesday\n') wri2.printstring('8 Nov 2016\n') wri2.printstring('10.30am') ssd.show() - diff --git a/SSD1306/writer.py b/SSD1306/writer.py index 2b9040d..1a928fc 100644 --- a/SSD1306/writer.py +++ b/SSD1306/writer.py @@ -27,6 +27,7 @@ # Multiple Writer instances may be created, each rendering a font to the # same Display object. +import framebuf class Writer(object): text_row = 0 # attributes common to all Writer instances @@ -48,8 +49,12 @@ class Writer(object): super().__init__() self.device = device self.font = font + # Allow to work with any font mapping if font.hmap(): - raise OSError('Font must be vertically mapped') + self.map = framebuf.MHMSB if font.reverse() else framebuf.MHLSB + else: + raise ValueError('Font must be horizontally mapped.') + print('Orientation: {} Reversal: {}'.format('horiz' if font.hmap() else 'vert', font.reverse())) self.screenwidth = device.width # In pixels self.screenheight = device.height @@ -67,7 +72,31 @@ class Writer(object): for char in string: self._printchar(char) + # Method using blitting. Efficient rendering for monochrome displays. + # Tested on SSD1306. def _printchar(self, char): + if char == '\n': + self._newline() + return + glyph, char_height, char_width = self.font.get_ch(char) + if Writer.text_row + char_height > self.screenheight: + if Writer.row_clip: + return + self._newline() + if Writer.text_col + char_width > self.screenwidth: + if Writer.col_clip: + return + else: + self._newline() + buf = bytearray(glyph) + fbc = framebuf.FrameBuffer(buf, char_width, char_height, self.map) + self.device.framebuf.blit(fbc, Writer.text_col, Writer.text_row) + Writer.text_col += char_width + + # Bitwise rendering. Currently this is required for colour displays + # because the framebuf blit method does not have an effective means of + # colour mapping single bit framebufs onto n-bit ones + def _printchar_bitwise(self, char): if char == '\n': self._newline() return @@ -97,3 +126,4 @@ class Writer(object): device.pixel(dcol, drow, data & (1 << gbit)) drow += 1 Writer.text_col += char_width + diff --git a/data_to_py/data_to_py.py b/data_to_py/data_to_py.py new file mode 100755 index 0000000..da60490 --- /dev/null +++ b/data_to_py/data_to_py.py @@ -0,0 +1,153 @@ +#! /usr/bin/python3 +# -*- coding: utf-8 -*- + +# The MIT License (MIT) +# +# Copyright (c) 2016 Peter Hinch +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import argparse +import sys +import os + +# UTILITIES FOR WRITING PYTHON SOURCECODE TO A FILE + +# ByteWriter takes as input a variable name and data values and writes +# Python source to an output stream of the form +# my_variable = b'\x01\x02\x03\x04\x05\x06\x07\x08'\ + +# Lines are broken with \ for readability. + + +class ByteWriter(object): + bytes_per_line = 16 + + def __init__(self, stream, varname): + self.stream = stream + self.stream.write('{} =\\\n'.format(varname)) + self.bytecount = 0 # For line breaks + + def _eol(self): + self.stream.write("'\\\n") + + def _eot(self): + self.stream.write("'\n") + + def _bol(self): + self.stream.write("b'") + + # Output a single byte + def obyte(self, data): + if not self.bytecount: + self._bol() + self.stream.write('\\x{:02x}'.format(data)) + self.bytecount += 1 + self.bytecount %= self.bytes_per_line + if not self.bytecount: + self._eol() + + # Output from a sequence + def odata(self, bytelist): + for byt in bytelist: + self.obyte(byt) + + # ensure a correct final line + def eot(self): # User force EOL if one hasn't occurred + if self.bytecount: + self._eot() + self.stream.write('\n') + + +# PYTHON FILE WRITING + +STR01 = """# Code generated by data_to_py.py. +version = '0.1' +""" + +STR02 = """_mvdata = memoryview(_data) + +def data(): + return _mvdata + +""" + +def write_func(stream, name, arg): + stream.write('def {}():\n return {}\n\n'.format(name, arg)) + + +def write_data(op_path, ip_path): + try: + with open(ip_path, 'rb') as ip_stream: + try: + with open(op_path, 'w') as op_stream: + write_stream(ip_stream, op_stream) + except OSError: + print("Can't open", op_path, 'for writing') + return False + except OSError: + print("Can't open", ip_path) + return False + return True + + +def write_stream(ip_stream, op_stream): + op_stream.write(STR01) + op_stream.write('\n') + data = ip_stream.read() + bw_data = ByteWriter(op_stream, '_data') + bw_data.odata(data) + bw_data.eot() + op_stream.write(STR02) + + +# PARSE COMMAND LINE ARGUMENTS + +def quit(msg): + print(msg) + sys.exit(1) + +DESC = """data_to_py.py +Utility to convert an arbitrary binary file to Python source. +Sample usage: +data_to_py.py image.jpg image.py + +""" + +if __name__ == "__main__": + parser = argparse.ArgumentParser(__file__, description=DESC, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('infile', type=str, help='Input file path') + parser.add_argument('outfile', type=str, + help='Path and name of output file. Must have .py extension.') + + + args = parser.parse_args() + + if not os.path.isfile(args.infile): + quit("Data filename does not exist") + + if not os.path.splitext(args.outfile)[1].upper() == '.PY': + quit('Output filename must have a .py extension.') + + print('Writing Python file.') + if not write_data(args.outfile, args.infile): + sys.exit(1) + + print(args.outfile, 'written successfully.')