From b508f4dc266be0c5142faf8089be09e9924e28f1 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Wed, 19 Feb 2020 19:47:51 +0000 Subject: [PATCH] wasp: Add a simple font renderer --- .gitmodules | 3 + tools/micropython-font-to-py | 1 + wasp/boards/pinetime/manifest.py | 2 + wasp/demo.py | 17 +- wasp/draw565.py | 91 ++++++++ wasp/drivers/st7789.py | 4 + wasp/fonts/LICENSE | 192 ++++++++++++++++ wasp/fonts/sans24.py | 368 +++++++++++++++++++++++++++++++ 8 files changed, 677 insertions(+), 1 deletion(-) create mode 160000 tools/micropython-font-to-py create mode 100644 wasp/draw565.py create mode 100644 wasp/fonts/LICENSE create mode 100644 wasp/fonts/sans24.py diff --git a/.gitmodules b/.gitmodules index 3e11eb3..cc94518 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "tools/pynus"] path = tools/pynus url = https://github.com/aykevl/pynus +[submodule "tools/micropython-font-to-py"] + path = tools/micropython-font-to-py + url = https://github.com/peterhinch/micropython-font-to-py diff --git a/tools/micropython-font-to-py b/tools/micropython-font-to-py new file mode 160000 index 0000000..5975b35 --- /dev/null +++ b/tools/micropython-font-to-py @@ -0,0 +1 @@ +Subproject commit 5975b3588366d118dbbc005bf04549f24026f406 diff --git a/wasp/boards/pinetime/manifest.py b/wasp/boards/pinetime/manifest.py index b82aa24..2d8aeae 100644 --- a/wasp/boards/pinetime/manifest.py +++ b/wasp/boards/pinetime/manifest.py @@ -4,12 +4,14 @@ freeze('../..', 'boot.py', 'clock.py', 'demo.py', + 'draw565.py', 'drivers/battery.py', 'drivers/nrf_rtc.py', 'drivers/signal.py', 'drivers/st7789.py', 'drivers/vibrator.py', 'fonts/clock.py', + 'fonts/sans24.py', 'icons.py', 'logo.py', 'manager.py', diff --git a/wasp/demo.py b/wasp/demo.py index d901fcc..66cc0c8 100644 --- a/wasp/demo.py +++ b/wasp/demo.py @@ -7,7 +7,7 @@ # len(colors) is not a multiple of 5 ;-) ). # -import watch, logo, time, gc +import watch, logo, time, gc, draw565 colors = ( 0xffff, @@ -24,6 +24,18 @@ colors = ( 0xf81f, # magenta ) +draw = draw565.Draw565(watch.display) + +def textdemo(): + watch.display.fill(0) + draw.string("The quick brown", 12, 24) + draw.string("fox jumped over", 12, 48) + draw.string("the lazy dog.", 12, 72) + time.sleep(2) + draw.string("0123456789", 12, 120) + draw.string('!"£$%^&*()', 12, 144) + time.sleep(3) + def run(): l = logo.pine64 i = 0 @@ -33,6 +45,8 @@ def run(): while True: for c in colors: + if i == 2: + textdemo() if i < 5: i += 1 else: @@ -46,3 +60,4 @@ def run(): watch.display.rleblit(l, fg=c) time.sleep(2) gc.collect() + diff --git a/wasp/draw565.py b/wasp/draw565.py new file mode 100644 index 0000000..4c5f25f --- /dev/null +++ b/wasp/draw565.py @@ -0,0 +1,91 @@ +import fonts.sans24 +import micropython + +@micropython.viper +def bitblit(bitbuf, pixels, bgfg: int, count: int): + mv = ptr8(bitbuf) + px = ptr8(pixels) + + bghi = (bgfg >> 24) & 0xff + bglo = (bgfg >> 16) & 0xff + fghi = (bgfg >> 8) & 0xff + fglo = (bgfg ) & 0xff + + bitselect = 0x80 + pxp = 0 + mvp = 0 + + for bit in range(count): + # Draw the pixel + active = px[pxp] & bitselect + mv[mvp] = fghi if active else bghi + mvp += 1 + mv[mvp] = fglo if active else bglo + mvp += 1 + + # Advance to the next bit + bitselect >>= 1 + if not bitselect: + bitselect = 0x80 + pxp += 1 + +def bounding_box(s, font): + w = 0 + for ch in s: + (_, h, wc) = font.get_ch(ch) + w += wc + 1 + + return (w, h) + +def draw_glyph(display, glyph, x, y, bgfg): + (px, h, w) = glyph + + buf = memoryview(display.linebuffer)[0:2*(w+1)] + bytes_per_row = (w + 7) // 8 + + for row in range(h): + bitblit(buf, px[row*bytes_per_row:], bgfg, w) + buf[2*w] = 0 + buf[2*w + 1] = 0 + display.rawblit(buf, x, y+row, w+1, 1) + +class Draw565(object): + def __init__(self, display): + self._display = display + self.set_color(0xffff) + self.set_font(fonts.sans24) + + def set_color(self, color, bg=0): + self._bgfg = (bg << 16) + color + + def set_font(self, font): + self._font = font + + def string(self, s, x, y, width=None): + display = self._display + bgfg = self._bgfg + font = self._font + + if width: + (w, h) = bounding_box(s, font) + leftpad = (width - w) // 2 + rightpad = width - w - leftpad + display.fill(0, x, y, leftpad, h) + x += leftpad + + for ch in s: + glyph = font.get_ch(ch) + draw_glyph(display, glyph, x, y, bgfg) + x += glyph[2] + 1 + + if width: + display.fill(0, x, y, rightpad, h) + +#import watch +#draw = Draw(watch.display) +# +#def test(): +# watch.display.poweron() +# watch.backlight.set(2) +# +# draw.string('10-Jan-2020', 0, 24, width=240) diff --git a/wasp/drivers/st7789.py b/wasp/drivers/st7789.py index 1ec1ed4..d57c09b 100644 --- a/wasp/drivers/st7789.py +++ b/wasp/drivers/st7789.py @@ -93,6 +93,10 @@ class ST7789(object): self.write_data(bytearray([y >> 8, y & 0xff, yp >> 8, yp & 0xff])) self.write_cmd(_RAMWR) + def rawblit(self, buf, x, y, width, height): + self.set_window(x, y, width, height) + self.write_data(buf) + def fill(self, bg, x=0, y=0, w=None, h=None): if not w: w = self.width - x diff --git a/wasp/fonts/LICENSE b/wasp/fonts/LICENSE new file mode 100644 index 0000000..76b5662 --- /dev/null +++ b/wasp/fonts/LICENSE @@ -0,0 +1,192 @@ +The following license applies to the Font Software that was used to +generate clock.py and all files that match `git grep 'Font: DejaVu'`. + +--- + +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +TeX Gyre DJV Math +----------------- +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. + +Math extensions done by B. Jackowski, P. Strzelczyk and P. Pianowski +(on behalf of TeX users groups) are in public domain. + +Letters imported from Euler Fraktur from AMSfonts are (c) American +Mathematical Society (see below). +Bitstream Vera Fonts Copyright +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera +is a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license (“Fonts”) and associated +documentation +files (the “Font Software”), to reproduce and distribute the Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, +and/or sell copies of the Font Software, and to permit persons to whom +the Font Software is furnished to do so, subject to the following +conditions: + +The above copyright and trademark notices and this permission notice +shall be +included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional +glyphs or characters may be added to the Fonts, only if the fonts are +renamed +to names not containing either the words “Bitstream” or the word “Vera”. + +This License becomes null and void to the extent applicable to Fonts or +Font Software +that has been modified and is distributed under the “Bitstream Vera” +names. + +The Font Software may be sold as part of a larger software package but +no copy +of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, +SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN +ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR +INABILITY TO USE +THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. +Except as contained in this notice, the names of GNOME, the GNOME +Foundation, +and Bitstream Inc., shall not be used in advertising or otherwise to promote +the sale, use or other dealings in this Font Software without prior written +authorization from the GNOME Foundation or Bitstream Inc., respectively. +For further information, contact: fonts at gnome dot org. + +AMSFonts (v. 2.2) copyright + +The PostScript Type 1 implementation of the AMSFonts produced by and +previously distributed by Blue Sky Research and Y&Y, Inc. are now freely +available for general use. This has been accomplished through the +cooperation +of a consortium of scientific publishers with Blue Sky Research and Y&Y. +Members of this consortium include: + +Elsevier Science IBM Corporation Society for Industrial and Applied +Mathematics (SIAM) Springer-Verlag American Mathematical Society (AMS) + +In order to assure the authenticity of these fonts, copyright will be +held by +the American Mathematical Society. This is not meant to restrict in any way +the legitimate use of the fonts, such as (but not limited to) electronic +distribution of documents containing these fonts, inclusion of these fonts +into other public domain or commercial font collections or computer +applications, use of the outline data to create derivative fonts and/or +faces, etc. However, the AMS does require that the AMS copyright notice be +removed from any derivative versions of the fonts which have been altered in +any way. In addition, to ensure the fidelity of TeX documents using Computer +Modern fonts, Professor Donald Knuth, creator of the Computer Modern faces, +has requested that any alterations which yield different font metrics be +given a different name. + +$Id$ diff --git a/wasp/fonts/sans24.py b/wasp/fonts/sans24.py new file mode 100644 index 0000000..2fdb6f2 --- /dev/null +++ b/wasp/fonts/sans24.py @@ -0,0 +1,368 @@ +# Code generated by font_to_py.py. +# Font: DejaVuSans.ttf +# Cmd: tools/micropython-font-to-py/font_to_py.py /usr/share/fonts/dejavu/DejaVuSans.ttf --xmap 24 wasp/fonts/sans24.py +version = '0.33' + +def height(): + return 24 + +def baseline(): + return 18 + +def max_width(): + return 23 + +def hmap(): + return True + +def reverse(): + return False + +def monospaced(): + return False + +def min_ch(): + return 32 + +def max_ch(): + return 126 + +_font =\ +b'\x0c\x00\x00\x00\x0f\x80\x1f\xc0\x30\xe0\x20\x60\x00\x60\x00\x60'\ +b'\x00\xc0\x03\x80\x03\x00\x06\x00\x06\x00\x06\x00\x00\x00\x00\x00'\ +b'\x06\x00\x06\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x07\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\x09\x00\x00\x00'\ +b'\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00'\ +b'\x18\x00\x18\x00\x18\x00\x00\x00\x00\x00\x00\x00\x18\x00\x18\x00'\ +b'\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00'\ +b'\x00\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\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\x00\x00'\ +b'\x13\x00\x00\x00\x00\x00\xc2\x00\x00\xc6\x00\x00\xc6\x00\x00\xc6'\ +b'\x00\x00\x86\x00\x1f\xff\xc0\x1f\xff\xc0\x01\x8c\x00\x03\x0c\x00'\ +b'\x03\x18\x00\x3f\xff\x80\x3f\xff\x80\x06\x10\x00\x06\x30\x00\x06'\ +b'\x30\x00\x06\x30\x00\x04\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x01\x00\x01\x00'\ +b'\x01\x00\x07\xe0\x1f\xf0\x39\x10\x31\x00\x31\x00\x39\x00\x1f\x00'\ +b'\x0f\xe0\x01\xf0\x01\x38\x01\x18\x01\x18\x21\x38\x3f\xf0\x0f\xc0'\ +b'\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00'\ +b'\x00\x1e\x03\x00\x33\x07\x00\x61\x86\x00\x61\x8c\x00\x61\x8c\x00'\ +b'\x61\x98\x00\x61\xb8\x00\x33\x30\x00\x1e\x73\xc0\x00\x66\x60\x00'\ +b'\xec\x30\x00\xcc\x30\x01\x8c\x30\x01\x8c\x30\x03\x0c\x30\x07\x06'\ +b'\x60\x06\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x07\xc0\x00\x0f\xe0'\ +b'\x00\x1c\x20\x00\x18\x00\x00\x18\x00\x00\x18\x00\x00\x0c\x00\x00'\ +b'\x1e\x00\x00\x3b\x03\x00\x31\x83\x00\x60\xe6\x00\x60\x76\x00\x60'\ +b'\x3c\x00\x70\x1c\x00\x38\x7e\x00\x1f\xe7\x00\x0f\xc3\x80\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x06\x00\x00\x30\x30\x30\x30\x30\x30\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x06\x00'\ +b'\x0c\x00\x0c\x00\x18\x00\x18\x00\x18\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x18\x00\x18\x00'\ +b'\x18\x00\x0c\x00\x0c\x00\x06\x00\x00\x00\x00\x00\x09\x00\x00\x00'\ +b'\x30\x00\x18\x00\x18\x00\x0c\x00\x0c\x00\x0c\x00\x06\x00\x06\x00'\ +b'\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x0c\x00'\ +b'\x0c\x00\x0c\x00\x18\x00\x18\x00\x30\x00\x00\x00\x00\x00\x0c\x00'\ +b'\x00\x00\x04\x00\x04\x00\x44\x40\x35\x80\x0e\x00\x0e\x00\x35\x80'\ +b'\x44\x40\x04\x00\x04\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\x00'\ +b'\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0'\ +b'\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00'\ +b'\x3f\xff\x00\x3f\xff\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00'\ +b'\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x18\x10\x30'\ +b'\x20\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x7e\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18'\ +b'\x18\x18\x00\x00\x00\x00\x00\x00\x08\x00\x00\x03\x07\x06\x06\x06'\ +b'\x0c\x0c\x0c\x18\x18\x18\x30\x30\x30\x60\x60\x60\xe0\xc0\x00\x00'\ +b'\x00\x00\x0f\x00\x00\x00\x03\xc0\x0f\xf0\x1c\x38\x18\x18\x38\x1c'\ +b'\x30\x0c\x30\x0c\x30\x0c\x30\x0c\x30\x0c\x30\x0c\x30\x0c\x38\x1c'\ +b'\x18\x18\x1c\x38\x0f\xf0\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0f\x00\x00\x00\x07\x80\x1f\x80\x19\x80\x01\x80'\ +b'\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80\x01\x80'\ +b'\x01\x80\x01\x80\x01\x80\x1f\xf8\x1f\xf8\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\xc0\x3f\xf0\x30\x70'\ +b'\x00\x18\x00\x18\x00\x18\x00\x18\x00\x30\x00\x60\x00\xe0\x01\xc0'\ +b'\x03\x80\x07\x00\x0e\x00\x18\x00\x3f\xf8\x3f\xf8\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\xc0\x1f\xe0'\ +b'\x10\x70\x00\x30\x00\x30\x00\x30\x00\x60\x07\xc0\x07\xe0\x00\x70'\ +b'\x00\x18\x00\x18\x00\x18\x00\x18\x20\x70\x3f\xf0\x1f\xc0\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\xe0'\ +b'\x01\xe0\x03\x60\x03\x60\x06\x60\x0c\x60\x0c\x60\x18\x60\x10\x60'\ +b'\x30\x60\x60\x60\x7f\xf8\x7f\xf8\x00\x60\x00\x60\x00\x60\x00\x60'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00'\ +b'\x1f\xf0\x1f\xf0\x18\x00\x18\x00\x18\x00\x18\x00\x1f\xc0\x1f\xe0'\ +b'\x10\x70\x00\x38\x00\x18\x00\x18\x00\x18\x00\x38\x20\x70\x3f\xe0'\ +b'\x1f\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00'\ +b'\x00\x00\x03\xf0\x07\xf8\x0e\x08\x1c\x00\x18\x00\x30\x00\x33\xe0'\ +b'\x37\xf0\x3e\x38\x3c\x1c\x38\x0c\x38\x0c\x38\x0c\x18\x1c\x1e\x38'\ +b'\x0f\xf0\x03\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0f\x00\x00\x00\x3f\xf8\x3f\xf8\x00\x30\x00\x30\x00\x60\x00\x60'\ +b'\x00\xe0\x00\xc0\x00\xc0\x01\x80\x01\x80\x03\x80\x03\x00\x07\x00'\ +b'\x06\x00\x06\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0f\x00\x00\x00\x07\xe0\x1f\xf8\x38\x1c\x30\x0c\x30\x0c'\ +b'\x30\x0c\x18\x18\x0f\xf0\x0f\xf0\x1c\x38\x30\x0c\x30\x0c\x30\x0c'\ +b'\x30\x0c\x1c\x38\x1f\xf8\x07\xe0\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0f\x00\x00\x00\x07\xc0\x0f\xf0\x1c\x78\x38\x38'\ +b'\x30\x1c\x30\x1c\x30\x1c\x30\x3c\x1c\x7c\x0f\xec\x07\xcc\x00\x0c'\ +b'\x00\x18\x00\x38\x10\x70\x1f\xe0\x0f\xc0\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x18\x18'\ +b'\x18\x00\x00\x00\x00\x00\x00\x18\x18\x18\x00\x00\x00\x00\x00\x00'\ +b'\x08\x00\x00\x00\x00\x00\x00\x00\x18\x18\x18\x00\x00\x00\x00\x00'\ +b'\x00\x18\x18\x18\x10\x30\x20\x00\x00\x00\x13\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x0f'\ +b'\x00\x00\x7e\x00\x03\xf0\x00\x0f\xc0\x00\x3e\x00\x00\x3e\x00\x00'\ +b'\x0f\xc0\x00\x03\xf0\x00\x00\x7e\x00\x00\x0f\x00\x00\x01\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\xff\x00\x3f\xff'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\xff\x00\x3f\xff\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\x13\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20'\ +b'\x00\x00\x3c\x00\x00\x1f\x80\x00\x03\xf0\x00\x00\x7c\x00\x00\x1f'\ +b'\x00\x00\x1f\x00\x00\x7c\x00\x03\xf0\x00\x1f\x80\x00\x3c\x00\x00'\ +b'\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x0f\x80\x1f\xc0'\ +b'\x30\xe0\x20\x60\x00\x60\x00\x60\x00\xc0\x03\x80\x03\x00\x06\x00'\ +b'\x06\x00\x06\x00\x00\x00\x00\x00\x06\x00\x06\x00\x06\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x7f\x00\x01\xff\xc0\x07\x81\xe0\x0e\x00\x70\x0c\x00'\ +b'\x38\x18\x79\x98\x18\xff\x8c\x30\xc3\x8c\x31\x81\x8c\x31\x81\x8c'\ +b'\x31\x81\x8c\x31\x81\x98\x31\xc3\xb8\x18\xff\xf0\x18\x79\xc0\x0c'\ +b'\x00\x00\x0e\x00\x40\x07\x81\xc0\x01\xff\x80\x00\x7e\x00\x00\x00'\ +b'\x00\x00\x00\x00\x10\x00\x00\x00\x03\x80\x03\x80\x06\xc0\x06\xc0'\ +b'\x06\xc0\x0c\x60\x0c\x60\x1c\x70\x18\x30\x18\x30\x38\x38\x3f\xf8'\ +b'\x3f\xf8\x60\x0c\x60\x0c\x60\x0c\xc0\x06\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x3f\xe0\x3f\xf0\x30\x38'\ +b'\x30\x18\x30\x18\x30\x18\x30\x30\x3f\xe0\x3f\xf0\x30\x18\x30\x0c'\ +b'\x30\x0c\x30\x0c\x30\x0c\x30\x18\x3f\xf8\x3f\xe0\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x03\xf0\x0f\xfc'\ +b'\x1c\x0e\x38\x02\x30\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00'\ +b'\x60\x00\x60\x00\x30\x00\x38\x02\x1c\x0e\x0f\xfc\x03\xf0\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x3f'\ +b'\xe0\x00\x3f\xf8\x00\x30\x3c\x00\x30\x0e\x00\x30\x06\x00\x30\x03'\ +b'\x00\x30\x03\x00\x30\x03\x00\x30\x03\x00\x30\x03\x00\x30\x03\x00'\ +b'\x30\x03\x00\x30\x06\x00\x30\x0e\x00\x30\x3c\x00\x3f\xf8\x00\x3f'\ +b'\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0f\x00\x00\x00\x3f\xf8\x3f\xf8\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x3f\xf0\x3f\xf0\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x3f\xf8\x3f\xf8\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x3f\xf0\x3f\xf0\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x3f\xe0\x3f\xe0\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x03\xf0\x00'\ +b'\x0f\xfc\x00\x1c\x0e\x00\x38\x02\x00\x30\x00\x00\x60\x00\x00\x60'\ +b'\x00\x00\x60\x00\x00\x60\x3f\x00\x60\x3f\x00\x60\x03\x00\x60\x03'\ +b'\x00\x30\x03\x00\x38\x03\x00\x1e\x07\x00\x0f\xfe\x00\x03\xf8\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x11\x00\x00\x00\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00'\ +b'\x30\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x3f\xfe\x00\x3f'\ +b'\xfe\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06'\ +b'\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x30'\ +b'\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30'\ +b'\x00\x00\x00\x00\x00\x00\x08\x00\x00\x18\x18\x18\x18\x18\x18\x18'\ +b'\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x38\xf0\xe0\x00'\ +b'\x0f\x00\x00\x00\x30\x1c\x30\x38\x30\x70\x30\xe0\x31\xc0\x33\x80'\ +b'\x37\x00\x3e\x00\x3e\x00\x37\x00\x33\x80\x31\xc0\x30\xe0\x30\x70'\ +b'\x30\x38\x30\x1c\x30\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0d\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x3f\xf0\x3f\xf0\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x14\x00\x00\x00\x00\x3c\x07\x80\x3c\x07\x80\x3c'\ +b'\x07\x80\x36\x0d\x80\x36\x0d\x80\x36\x0d\x80\x33\x19\x80\x33\x19'\ +b'\x80\x33\x19\x80\x31\xb1\x80\x31\xb1\x80\x31\xf1\x80\x30\xe1\x80'\ +b'\x30\xe1\x80\x30\x01\x80\x30\x01\x80\x30\x01\x80\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00'\ +b'\x00\x00\x00\x38\x06\x00\x3c\x06\x00\x3c\x06\x00\x36\x06\x00\x36'\ +b'\x06\x00\x33\x06\x00\x33\x86\x00\x31\x86\x00\x31\xc6\x00\x30\xc6'\ +b'\x00\x30\xe6\x00\x30\x66\x00\x30\x36\x00\x30\x36\x00\x30\x1e\x00'\ +b'\x30\x1e\x00\x30\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x03\xf0\x00'\ +b'\x0f\xfc\x00\x1c\x0e\x00\x38\x07\x00\x30\x03\x00\x70\x03\x80\x60'\ +b'\x01\x80\x60\x01\x80\x60\x01\x80\x60\x01\x80\x60\x01\x80\x70\x03'\ +b'\x80\x30\x03\x00\x38\x07\x00\x1c\x0e\x00\x0f\xfc\x00\x03\xf0\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0e\x00\x00\x00\x3f\xc0\x3f\xf0\x30\x30\x30\x18\x30\x18'\ +b'\x30\x18\x30\x18\x30\x30\x3f\xf0\x3f\xc0\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x12\x00\x00\x00\x00\x03\xf0\x00\x0f\xfc\x00\x1c'\ +b'\x0e\x00\x38\x07\x00\x30\x03\x00\x70\x03\x80\x60\x01\x80\x60\x01'\ +b'\x80\x60\x01\x80\x60\x01\x80\x60\x01\x80\x70\x03\x80\x30\x03\x00'\ +b'\x38\x07\x00\x1c\x0e\x00\x0f\xfc\x00\x03\xf8\x00\x00\x1c\x00\x00'\ +b'\x0c\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'\ +b'\x00\x00\x3f\xc0\x3f\xf0\x30\x38\x30\x18\x30\x18\x30\x18\x30\x18'\ +b'\x30\x30\x3f\xf0\x3f\xe0\x30\x70\x30\x30\x30\x18\x30\x18\x30\x0c'\ +b'\x30\x0c\x30\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0f\x00\x00\x00\x07\xe0\x1f\xf8\x18\x18\x30\x00\x30\x00\x30\x00'\ +b'\x38\x00\x1f\x00\x0f\xf0\x00\xf8\x00\x1c\x00\x0c\x00\x0c\x00\x0c'\ +b'\x30\x18\x3f\xf8\x0f\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0e\x00\x00\x00\xff\xfc\xff\xfc\x03\x00\x03\x00\x03\x00'\ +b'\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00'\ +b'\x03\x00\x03\x00\x03\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x11\x00\x00\x00\x00\x30\x06\x00\x30\x06\x00\x30'\ +b'\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06'\ +b'\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00\x30\x06\x00'\ +b'\x18\x0c\x00\x1c\x1c\x00\x0f\xf8\x00\x07\xf0\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'\ +b'\x00\x00\xc0\x06\x60\x0c\x60\x0c\x60\x0c\x30\x18\x30\x18\x38\x38'\ +b'\x18\x30\x18\x30\x1c\x70\x0c\x60\x0c\x60\x06\xc0\x06\xc0\x06\xc0'\ +b'\x03\x80\x03\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x17\x00\x00\x00\x00\x60\x38\x0c\x60\x38\x0c\x30\x6c\x18\x30\x6c'\ +b'\x18\x30\x6c\x18\x30\x6c\x18\x18\xc6\x30\x18\xc6\x30\x18\xc6\x30'\ +b'\x18\xc6\x30\x0d\xc7\x60\x0d\x83\x60\x0d\x83\x60\x0d\x83\x60\x07'\ +b'\x83\xc0\x07\x01\xc0\x07\x01\xc0\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x38\x0e'\ +b'\x18\x0c\x0c\x18\x0e\x38\x06\x30\x07\x60\x03\xe0\x01\xc0\x01\xc0'\ +b'\x03\xc0\x07\x60\x06\x70\x0c\x30\x1c\x38\x18\x18\x30\x0c\x70\x0e'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00'\ +b'\xe0\x1c\x60\x18\x30\x30\x38\x70\x18\x60\x0c\xc0\x0f\xc0\x07\x80'\ +b'\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00'\ +b'\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'\ +b'\x00\x00\x7f\xfe\x7f\xfe\x00\x0c\x00\x1c\x00\x38\x00\x70\x00\xe0'\ +b'\x00\xc0\x01\x80\x03\x00\x07\x00\x0e\x00\x1c\x00\x38\x00\x30\x00'\ +b'\x7f\xfe\x7f\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x09\x00\x00\x00\x3e\x00\x3e\x00\x30\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x3e\x00\x3e\x00\x00\x00'\ +b'\x00\x00\x08\x00\x00\xc0\xe0\x60\x60\x60\x30\x30\x30\x18\x18\x18'\ +b'\x0c\x0c\x0c\x06\x06\x06\x07\x03\x00\x00\x00\x00\x09\x00\x00\x00'\ +b'\x3e\x00\x3e\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00'\ +b'\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00\x06\x00'\ +b'\x06\x00\x06\x00\x06\x00\x3e\x00\x3e\x00\x00\x00\x00\x00\x13\x00'\ +b'\x00\x00\x00\x01\xe0\x00\x03\xf0\x00\x07\x38\x00\x0e\x1c\x00\x1c'\ +b'\x0e\x00\x38\x07\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\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\x0c\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\x00\x00\x00\x00\xff\xf0'\ +b'\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x30\x00\x18\x00'\ +b'\x0c\x00\x06\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\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x80\x3f\xe0\x20\x60\x00\x30'\ +b'\x00\x30\x0f\xf0\x3f\xf0\x70\x30\x60\x30\x60\x70\x70\xf0\x3f\xf0'\ +b'\x1f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00'\ +b'\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x33\xc0\x3f\xe0\x3c\x70'\ +b'\x38\x38\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x38\x38\x3c\x70'\ +b'\x3f\xe0\x33\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xc0\x1f\xe0'\ +b'\x38\x20\x30\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x30\x00'\ +b'\x38\x20\x1f\xe0\x07\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0f\x00\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x0f\x30'\ +b'\x1f\xf0\x38\xf0\x70\x70\x60\x30\x60\x30\x60\x30\x60\x30\x60\x30'\ +b'\x70\x70\x38\xf0\x1f\xf0\x0f\x30\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x07\xc0\x1f\xe0\x38\x30\x30\x18\x60\x18\x7f\xf8\x7f\xf8\x60\x00'\ +b'\x60\x00\x30\x00\x38\x08\x1f\xf8\x07\xf0\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x0f\x80\x1f\x80\x18\x00'\ +b'\x18\x00\x7f\x00\x7f\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00'\ +b'\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0f\x30\x1f\xf0\x38\xf0\x70\x70\x60\x30\x60\x30'\ +b'\x60\x30\x60\x30\x60\x30\x70\x70\x38\xf0\x1f\xf0\x0f\x30\x00\x30'\ +b'\x00\x70\x10\xe0\x1f\xe0\x0f\x80\x00\x00\x0f\x00\x00\x00\x30\x00'\ +b'\x30\x00\x30\x00\x30\x00\x33\xe0\x3f\xf0\x3c\x38\x38\x18\x30\x18'\ +b'\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x30'\ +b'\x30\x30\x00\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30'\ +b'\x00\x00\x00\x00\x00\x00\x07\x00\x00\x18\x18\x18\x00\x18\x18\x18'\ +b'\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\xf0\xe0\x00'\ +b'\x0d\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x70\x30\xe0'\ +b'\x31\xc0\x33\x80\x37\x00\x3e\x00\x3e\x00\x37\x00\x33\x80\x31\xc0'\ +b'\x30\xe0\x30\x70\x30\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x06\x00\x00\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30'\ +b'\x30\x30\x30\x30\x30\x30\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\xc3\xc0'\ +b'\x3f\xef\xe0\x3c\x7c\x70\x38\x38\x30\x30\x30\x30\x30\x30\x30\x30'\ +b'\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30'\ +b'\x30\x30\x30\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x33\xe0\x3f\xf0\x3c\x38\x38\x18\x30\x18\x30\x18\x30\x18'\ +b'\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0f\xc0\x1f\xe0\x38\x70\x30\x30\x60\x18\x60\x18'\ +b'\x60\x18\x60\x18\x60\x18\x30\x30\x38\x70\x1f\xe0\x0f\xc0\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x33\xc0\x3f\xe0\x3c\x70\x38\x38\x30\x18'\ +b'\x30\x18\x30\x18\x30\x18\x30\x18\x38\x38\x3c\x70\x3f\xe0\x33\xc0'\ +b'\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x0e\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x30\x1f\xf0\x38\xf0\x70\x70'\ +b'\x60\x30\x60\x30\x60\x30\x60\x30\x60\x30\x70\x70\x38\xf0\x1f\xf0'\ +b'\x0f\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x09\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x80\x3f\x80\x3c\x00'\ +b'\x38\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\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\x1f\x80\x3f\xc0'\ +b'\x70\x40\x60\x00\x60\x00\x7e\x00\x1f\xc0\x03\xe0\x00\x60\x00\x60'\ +b'\x40\xe0\x7f\xc0\x3f\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x09\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\xff\x00'\ +b'\xff\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00'\ +b'\x30\x00\x30\x00\x3f\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18\x30\x18'\ +b'\x30\x18\x30\x38\x38\x78\x1f\xf8\x0f\x98\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x60\x18\x30\x30\x30\x30\x30\x30\x18\x60\x18\x60\x18\x60'\ +b'\x0c\xc0\x0c\xc0\x0f\xc0\x07\x80\x07\x80\x07\x80\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\xe0\xc0\x60\xe0\xc0\x31'\ +b'\xb1\x80\x31\xb1\x80\x31\xb1\x80\x31\xb1\x80\x1b\x1b\x00\x1b\x1b'\ +b'\x00\x1b\x1b\x00\x1b\x1b\x00\x0e\x0e\x00\x0e\x0e\x00\x0e\x0e\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x38'\ +b'\x38\x70\x18\x60\x0c\xc0\x0f\xc0\x07\x80\x07\x00\x07\x80\x0d\xc0'\ +b'\x1c\xe0\x18\x60\x30\x70\x70\x38\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x60\x18\x30\x30\x30\x30\x30\x70\x18\x60\x18\x60\x0c\xc0\x0c\xc0'\ +b'\x0c\xc0\x07\x80\x07\x80\x07\x80\x03\x00\x03\x00\x06\x00\x06\x00'\ +b'\x3c\x00\x3c\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ +b'\x00\x00\x7f\xe0\x7f\xe0\x00\xe0\x01\xc0\x03\x80\x03\x00\x06\x00'\ +b'\x0e\x00\x1c\x00\x38\x00\x70\x00\x7f\xe0\x7f\xe0\x00\x00\x00\x00'\ +b'\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x01\xe0\x03\xe0'\ +b'\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x07\x00\x3e\x00'\ +b'\x3e\x00\x07\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00'\ +b'\x03\x00\x03\xe0\x01\xe0\x00\x00\x00\x00\x08\x00\x00\x18\x18\x18'\ +b'\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18'\ +b'\x18\x18\x18\x18\x0f\x00\x00\x00\x1e\x00\x1f\x00\x03\x00\x03\x00'\ +b'\x03\x00\x03\x00\x03\x00\x03\x00\x03\x80\x01\xf0\x01\xf0\x03\x80'\ +b'\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x1f\x00'\ +b'\x1e\x00\x00\x00\x00\x00\x13\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\x0f\x01\x00\x1f\xc3\x00\x30\xfe\x00\x00\x3c\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\x00\x00'\ + +_index =\ +b'\x00\x00\x32\x00\x4c\x00\x7e\x00\xb0\x00\xfa\x00\x2c\x01\x76\x01'\ +b'\xc0\x01\xda\x01\x0c\x02\x3e\x02\x70\x02\xba\x02\xd4\x02\xee\x02'\ +b'\x08\x03\x22\x03\x54\x03\x86\x03\xb8\x03\xea\x03\x1c\x04\x4e\x04'\ +b'\x80\x04\xb2\x04\xe4\x04\x16\x05\x30\x05\x4a\x05\x94\x05\xde\x05'\ +b'\x28\x06\x5a\x06\xa4\x06\xd6\x06\x08\x07\x3a\x07\x84\x07\xb6\x07'\ +b'\xe8\x07\x32\x08\x7c\x08\x96\x08\xb0\x08\xe2\x08\x14\x09\x5e\x09'\ +b'\xa8\x09\xf2\x09\x24\x0a\x6e\x0a\xa0\x0a\xd2\x0a\x04\x0b\x4e\x0b'\ +b'\x80\x0b\xca\x0b\xfc\x0b\x2e\x0c\x60\x0c\x92\x0c\xac\x0c\xde\x0c'\ +b'\x28\x0d\x5a\x0d\x8c\x0d\xbe\x0d\xf0\x0d\x22\x0e\x54\x0e\x86\x0e'\ +b'\xb8\x0e\xea\x0e\x1c\x0f\x36\x0f\x50\x0f\x82\x0f\x9c\x0f\xe6\x0f'\ +b'\x18\x10\x4a\x10\x7c\x10\xae\x10\xe0\x10\x12\x11\x44\x11\x76\x11'\ +b'\xa8\x11\xf2\x11\x24\x12\x56\x12\x88\x12\xba\x12\xd4\x12\x06\x13'\ +b'\x50\x13' + +_mvfont = memoryview(_font) +_mvi = memoryview(_index) +ifb = lambda l : l[0] | (l[1] << 8) + +def get_ch(ch): + oc = ord(ch) + ioff = 2 * (oc - 32 + 1) if oc >= 32 and oc <= 126 else 0 + doff = ifb(_mvi[ioff : ]) + width = ifb(_mvfont[doff : ]) + + next_offs = doff + 2 + ((width - 1)//8 + 1) * 24 + return _mvfont[doff + 2:next_offs], 24, width +