adds rotary encoder+SPI based Display: ili9341
This commit is contained in:
		
							parent
							
								
									dd2a5bf637
								
							
						
					
					
						commit
						a8f8586756
					
				
					 11 changed files with 2184 additions and 269 deletions
				
			
		|  | @ -1,3 +1,12 @@ | |||
| # Spinny boy | ||||
| 
 | ||||
| this readme will contain documentation and stuff | ||||
| 
 | ||||
| # Flashing programm on the ESP32 | ||||
| ``` | ||||
| rshell -p /dev/ttyUSB0  # connect | ||||
| rsync src /pyboard/  # sync code to ESP32 | ||||
| repl  # enter MicroPython REPL, press ctrl+D to soft reboot | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										540
									
								
								src/font_to_py.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										540
									
								
								src/font_to_py.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,540 @@ | |||
| #! /usr/bin/python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| # Needs freetype-py>=1.0 | ||||
| 
 | ||||
| # Implements multi-pass solution to setting an exact font height | ||||
| 
 | ||||
| # Some code adapted from Daniel Bader's work at the following URL | ||||
| # http://dbader.org/blog/monochrome-font-rendering-with-freetype-and-python | ||||
| 
 | ||||
| # 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 | ||||
| import freetype | ||||
| 
 | ||||
| # 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') | ||||
| 
 | ||||
| 
 | ||||
| # Define a global | ||||
| def var_write(stream, name, value): | ||||
|     stream.write('{} = {}\n'.format(name, value)) | ||||
| 
 | ||||
| # FONT HANDLING | ||||
| 
 | ||||
| 
 | ||||
| class Bitmap(object): | ||||
|     """ | ||||
|     A 2D bitmap image represented as a list of byte values. Each byte indicates | ||||
|     the state of a single pixel in the bitmap. A value of 0 indicates that the | ||||
|     pixel is `off` and any other value indicates that it is `on`. | ||||
|     """ | ||||
|     def __init__(self, width, height, pixels=None): | ||||
|         self.width = width | ||||
|         self.height = height | ||||
|         self.pixels = pixels or bytearray(width * height) | ||||
| 
 | ||||
|     def display(self): | ||||
|         """Print the bitmap's pixels.""" | ||||
|         for row in range(self.height): | ||||
|             for col in range(self.width): | ||||
|                 char = '#' if self.pixels[row * self.width + col] else '.' | ||||
|                 print(char, end='') | ||||
|             print() | ||||
|         print() | ||||
| 
 | ||||
|     def bitblt(self, src, row): | ||||
|         """Copy all pixels from `src` into this bitmap""" | ||||
|         srcpixel = 0 | ||||
|         dstpixel = row * self.width | ||||
|         row_offset = self.width - src.width | ||||
| 
 | ||||
|         for _ in range(src.height): | ||||
|             for _ in range(src.width): | ||||
|                 self.pixels[dstpixel] = src.pixels[srcpixel] | ||||
|                 srcpixel += 1 | ||||
|                 dstpixel += 1 | ||||
|             dstpixel += row_offset | ||||
| 
 | ||||
|     # Horizontal mapping generator function | ||||
|     def get_hbyte(self, reverse): | ||||
|         for row in range(self.height): | ||||
|             col = 0 | ||||
|             while True: | ||||
|                 bit = col % 8 | ||||
|                 if bit == 0: | ||||
|                     if col >= self.width: | ||||
|                         break | ||||
|                     byte = 0 | ||||
|                 if col < self.width: | ||||
|                     if reverse: | ||||
|                         byte |= self.pixels[row * self.width + col] << bit | ||||
|                     else: | ||||
|                         # Normal map MSB of byte 0 is (0, 0) | ||||
|                         byte |= self.pixels[row * self.width + col] << (7 - bit) | ||||
|                 if bit == 7: | ||||
|                     yield byte | ||||
|                 col += 1 | ||||
| 
 | ||||
|     # Vertical mapping | ||||
|     def get_vbyte(self, reverse): | ||||
|         for col in range(self.width): | ||||
|             row = 0 | ||||
|             while True: | ||||
|                 bit = row % 8 | ||||
|                 if bit == 0: | ||||
|                     if row >= self.height: | ||||
|                         break | ||||
|                     byte = 0 | ||||
|                 if row < self.height: | ||||
|                     if reverse: | ||||
|                         byte |= self.pixels[row * self.width + col] << (7 - bit) | ||||
|                     else: | ||||
|                         # Normal map MSB of byte 0 is (0, 7) | ||||
|                         byte |= self.pixels[row * self.width + col] << bit | ||||
|                 if bit == 7: | ||||
|                     yield byte | ||||
|                 row += 1 | ||||
| 
 | ||||
| 
 | ||||
| class Glyph(object): | ||||
|     def __init__(self, pixels, width, height, top, advance_width): | ||||
|         self.bitmap = Bitmap(width, height, pixels) | ||||
| 
 | ||||
|         # The glyph bitmap's top-side bearing, i.e. the vertical distance from | ||||
|         # the baseline to the bitmap's top-most scanline. | ||||
|         self.top = top | ||||
| 
 | ||||
|         # Ascent and descent determine how many pixels the glyph extends | ||||
|         # above or below the baseline. | ||||
|         self.descent = max(0, self.height - self.top) | ||||
|         self.ascent = max(0, max(self.top, self.height) - self.descent) | ||||
| 
 | ||||
|         # The advance width determines where to place the next character | ||||
|         # horizontally, that is, how many pixels we move to the right to | ||||
|         # draw the next glyph. | ||||
|         self.advance_width = advance_width | ||||
| 
 | ||||
|     @property | ||||
|     def width(self): | ||||
|         return self.bitmap.width | ||||
| 
 | ||||
|     @property | ||||
|     def height(self): | ||||
|         return self.bitmap.height | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def from_glyphslot(slot): | ||||
|         """Construct and return a Glyph object from a FreeType GlyphSlot.""" | ||||
|         pixels = Glyph.unpack_mono_bitmap(slot.bitmap) | ||||
|         width, height = slot.bitmap.width, slot.bitmap.rows | ||||
|         top = slot.bitmap_top | ||||
| 
 | ||||
|         # The advance width is given in FreeType's 26.6 fixed point format, | ||||
|         # which means that the pixel values are multiples of 64. | ||||
|         advance_width = slot.advance.x / 64 | ||||
| 
 | ||||
|         return Glyph(pixels, width, height, top, advance_width) | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def unpack_mono_bitmap(bitmap): | ||||
|         """ | ||||
|         Unpack a freetype FT_LOAD_TARGET_MONO glyph bitmap into a bytearray | ||||
|         where each pixel is represented by a single byte. | ||||
|         """ | ||||
|         # Allocate a bytearray of sufficient size to hold the glyph bitmap. | ||||
|         data = bytearray(bitmap.rows * bitmap.width) | ||||
| 
 | ||||
|         # Iterate over every byte in the glyph bitmap. Note that we're not | ||||
|         # iterating over every pixel in the resulting unpacked bitmap -- | ||||
|         # we're iterating over the packed bytes in the input bitmap. | ||||
|         for row in range(bitmap.rows): | ||||
|             for byte_index in range(bitmap.pitch): | ||||
| 
 | ||||
|                 # Read the byte that contains the packed pixel data. | ||||
|                 byte_value = bitmap.buffer[row * bitmap.pitch + byte_index] | ||||
| 
 | ||||
|                 # We've processed this many bits (=pixels) so far. This | ||||
|                 # determines where we'll read the next batch of pixels from. | ||||
|                 num_bits_done = byte_index * 8 | ||||
| 
 | ||||
|                 # Pre-compute where to write the pixels that we're going | ||||
|                 # to unpack from the current byte in the glyph bitmap. | ||||
|                 rowstart = row * bitmap.width + byte_index * 8 | ||||
| 
 | ||||
|                 # Iterate over every bit (=pixel) that's still a part of the | ||||
|                 # output bitmap. Sometimes we're only unpacking a fraction of | ||||
|                 # a byte because glyphs may not always fit on a byte boundary. | ||||
|                 # So we make sure to stop if we unpack past the current row | ||||
|                 # of pixels. | ||||
|                 for bit_index in range(min(8, bitmap.width - num_bits_done)): | ||||
| 
 | ||||
|                     # Unpack the next pixel from the current glyph byte. | ||||
|                     bit = byte_value & (1 << (7 - bit_index)) | ||||
| 
 | ||||
|                     # Write the pixel to the output bytearray. We ensure that | ||||
|                     # `off` pixels have a value of 0 and `on` pixels have a | ||||
|                     # value of 1. | ||||
|                     data[rowstart + bit_index] = 1 if bit else 0 | ||||
| 
 | ||||
|         return data | ||||
| 
 | ||||
| 
 | ||||
| # A Font object is a dictionary of ASCII chars indexed by a character e.g. | ||||
| # myfont['a'] | ||||
| # Each entry comprises a list | ||||
| # [0] A Bitmap instance containing the character | ||||
| # [1] The width of the character data including advance (actual data stored) | ||||
| # Public attributes: | ||||
| # height (in pixels) of all characters | ||||
| # width (in pixels) for monospaced output (advance width of widest char) | ||||
| class Font(dict): | ||||
|     def __init__(self, filename, size, minchar, maxchar, monospaced, defchar): | ||||
|         super().__init__() | ||||
|         self._face = freetype.Face(filename) | ||||
|         if defchar is None: # Binary font | ||||
|             self.charset = [chr(char) for char in range(minchar, maxchar + 1)] | ||||
|         else: | ||||
|             self.charset = [chr(defchar)] + [chr(char) for char in range(minchar, maxchar + 1)] | ||||
|         self.max_width = self.get_dimensions(size) | ||||
|         self.width = self.max_width if monospaced else 0 | ||||
|         for char in self.charset:  # Populate dictionary | ||||
|             self._render_char(char) | ||||
| 
 | ||||
|     # n-pass solution to setting a precise height. | ||||
|     def get_dimensions(self, required_height): | ||||
|         error = 0 | ||||
|         height = required_height | ||||
|         for npass in range(10): | ||||
|             height += error | ||||
|             self._face.set_pixel_sizes(0, height) | ||||
|             max_descent = 0 | ||||
| 
 | ||||
|             # For each character in the charset string we get the glyph | ||||
|             # and update the overall dimensions of the resulting bitmap. | ||||
|             max_width = 0 | ||||
|             max_ascent = 0 | ||||
|             for char in self.charset: | ||||
|                 glyph = self._glyph_for_character(char) | ||||
|                 max_ascent = max(max_ascent, glyph.ascent) | ||||
|                 max_descent = max(max_descent, glyph.descent) | ||||
|                 # for a few chars e.g. _ glyph.width > glyph.advance_width | ||||
|                 max_width = int(max(max_width, glyph.advance_width, | ||||
|                                         glyph.width)) | ||||
| 
 | ||||
|             new_error = required_height - (max_ascent + max_descent) | ||||
|             if (new_error == 0) or (abs(new_error) - abs(error) == 0): | ||||
|                 break | ||||
|             error = new_error | ||||
|         self.height = int(max_ascent + max_descent) | ||||
|         st = 'Height set in {} passes. Actual height {} pixels.\nMax character width {} pixels.' | ||||
|         print(st.format(npass + 1, self.height, max_width)) | ||||
|         self._max_descent = int(max_descent) | ||||
|         return max_width | ||||
| 
 | ||||
| 
 | ||||
|     def _glyph_for_character(self, char): | ||||
|         # Let FreeType load the glyph for the given character and tell it to | ||||
|         # render a monochromatic bitmap representation. | ||||
|         self._face.load_char(char, freetype.FT_LOAD_RENDER | | ||||
|                              freetype.FT_LOAD_TARGET_MONO) | ||||
|         return Glyph.from_glyphslot(self._face.glyph) | ||||
| 
 | ||||
|     def _render_char(self, char): | ||||
|         glyph = self._glyph_for_character(char) | ||||
|         char_width = int(max(glyph.width, glyph.advance_width))  # Actual width | ||||
|         width = self.width if self.width else char_width  # Space required if monospaced | ||||
|         outbuffer = Bitmap(width, self.height) | ||||
| 
 | ||||
|         # The vertical drawing position should place the glyph | ||||
|         # on the baseline as intended. | ||||
|         row = self.height - int(glyph.ascent) - self._max_descent | ||||
|         outbuffer.bitblt(glyph.bitmap, row) | ||||
|         self[char] = [outbuffer, width, char_width] | ||||
| 
 | ||||
|     def stream_char(self, char, hmap, reverse): | ||||
|         outbuffer, _, _ = self[char] | ||||
|         if hmap: | ||||
|             gen = outbuffer.get_hbyte(reverse) | ||||
|         else: | ||||
|             gen = outbuffer.get_vbyte(reverse) | ||||
|         yield from gen | ||||
| 
 | ||||
|     def build_arrays(self, hmap, reverse): | ||||
|         data = bytearray() | ||||
|         index = bytearray((0, 0)) | ||||
|         for char in self.charset: | ||||
|             width = self[char][1] | ||||
|             data += (width).to_bytes(2, byteorder='little') | ||||
|             data += bytearray(self.stream_char(char, hmap, reverse)) | ||||
|             index += (len(data)).to_bytes(2, byteorder='little') | ||||
|         return data, index | ||||
| 
 | ||||
|     def build_binary_array(self, hmap, reverse, sig): | ||||
|         data = bytearray((0x3f + sig, 0xe7, self.max_width, self.height)) | ||||
|         for char in self.charset: | ||||
|             width = self[char][2] | ||||
|             data += bytes((width,)) | ||||
|             data += bytearray(self.stream_char(char, hmap, reverse)) | ||||
|         return data | ||||
| 
 | ||||
| # PYTHON FILE WRITING | ||||
| 
 | ||||
| STR01 = """# Code generated by font-to-py.py. | ||||
| # Font: {} | ||||
| version = '0.2' | ||||
| """ | ||||
| 
 | ||||
| STR02 = """_mvfont = memoryview(_font) | ||||
| 
 | ||||
| def _chr_addr(ordch): | ||||
|     offset = 2 * (ordch - {}) | ||||
|     return int.from_bytes(_index[offset:offset + 2], 'little') | ||||
|      | ||||
| def get_width(s): | ||||
|     width = 0 | ||||
|     for ch in s: | ||||
|         ordch = ord(ch) | ||||
|         ordch = ordch + 1 if ordch >= {} and ordch <= {} else 32 | ||||
|         offset = _chr_addr(ordch) | ||||
|         width += int.from_bytes(_font[offset:offset + 2], 'little') | ||||
|     return width | ||||
| 
 | ||||
| def get_ch(ch): | ||||
|     ordch = ord(ch) | ||||
|     ordch = ordch + 1 if ordch >= {} and ordch <= {} else {} | ||||
|     offset = _chr_addr(ordch) | ||||
|     width = int.from_bytes(_font[offset:offset + 2], 'little') | ||||
|     next_offs = _chr_addr(ordch +1) | ||||
|     return _mvfont[offset + 2:next_offs], width | ||||
|   | ||||
| """ | ||||
| 
 | ||||
| def write_func(stream, name, arg): | ||||
|     stream.write('def {}():\n    return {}\n\n'.format(name, arg)) | ||||
| 
 | ||||
| # filename, size, minchar=32, maxchar=126, monospaced=False, defchar=ord('?'): | ||||
| 
 | ||||
| def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar, maxchar, defchar): | ||||
|     try: | ||||
|         fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar) | ||||
|     except freetype.ft_errors.FT_Exception: | ||||
|         print("Can't open", font_path) | ||||
|         return False | ||||
|     try: | ||||
|         with open(op_path, 'w') as stream: | ||||
|             write_data(stream, fnt, font_path, monospaced, hmap, reverse, minchar, maxchar) | ||||
|     except OSError: | ||||
|         print("Can't open", op_path, 'for writing') | ||||
|         return False | ||||
|     return True | ||||
| 
 | ||||
| 
 | ||||
| def write_data(stream, fnt, font_path, monospaced, hmap, reverse, minchar, maxchar): | ||||
|     height = fnt.height  # Actual height, not target height | ||||
|     stream.write(STR01.format(os.path.split(font_path)[1])) | ||||
|     stream.write('\n') | ||||
|     write_func(stream, 'height', height) | ||||
|     write_func(stream, 'max_width', fnt.max_width) | ||||
|     write_func(stream, 'hmap', hmap) | ||||
|     write_func(stream, 'reverse', reverse) | ||||
|     write_func(stream, 'monospaced', monospaced) | ||||
|     write_func(stream, 'min_ch', minchar) | ||||
|     write_func(stream, 'max_ch', maxchar) | ||||
|     data, index = fnt.build_arrays(hmap, reverse) | ||||
|     bw_font = ByteWriter(stream, '_font') | ||||
|     bw_font.odata(data) | ||||
|     bw_font.eot() | ||||
|     bw_index = ByteWriter(stream, '_index') | ||||
|     bw_index.odata(index) | ||||
|     bw_index.eot() | ||||
|     stream.write(STR02.format(minchar, minchar, maxchar, minchar, maxchar, minchar)) | ||||
| 
 | ||||
| # BINARY OUTPUT | ||||
| # hmap reverse magic bytes | ||||
| # 0    0       0x3f 0xe7 | ||||
| # 1    0       0x40 0xe7 | ||||
| # 0    1       0x41 0xe7 | ||||
| # 1    1       0x42 0xe7 | ||||
| def write_binary_font(op_path, font_path, height, hmap, reverse): | ||||
|     try: | ||||
|         fnt = Font(font_path, height, 32, 126, True, None)  # All chars have same width | ||||
|     except freetype.ft_errors.FT_Exception: | ||||
|         print("Can't open", font_path) | ||||
|         return False | ||||
|     sig = 1 if hmap else 0 | ||||
|     if reverse: | ||||
|         sig += 2 | ||||
|     try: | ||||
|         with open(op_path, 'wb') as stream: | ||||
|             data = fnt.build_binary_array(hmap, reverse, sig) | ||||
|             stream.write(data) | ||||
|     except OSError: | ||||
|         print("Can't open", op_path, 'for writing') | ||||
|         return False | ||||
|     return True | ||||
| 
 | ||||
| # PARSE COMMAND LINE ARGUMENTS | ||||
| 
 | ||||
| def quit(msg): | ||||
|     print(msg) | ||||
|     sys.exit(1) | ||||
| 
 | ||||
| DESC = """font_to_py.py | ||||
| Utility to convert ttf or otf font files to Python source. | ||||
| Sample usage: | ||||
| font_to_py.py FreeSans.ttf 23 freesans.py | ||||
| 
 | ||||
| This creates a font with nominal height 23 pixels with these defaults: | ||||
| Mapping is vertical, pitch variable, character set 32-126 inclusive. | ||||
| Illegal characters will be rendered as "?". | ||||
| 
 | ||||
| To specify monospaced rendering issue: | ||||
| font_to_py.py FreeSans.ttf 23 --fixed freesans.py | ||||
| """ | ||||
| 
 | ||||
| BINARY = """Invalid arguments. Binary (random access) font files support the standard ASCII | ||||
| character set (from 32 to 126 inclusive). This range cannot be overridden. | ||||
| Random access font files don't support an error character. | ||||
| """ | ||||
| 
 | ||||
| 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('height', type=int, help='Font height in pixels') | ||||
|     parser.add_argument('outfile', type=str, | ||||
|                         help='Path and name of output file') | ||||
| 
 | ||||
|     parser.add_argument('-x', '--xmap', action='store_true', | ||||
|                         help='Horizontal (x) mapping') | ||||
|     parser.add_argument('-r', '--reverse', action='store_true', | ||||
|                         help='Bit reversal') | ||||
|     parser.add_argument('-f', '--fixed', action='store_true', | ||||
|                         help='Fixed width (monospaced) font') | ||||
|     parser.add_argument('-b', '--binary', action='store_true', | ||||
|                         help='Produce binary (random access) font file.') | ||||
| 
 | ||||
|     parser.add_argument('-s', '--smallest', | ||||
|                         type = int, | ||||
|                         default = 32, | ||||
|                         help = 'Ordinal value of smallest character default %(default)i') | ||||
| 
 | ||||
|     parser.add_argument('-l', '--largest', | ||||
|                         type = int, | ||||
|                         help = 'Ordinal value of largest character default %(default)i', | ||||
|                         default = 126) | ||||
| 
 | ||||
|     parser.add_argument('-e', '--errchar', | ||||
|                         type = int, | ||||
|                         help = 'Ordinal value of error character default %(default)i ("?")', | ||||
|                         default = 63) | ||||
| 
 | ||||
|     args = parser.parse_args() | ||||
|     if not args.infile[0].isalpha(): | ||||
|         quit('Font filenames must be valid Python variable names.') | ||||
| 
 | ||||
|     if not os.path.isfile(args.infile): | ||||
|         quit("Font filename does not exist") | ||||
| 
 | ||||
|     if not os.path.splitext(args.infile)[1].upper() in ('.TTF', '.OTF'): | ||||
|         quit("Font file should be a ttf or otf file.") | ||||
| 
 | ||||
|     if args.binary: | ||||
|         if os.path.splitext(args.outfile)[1].upper() == '.PY': | ||||
|             quit('Binary file must not have a .py extension.') | ||||
| 
 | ||||
|         if args.smallest != 32 or args.largest != 126 or args.errchar != ord('?'): | ||||
|             quit(BINARY) | ||||
| 
 | ||||
|         print('Writing binary font file.') | ||||
|         if not write_binary_font(args.outfile, args.infile, args.height, | ||||
|                                  args.xmap, args.reverse): | ||||
|             sys.exit(1) | ||||
|     else: | ||||
|         if not os.path.splitext(args.outfile)[1].upper() == '.PY': | ||||
|             quit('Output filename must have a .py extension.') | ||||
| 
 | ||||
|         if args.smallest < 0: | ||||
|             quit('--smallest must be >= 0') | ||||
| 
 | ||||
|         if args.largest > 255: | ||||
|             quit('--largest must be < 256') | ||||
| 
 | ||||
|         if args.errchar < 0 or args.errchar > 255: | ||||
|             quit('--errchar must be between 0 and 255') | ||||
| 
 | ||||
|         print('Writing Python font file.') | ||||
|         if not write_font(args.outfile, args.infile, args.height, args.fixed, | ||||
|                           args.xmap, args.reverse, args.smallest, args.largest, | ||||
|                           args.errchar): | ||||
|             sys.exit(1) | ||||
| 
 | ||||
|     print(args.outfile, 'written successfully.') | ||||
| 
 | ||||
							
								
								
									
										294
									
								
								src/glcdfont.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								src/glcdfont.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,294 @@ | |||
| # Original Adafruit_GFX 5x7 font | ||||
| 
 | ||||
| def height(): | ||||
|     return 8 | ||||
| 
 | ||||
| def max_width(): | ||||
|     return 6 | ||||
| 
 | ||||
| def hmap(): | ||||
|     return False | ||||
| 
 | ||||
| def reverse(): | ||||
|     return False | ||||
| 
 | ||||
| def monospaced(): | ||||
|     return True | ||||
| 
 | ||||
| def min_ch(): | ||||
|     return 0 | ||||
| 
 | ||||
| def max_ch(): | ||||
|     return 255 | ||||
| 
 | ||||
| 
 | ||||
| _font = \ | ||||
| 	b'\x00\x00\x00\x00\x00'\ | ||||
| 	b'\x3E\x5B\x4F\x5B\x3E'\ | ||||
| 	b'\x3E\x6B\x4F\x6B\x3E'\ | ||||
| 	b'\x1C\x3E\x7C\x3E\x1C'\ | ||||
| 	b'\x18\x3C\x7E\x3C\x18'\ | ||||
| 	b'\x1C\x57\x7D\x57\x1C'\ | ||||
| 	b'\x1C\x5E\x7F\x5E\x1C'\ | ||||
| 	b'\x00\x18\x3C\x18\x00'\ | ||||
| 	b'\xFF\xE7\xC3\xE7\xFF'\ | ||||
| 	b'\x00\x18\x24\x18\x00'\ | ||||
| 	b'\xFF\xE7\xDB\xE7\xFF'\ | ||||
| 	b'\x30\x48\x3A\x06\x0E'\ | ||||
| 	b'\x26\x29\x79\x29\x26'\ | ||||
| 	b'\x40\x7F\x05\x05\x07'\ | ||||
| 	b'\x40\x7F\x05\x25\x3F'\ | ||||
| 	b'\x5A\x3C\xE7\x3C\x5A'\ | ||||
| 	b'\x7F\x3E\x1C\x1C\x08'\ | ||||
| 	b'\x08\x1C\x1C\x3E\x7F'\ | ||||
| 	b'\x14\x22\x7F\x22\x14'\ | ||||
| 	b'\x5F\x5F\x00\x5F\x5F'\ | ||||
| 	b'\x06\x09\x7F\x01\x7F'\ | ||||
| 	b'\x00\x66\x89\x95\x6A'\ | ||||
| 	b'\x60\x60\x60\x60\x60'\ | ||||
| 	b'\x94\xA2\xFF\xA2\x94'\ | ||||
| 	b'\x08\x04\x7E\x04\x08'\ | ||||
| 	b'\x10\x20\x7E\x20\x10'\ | ||||
| 	b'\x08\x08\x2A\x1C\x08'\ | ||||
| 	b'\x08\x1C\x2A\x08\x08'\ | ||||
| 	b'\x1E\x10\x10\x10\x10'\ | ||||
| 	b'\x0C\x1E\x0C\x1E\x0C'\ | ||||
| 	b'\x30\x38\x3E\x38\x30'\ | ||||
| 	b'\x06\x0E\x3E\x0E\x06'\ | ||||
| 	b'\x00\x00\x00\x00\x00'\ | ||||
| 	b'\x00\x00\x5F\x00\x00'\ | ||||
| 	b'\x00\x07\x00\x07\x00'\ | ||||
| 	b'\x14\x7F\x14\x7F\x14'\ | ||||
| 	b'\x24\x2A\x7F\x2A\x12'\ | ||||
| 	b'\x23\x13\x08\x64\x62'\ | ||||
| 	b'\x36\x49\x56\x20\x50'\ | ||||
| 	b'\x00\x08\x07\x03\x00'\ | ||||
| 	b'\x00\x1C\x22\x41\x00'\ | ||||
| 	b'\x00\x41\x22\x1C\x00'\ | ||||
| 	b'\x2A\x1C\x7F\x1C\x2A'\ | ||||
| 	b'\x08\x08\x3E\x08\x08'\ | ||||
| 	b'\x00\x80\x70\x30\x00'\ | ||||
| 	b'\x08\x08\x08\x08\x08'\ | ||||
| 	b'\x00\x00\x60\x60\x00'\ | ||||
| 	b'\x20\x10\x08\x04\x02'\ | ||||
| 	b'\x3E\x51\x49\x45\x3E'\ | ||||
| 	b'\x00\x42\x7F\x40\x00'\ | ||||
| 	b'\x72\x49\x49\x49\x46'\ | ||||
| 	b'\x21\x41\x49\x4D\x33'\ | ||||
| 	b'\x18\x14\x12\x7F\x10'\ | ||||
| 	b'\x27\x45\x45\x45\x39'\ | ||||
| 	b'\x3C\x4A\x49\x49\x31'\ | ||||
| 	b'\x41\x21\x11\x09\x07'\ | ||||
| 	b'\x36\x49\x49\x49\x36'\ | ||||
| 	b'\x46\x49\x49\x29\x1E'\ | ||||
| 	b'\x00\x00\x14\x00\x00'\ | ||||
| 	b'\x00\x40\x34\x00\x00'\ | ||||
| 	b'\x00\x08\x14\x22\x41'\ | ||||
| 	b'\x14\x14\x14\x14\x14'\ | ||||
| 	b'\x00\x41\x22\x14\x08'\ | ||||
| 	b'\x02\x01\x59\x09\x06'\ | ||||
| 	b'\x3E\x41\x5D\x59\x4E'\ | ||||
| 	b'\x7C\x12\x11\x12\x7C'\ | ||||
| 	b'\x7F\x49\x49\x49\x36'\ | ||||
| 	b'\x3E\x41\x41\x41\x22'\ | ||||
| 	b'\x7F\x41\x41\x41\x3E'\ | ||||
| 	b'\x7F\x49\x49\x49\x41'\ | ||||
| 	b'\x7F\x09\x09\x09\x01'\ | ||||
| 	b'\x3E\x41\x41\x51\x73'\ | ||||
| 	b'\x7F\x08\x08\x08\x7F'\ | ||||
| 	b'\x00\x41\x7F\x41\x00'\ | ||||
| 	b'\x20\x40\x41\x3F\x01'\ | ||||
| 	b'\x7F\x08\x14\x22\x41'\ | ||||
| 	b'\x7F\x40\x40\x40\x40'\ | ||||
| 	b'\x7F\x02\x1C\x02\x7F'\ | ||||
| 	b'\x7F\x04\x08\x10\x7F'\ | ||||
| 	b'\x3E\x41\x41\x41\x3E'\ | ||||
| 	b'\x7F\x09\x09\x09\x06'\ | ||||
| 	b'\x3E\x41\x51\x21\x5E'\ | ||||
| 	b'\x7F\x09\x19\x29\x46'\ | ||||
| 	b'\x26\x49\x49\x49\x32'\ | ||||
| 	b'\x03\x01\x7F\x01\x03'\ | ||||
| 	b'\x3F\x40\x40\x40\x3F'\ | ||||
| 	b'\x1F\x20\x40\x20\x1F'\ | ||||
| 	b'\x3F\x40\x38\x40\x3F'\ | ||||
| 	b'\x63\x14\x08\x14\x63'\ | ||||
| 	b'\x03\x04\x78\x04\x03'\ | ||||
| 	b'\x61\x59\x49\x4D\x43'\ | ||||
| 	b'\x00\x7F\x41\x41\x41'\ | ||||
| 	b'\x02\x04\x08\x10\x20'\ | ||||
| 	b'\x00\x41\x41\x41\x7F'\ | ||||
| 	b'\x04\x02\x01\x02\x04'\ | ||||
| 	b'\x40\x40\x40\x40\x40'\ | ||||
| 	b'\x00\x03\x07\x08\x00'\ | ||||
| 	b'\x20\x54\x54\x78\x40'\ | ||||
| 	b'\x7F\x28\x44\x44\x38'\ | ||||
| 	b'\x38\x44\x44\x44\x28'\ | ||||
| 	b'\x38\x44\x44\x28\x7F'\ | ||||
| 	b'\x38\x54\x54\x54\x18'\ | ||||
| 	b'\x00\x08\x7E\x09\x02'\ | ||||
| 	b'\x18\xA4\xA4\x9C\x78'\ | ||||
| 	b'\x7F\x08\x04\x04\x78'\ | ||||
| 	b'\x00\x44\x7D\x40\x00'\ | ||||
| 	b'\x20\x40\x40\x3D\x00'\ | ||||
| 	b'\x7F\x10\x28\x44\x00'\ | ||||
| 	b'\x00\x41\x7F\x40\x00'\ | ||||
| 	b'\x7C\x04\x78\x04\x78'\ | ||||
| 	b'\x7C\x08\x04\x04\x78'\ | ||||
| 	b'\x38\x44\x44\x44\x38'\ | ||||
| 	b'\xFC\x18\x24\x24\x18'\ | ||||
| 	b'\x18\x24\x24\x18\xFC'\ | ||||
| 	b'\x7C\x08\x04\x04\x08'\ | ||||
| 	b'\x48\x54\x54\x54\x24'\ | ||||
| 	b'\x04\x04\x3F\x44\x24'\ | ||||
| 	b'\x3C\x40\x40\x20\x7C'\ | ||||
| 	b'\x1C\x20\x40\x20\x1C'\ | ||||
| 	b'\x3C\x40\x30\x40\x3C'\ | ||||
| 	b'\x44\x28\x10\x28\x44'\ | ||||
| 	b'\x4C\x90\x90\x90\x7C'\ | ||||
| 	b'\x44\x64\x54\x4C\x44'\ | ||||
| 	b'\x00\x08\x36\x41\x00'\ | ||||
| 	b'\x00\x00\x77\x00\x00'\ | ||||
| 	b'\x00\x41\x36\x08\x00'\ | ||||
| 	b'\x02\x01\x02\x04\x02'\ | ||||
| 	b'\x3C\x26\x23\x26\x3C'\ | ||||
| 	b'\x1E\xA1\xA1\x61\x12'\ | ||||
| 	b'\x3A\x40\x40\x20\x7A'\ | ||||
| 	b'\x38\x54\x54\x55\x59'\ | ||||
| 	b'\x21\x55\x55\x79\x41'\ | ||||
| 	b'\x21\x54\x54\x78\x41'\ | ||||
| 	b'\x21\x55\x54\x78\x40'\ | ||||
| 	b'\x20\x54\x55\x79\x40'\ | ||||
| 	b'\x0C\x1E\x52\x72\x12'\ | ||||
| 	b'\x39\x55\x55\x55\x59'\ | ||||
| 	b'\x39\x54\x54\x54\x59'\ | ||||
| 	b'\x39\x55\x54\x54\x58'\ | ||||
| 	b'\x00\x00\x45\x7C\x41'\ | ||||
| 	b'\x00\x02\x45\x7D\x42'\ | ||||
| 	b'\x00\x01\x45\x7C\x40'\ | ||||
| 	b'\xF0\x29\x24\x29\xF0'\ | ||||
| 	b'\xF0\x28\x25\x28\xF0'\ | ||||
| 	b'\x7C\x54\x55\x45\x00'\ | ||||
| 	b'\x20\x54\x54\x7C\x54'\ | ||||
| 	b'\x7C\x0A\x09\x7F\x49'\ | ||||
| 	b'\x32\x49\x49\x49\x32'\ | ||||
| 	b'\x32\x48\x48\x48\x32'\ | ||||
| 	b'\x32\x4A\x48\x48\x30'\ | ||||
| 	b'\x3A\x41\x41\x21\x7A'\ | ||||
| 	b'\x3A\x42\x40\x20\x78'\ | ||||
| 	b'\x00\x9D\xA0\xA0\x7D'\ | ||||
| 	b'\x39\x44\x44\x44\x39'\ | ||||
| 	b'\x3D\x40\x40\x40\x3D'\ | ||||
| 	b'\x3C\x24\xFF\x24\x24'\ | ||||
| 	b'\x48\x7E\x49\x43\x66'\ | ||||
| 	b'\x2B\x2F\xFC\x2F\x2B'\ | ||||
| 	b'\xFF\x09\x29\xF6\x20'\ | ||||
| 	b'\xC0\x88\x7E\x09\x03'\ | ||||
| 	b'\x20\x54\x54\x79\x41'\ | ||||
| 	b'\x00\x00\x44\x7D\x41'\ | ||||
| 	b'\x30\x48\x48\x4A\x32'\ | ||||
| 	b'\x38\x40\x40\x22\x7A'\ | ||||
| 	b'\x00\x7A\x0A\x0A\x72'\ | ||||
| 	b'\x7D\x0D\x19\x31\x7D'\ | ||||
| 	b'\x26\x29\x29\x2F\x28'\ | ||||
| 	b'\x26\x29\x29\x29\x26'\ | ||||
| 	b'\x30\x48\x4D\x40\x20'\ | ||||
| 	b'\x38\x08\x08\x08\x08'\ | ||||
| 	b'\x08\x08\x08\x08\x38'\ | ||||
| 	b'\x2F\x10\xC8\xAC\xBA'\ | ||||
| 	b'\x2F\x10\x28\x34\xFA'\ | ||||
| 	b'\x00\x00\x7B\x00\x00'\ | ||||
| 	b'\x08\x14\x2A\x14\x22'\ | ||||
| 	b'\x22\x14\x2A\x14\x08'\ | ||||
| 	b'\xAA\x00\x55\x00\xAA'\ | ||||
| 	b'\xAA\x55\xAA\x55\xAA'\ | ||||
| 	b'\x00\x00\x00\xFF\x00'\ | ||||
| 	b'\x10\x10\x10\xFF\x00'\ | ||||
| 	b'\x14\x14\x14\xFF\x00'\ | ||||
| 	b'\x10\x10\xFF\x00\xFF'\ | ||||
| 	b'\x10\x10\xF0\x10\xF0'\ | ||||
| 	b'\x14\x14\x14\xFC\x00'\ | ||||
| 	b'\x14\x14\xF7\x00\xFF'\ | ||||
| 	b'\x00\x00\xFF\x00\xFF'\ | ||||
| 	b'\x14\x14\xF4\x04\xFC'\ | ||||
| 	b'\x14\x14\x17\x10\x1F'\ | ||||
| 	b'\x10\x10\x1F\x10\x1F'\ | ||||
| 	b'\x14\x14\x14\x1F\x00'\ | ||||
| 	b'\x10\x10\x10\xF0\x00'\ | ||||
| 	b'\x00\x00\x00\x1F\x10'\ | ||||
| 	b'\x10\x10\x10\x1F\x10'\ | ||||
| 	b'\x10\x10\x10\xF0\x10'\ | ||||
| 	b'\x00\x00\x00\xFF\x10'\ | ||||
| 	b'\x10\x10\x10\x10\x10'\ | ||||
| 	b'\x10\x10\x10\xFF\x10'\ | ||||
| 	b'\x00\x00\x00\xFF\x14'\ | ||||
| 	b'\x00\x00\xFF\x00\xFF'\ | ||||
| 	b'\x00\x00\x1F\x10\x17'\ | ||||
| 	b'\x00\x00\xFC\x04\xF4'\ | ||||
| 	b'\x14\x14\x17\x10\x17'\ | ||||
| 	b'\x14\x14\xF4\x04\xF4'\ | ||||
| 	b'\x00\x00\xFF\x00\xF7'\ | ||||
| 	b'\x14\x14\x14\x14\x14'\ | ||||
| 	b'\x14\x14\xF7\x00\xF7'\ | ||||
| 	b'\x14\x14\x14\x17\x14'\ | ||||
| 	b'\x10\x10\x1F\x10\x1F'\ | ||||
| 	b'\x14\x14\x14\xF4\x14'\ | ||||
| 	b'\x10\x10\xF0\x10\xF0'\ | ||||
| 	b'\x00\x00\x1F\x10\x1F'\ | ||||
| 	b'\x00\x00\x00\x1F\x14'\ | ||||
| 	b'\x00\x00\x00\xFC\x14'\ | ||||
| 	b'\x00\x00\xF0\x10\xF0'\ | ||||
| 	b'\x10\x10\xFF\x10\xFF'\ | ||||
| 	b'\x14\x14\x14\xFF\x14'\ | ||||
| 	b'\x10\x10\x10\x1F\x00'\ | ||||
| 	b'\x00\x00\x00\xF0\x10'\ | ||||
| 	b'\xFF\xFF\xFF\xFF\xFF'\ | ||||
| 	b'\xF0\xF0\xF0\xF0\xF0'\ | ||||
| 	b'\xFF\xFF\xFF\x00\x00'\ | ||||
| 	b'\x00\x00\x00\xFF\xFF'\ | ||||
| 	b'\x0F\x0F\x0F\x0F\x0F'\ | ||||
| 	b'\x38\x44\x44\x38\x44'\ | ||||
| 	b'\x7C\x2A\x2A\x3E\x14'\ | ||||
| 	b'\x7E\x02\x02\x06\x06'\ | ||||
| 	b'\x02\x7E\x02\x7E\x02'\ | ||||
| 	b'\x63\x55\x49\x41\x63'\ | ||||
| 	b'\x38\x44\x44\x3C\x04'\ | ||||
| 	b'\x40\x7E\x20\x1E\x20'\ | ||||
| 	b'\x06\x02\x7E\x02\x02'\ | ||||
| 	b'\x99\xA5\xE7\xA5\x99'\ | ||||
| 	b'\x1C\x2A\x49\x2A\x1C'\ | ||||
| 	b'\x4C\x72\x01\x72\x4C'\ | ||||
| 	b'\x30\x4A\x4D\x4D\x30'\ | ||||
| 	b'\x30\x48\x78\x48\x30'\ | ||||
| 	b'\xBC\x62\x5A\x46\x3D'\ | ||||
| 	b'\x3E\x49\x49\x49\x00'\ | ||||
| 	b'\x7E\x01\x01\x01\x7E'\ | ||||
| 	b'\x2A\x2A\x2A\x2A\x2A'\ | ||||
| 	b'\x44\x44\x5F\x44\x44'\ | ||||
| 	b'\x40\x51\x4A\x44\x40'\ | ||||
| 	b'\x40\x44\x4A\x51\x40'\ | ||||
| 	b'\x00\x00\xFF\x01\x03'\ | ||||
| 	b'\xE0\x80\xFF\x00\x00'\ | ||||
| 	b'\x08\x08\x6B\x6B\x08'\ | ||||
| 	b'\x36\x12\x36\x24\x36'\ | ||||
| 	b'\x06\x0F\x09\x0F\x06'\ | ||||
| 	b'\x00\x00\x18\x18\x00'\ | ||||
| 	b'\x00\x00\x10\x10\x00'\ | ||||
| 	b'\x30\x40\xFF\x01\x01'\ | ||||
| 	b'\x00\x1F\x01\x01\x1E'\ | ||||
| 	b'\x00\x19\x1D\x17\x12'\ | ||||
| 	b'\x00\x3C\x3C\x3C\x3C'\ | ||||
| 	b'\x00\x00\x00\x00\x00' | ||||
| 
 | ||||
| _mvfont = memoryview(_font) | ||||
| 
 | ||||
| def get_width(s): | ||||
|     return len(s)*6 | ||||
| 
 | ||||
| def get_ch(ch):  | ||||
|     ordch = ord(ch) | ||||
|     offset = ordch*5 | ||||
|     buf = bytearray(6) | ||||
|     buf[0] = 0 | ||||
|     buf[1:]=_mvfont[offset:offset+5] | ||||
|     return buf, 6 | ||||
| 
 | ||||
							
								
								
									
										327
									
								
								src/ili934xnew.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								src/ili934xnew.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,327 @@ | |||
| # This is an adapted version of the ILI934X driver as below. | ||||
| # It works with multiple fonts and also works with the esp32 H/W SPI implementation | ||||
| # Also includes a word wrap print function | ||||
| # Proportional fonts are generated by Peter Hinch's Font-to-py | ||||
| # MIT License; Copyright (c) 2017 Jeffrey N. Magee | ||||
| 
 | ||||
| # This file is part of MicroPython ILI934X driver | ||||
| # Copyright (c) 2016 - 2017 Radomir Dopieralski, Mika Tuupola | ||||
| # | ||||
| # Licensed under the MIT license: | ||||
| #   http://www.opensource.org/licenses/mit-license.php | ||||
| # | ||||
| # Project home: | ||||
| #   https://github.com/tuupola/micropython-ili934x | ||||
| 
 | ||||
| import time | ||||
| import ustruct | ||||
| import glcdfont | ||||
| import framebuf | ||||
| from micropython import const | ||||
| 
 | ||||
| _RDDSDR = const(0x0f) # Read Display Self-Diagnostic Result | ||||
| _SLPOUT = const(0x11) # Sleep Out | ||||
| _GAMSET = const(0x26) # Gamma Set | ||||
| _DISPOFF = const(0x28) # Display Off | ||||
| _DISPON = const(0x29) # Display On | ||||
| _CASET = const(0x2a) # Column Address Set | ||||
| _PASET = const(0x2b) # Page Address Set | ||||
| _RAMWR = const(0x2c) # Memory Write | ||||
| _RAMRD = const(0x2e) # Memory Read | ||||
| _MADCTL = const(0x36) # Memory Access Control | ||||
| _VSCRSADD = const(0x37) # Vertical Scrolling Start Address | ||||
| _PIXSET = const(0x3a) # Pixel Format Set | ||||
| _PWCTRLA = const(0xcb) # Power Control A | ||||
| _PWCRTLB = const(0xcf) # Power Control B | ||||
| _DTCTRLA = const(0xe8) # Driver Timing Control A | ||||
| _DTCTRLB = const(0xea) # Driver Timing Control B | ||||
| _PWRONCTRL = const(0xed) # Power on Sequence Control | ||||
| _PRCTRL = const(0xf7) # Pump Ratio Control | ||||
| _PWCTRL1 = const(0xc0) # Power Control 1 | ||||
| _PWCTRL2 = const(0xc1) # Power Control 2 | ||||
| _VMCTRL1 = const(0xc5) # VCOM Control 1 | ||||
| _VMCTRL2 = const(0xc7) # VCOM Control 2 | ||||
| _FRMCTR1 = const(0xb1) # Frame Rate Control 1 | ||||
| _DISCTRL = const(0xb6) # Display Function Control | ||||
| _ENA3G = const(0xf2) # Enable 3G | ||||
| _PGAMCTRL = const(0xe0) # Positive Gamma Control | ||||
| _NGAMCTRL = const(0xe1) # Negative Gamma Control | ||||
| 
 | ||||
| _CHUNK = const(1024) #maximum number of pixels per spi write | ||||
| 
 | ||||
| def color565(r, g, b): | ||||
|     return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3 | ||||
| 
 | ||||
| class ILI9341: | ||||
| 
 | ||||
|     def __init__(self, spi, cs, dc, rst, w, h, r): | ||||
|         self.spi = spi | ||||
|         self.cs = cs | ||||
|         self.dc = dc | ||||
|         self.rst = rst | ||||
|         self._init_width = w | ||||
|         self._init_height = h | ||||
|         self.width = w | ||||
|         self.height = h | ||||
|         self.rotation = r | ||||
|         self.cs.init(self.cs.OUT, value=1) | ||||
|         self.dc.init(self.dc.OUT, value=0) | ||||
|         self.rst.init(self.rst.OUT, value=0) | ||||
|         self.reset() | ||||
|         self.init() | ||||
|         self._scroll = 0 | ||||
|         self._buf = bytearray(_CHUNK * 2) | ||||
|         self._colormap = bytearray(b'\x00\x00\xFF\xFF') #default white foregraound, black background | ||||
|         self._x = 0 | ||||
|         self._y = 0 | ||||
|         self._font = glcdfont | ||||
|         self.scrolling = False | ||||
| 
 | ||||
|     def set_color(self,fg,bg): | ||||
|         self._colormap[0] = bg>>8 | ||||
|         self._colormap[1] = bg & 255 | ||||
|         self._colormap[2] = fg>>8 | ||||
|         self._colormap[3] = fg & 255 | ||||
| 
 | ||||
|     def set_pos(self,x,y): | ||||
|         self._x = x | ||||
|         self._y = y | ||||
| 
 | ||||
|     def reset_scroll(self): | ||||
|         self.scrolling = False | ||||
|         self._scroll = 0 | ||||
|         self.scroll(0) | ||||
| 
 | ||||
|     def set_font(self, font): | ||||
|         self._font = font | ||||
| 
 | ||||
|     def init(self): | ||||
|         for command, data in ( | ||||
|             (_RDDSDR, b"\x03\x80\x02"), | ||||
|             (_PWCRTLB, b"\x00\xc1\x30"), | ||||
|             (_PWRONCTRL, b"\x64\x03\x12\x81"), | ||||
|             (_DTCTRLA, b"\x85\x00\x78"), | ||||
|             (_PWCTRLA, b"\x39\x2c\x00\x34\x02"), | ||||
|             (_PRCTRL, b"\x20"), | ||||
|             (_DTCTRLB, b"\x00\x00"), | ||||
|             (_PWCTRL1, b"\x23"), | ||||
|             (_PWCTRL2, b"\x10"), | ||||
|             (_VMCTRL1, b"\x3e\x28"), | ||||
|             (_VMCTRL2, b"\x86")): | ||||
|             self._write(command, data) | ||||
| 
 | ||||
|         if self.rotation == 0:                  # 0 deg | ||||
|             self._write(_MADCTL, b"\x48") | ||||
|             self.width = self._init_height | ||||
|             self.height = self._init_width | ||||
|         elif self.rotation == 1:                # 90 deg | ||||
|             self._write(_MADCTL, b"\x28") | ||||
|             self.width = self._init_width | ||||
|             self.height = self._init_height | ||||
|         elif self.rotation == 2:                # 180 deg | ||||
|             self._write(_MADCTL, b"\x88") | ||||
|             self.width = self._init_height | ||||
|             self.height = self._init_width | ||||
|         elif self.rotation == 3:                # 270 deg | ||||
|             self._write(_MADCTL, b"\xE8") | ||||
|             self.width = self._init_width | ||||
|             self.height = self._init_height | ||||
|         elif self.rotation == 4:                # Mirrored + 0 deg | ||||
|             self._write(_MADCTL, b"\xC8") | ||||
|             self.width = self._init_height | ||||
|             self.height = self._init_width | ||||
|         elif self.rotation == 5:                # Mirrored + 90 deg | ||||
|             self._write(_MADCTL, b"\x68") | ||||
|             self.width = self._init_width | ||||
|             self.height = self._init_height | ||||
|         elif self.rotation == 6:                # Mirrored + 180 deg | ||||
|             self._write(_MADCTL, b"\x08") | ||||
|             self.width = self._init_height | ||||
|             self.height = self._init_width | ||||
|         elif self.rotation == 7:                # Mirrored + 270 deg | ||||
|             self._write(_MADCTL, b"\xA8") | ||||
|             self.width = self._init_width | ||||
|             self.height = self._init_height | ||||
|         else: | ||||
|             self._write(_MADCTL, b"\x08") | ||||
| 
 | ||||
|         for command, data in ( | ||||
|             (_PIXSET, b"\x55"), | ||||
|             (_FRMCTR1, b"\x00\x18"), | ||||
|             (_DISCTRL, b"\x08\x82\x27"), | ||||
|             (_ENA3G, b"\x00"), | ||||
|             (_GAMSET, b"\x01"), | ||||
|             (_PGAMCTRL, b"\x0f\x31\x2b\x0c\x0e\x08\x4e\xf1\x37\x07\x10\x03\x0e\x09\x00"), | ||||
|             (_NGAMCTRL, b"\x00\x0e\x14\x03\x11\x07\x31\xc1\x48\x08\x0f\x0c\x31\x36\x0f")): | ||||
|             self._write(command, data) | ||||
|         self._write(_SLPOUT) | ||||
|         time.sleep_ms(120) | ||||
|         self._write(_DISPON) | ||||
| 
 | ||||
|     def reset(self): | ||||
|         self.rst(0) | ||||
|         time.sleep_ms(50) | ||||
|         self.rst(1) | ||||
|         time.sleep_ms(50) | ||||
| 
 | ||||
|     def _write(self, command, data=None): | ||||
|         self.dc(0) | ||||
|         self.cs(0) | ||||
|         self.spi.write(bytearray([command])) | ||||
|         self.cs(1) | ||||
|         if data is not None: | ||||
|             self._data(data) | ||||
| 
 | ||||
|     def _data(self, data): | ||||
|         self.dc(1) | ||||
|         self.cs(0) | ||||
|         self.spi.write(data) | ||||
|         self.cs(1) | ||||
| 
 | ||||
|     def _writeblock(self, x0, y0, x1, y1, data=None): | ||||
|         self._write(_CASET, ustruct.pack(">HH", x0, x1)) | ||||
|         self._write(_PASET, ustruct.pack(">HH", y0, y1)) | ||||
|         self._write(_RAMWR, data) | ||||
| 
 | ||||
|     def _readblock(self, x0, y0, x1, y1, data=None): | ||||
|         self._write(_CASET, ustruct.pack(">HH", x0, x1)) | ||||
|         self._write(_PASET, ustruct.pack(">HH", y0, y1)) | ||||
|         if data is None: | ||||
|             return self._read(_RAMRD, (x1 - x0 + 1) * (y1 - y0 + 1) * 3) | ||||
| 
 | ||||
|     def _read(self, command, count): | ||||
|         self.dc(0) | ||||
|         self.cs(0) | ||||
|         self.spi.write(bytearray([command])) | ||||
|         data = self.spi.read(count) | ||||
|         self.cs(1) | ||||
|         return data | ||||
| 
 | ||||
|     def pixel(self, x, y, color=None): | ||||
|         if color is None: | ||||
|             r, b, g = self._readblock(x, y, x, y) | ||||
|             return color565(r, g, b) | ||||
|         if not 0 <= x < self.width or not 0 <= y < self.height: | ||||
|             return | ||||
|         self._writeblock(x, y, x, y, ustruct.pack(">H", color)) | ||||
| 
 | ||||
|     def fill_rectangle(self, x, y, w, h, color=None): | ||||
|         x = min(self.width - 1, max(0, x)) | ||||
|         y = min(self.height - 1, max(0, y)) | ||||
|         w = min(self.width - x, max(1, w)) | ||||
|         h = min(self.height - y, max(1, h)) | ||||
|         if color: | ||||
|             color = ustruct.pack(">H", color) | ||||
|         else: | ||||
|             color = self._colormap[0:2] #background | ||||
|         for i in range(_CHUNK): | ||||
|             self._buf[2*i]=color[0]; self._buf[2*i+1]=color[1] | ||||
|         chunks, rest = divmod(w * h, _CHUNK) | ||||
|         self._writeblock(x, y, x + w - 1, y + h - 1, None) | ||||
|         if chunks: | ||||
|             for count in range(chunks): | ||||
|                 self._data(self._buf) | ||||
|         if rest != 0: | ||||
|             mv = memoryview(self._buf) | ||||
|             self._data(mv[:rest*2]) | ||||
| 
 | ||||
|     def erase(self): | ||||
|         self.fill_rectangle(0, 0, self.width, self.height) | ||||
| 
 | ||||
|     def blit(self, bitbuff, x, y, w, h): | ||||
|         x = min(self.width - 1, max(0, x)) | ||||
|         y = min(self.height - 1, max(0, y)) | ||||
|         w = min(self.width - x, max(1, w)) | ||||
|         h = min(self.height - y, max(1, h)) | ||||
|         chunks, rest = divmod(w * h, _CHUNK) | ||||
|         self._writeblock(x, y, x + w - 1, y + h - 1, None) | ||||
|         written = 0 | ||||
|         for iy in range(h): | ||||
|             for ix in range(w): | ||||
|                 index = ix+iy*w - written | ||||
|                 if index >=_CHUNK: | ||||
|                     self._data(self._buf) | ||||
|                     written += _CHUNK | ||||
|                     index   -= _CHUNK | ||||
|                 c = bitbuff.pixel(ix,iy) | ||||
|                 self._buf[index*2] = self._colormap[c*2] | ||||
|                 self._buf[index*2+1] = self._colormap[c*2+1] | ||||
|         rest = w*h - written | ||||
|         if rest != 0: | ||||
|             mv = memoryview(self._buf) | ||||
|             self._data(mv[:rest*2]) | ||||
| 
 | ||||
|     def chars(self, str, x, y): | ||||
|         str_w  = self._font.get_width(str) | ||||
|         div, rem = divmod(self._font.height(),8) | ||||
|         nbytes = div+1 if rem else div | ||||
|         buf = bytearray(str_w * nbytes) | ||||
|         pos = 0 | ||||
|         for ch in str: | ||||
|             glyph, char_w = self._font.get_ch(ch) | ||||
|             for row in range(nbytes): | ||||
|                 index = row*str_w + pos | ||||
|                 for i in range(char_w): | ||||
|                     buf[index+i] = glyph[nbytes*i+row] | ||||
|             pos += char_w | ||||
|         fb = framebuf.FrameBuffer(buf,str_w, self._font.height(), framebuf.MONO_VLSB) | ||||
|         self.blit(fb,x,y,str_w,self._font.height()) | ||||
|         return x+str_w | ||||
| 
 | ||||
|     def scroll(self, dy): | ||||
|         self._scroll = (self._scroll + dy) % self.height | ||||
|         self._write(_VSCRSADD, ustruct.pack(">H", self._scroll)) | ||||
| 
 | ||||
|     def next_line(self, cury, char_h): | ||||
|         global scrolling | ||||
|         if not self.scrolling: | ||||
|             res = cury + char_h | ||||
|             self.scrolling = (res >= self.height) | ||||
|         if self.scrolling: | ||||
|             self.scroll(char_h) | ||||
|             res = (self.height - char_h + self._scroll)%self.height | ||||
|             self.fill_rectangle(0, res, self.width, self._font.height()) | ||||
|         return res | ||||
| 
 | ||||
|     def write(self, text): #does character wrap, compatible with stream output | ||||
|         curx = self._x; cury = self._y | ||||
|         char_h = self._font.height() | ||||
|         width = 0 | ||||
|         written = 0 | ||||
|         for pos, ch in enumerate(text): | ||||
|             if ch == '\n': | ||||
|                 if pos>0: | ||||
|                     self.chars(text[written:pos],curx,cury) | ||||
|                 curx = 0; written = pos+1; width = 0 | ||||
|                 cury = self.next_line(cury,char_h) | ||||
|             else: | ||||
|                 char_w = self._font.get_width(ch) | ||||
|                 if curx + width + char_w >= self.width: | ||||
|                     self.chars(text[written:pos], curx,cury) | ||||
|                     curx = 0 ; written = pos; width = char_h | ||||
|                     cury = self.next_line(cury,char_h) | ||||
|                 else: | ||||
|                     width += char_w | ||||
|         if written<len(text): | ||||
|             curx = self.chars(text[written:], curx,cury) | ||||
|         self._x = curx; self._y = cury | ||||
| 
 | ||||
| 
 | ||||
|     def print(self, text): #does word wrap, leaves self._x unchanged | ||||
|         cury = self._y; curx = self._x | ||||
|         char_h = self._font.height() | ||||
|         char_w = self._font.max_width() | ||||
|         lines = text.split('\n') | ||||
|         for line in lines: | ||||
|             words = line.split(' ') | ||||
|             for word in words: | ||||
|                 if curx + self._font.get_width(word) >= self.width: | ||||
|                     curx = self._x; cury = self.next_line(cury,char_h) | ||||
|                     while self._font.get_width(word) > self.width: | ||||
|                         self.chars(word[:self.width//char_w],curx,cury) | ||||
|                         word = word[self.width//char_w:] | ||||
|                         cury = self.next_line(cury,char_h) | ||||
|                 if len(word)>0: | ||||
|                     curx = self.chars(word+' ', curx,cury) | ||||
|             curx = self._x; cury = self.next_line(cury,char_h) | ||||
|         self._y = cury | ||||
							
								
								
									
										24
									
								
								src/m5stack.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								src/m5stack.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| 
 | ||||
| # This file is part of MicroPython M5Stack package | ||||
| # Copyright (c) 2017 Mika Tuupola | ||||
| # | ||||
| # Licensed under the MIT license: | ||||
| #   http://www.opensource.org/licenses/mit-license.php | ||||
| # | ||||
| # Project home: | ||||
| #   https://github.com/tuupola/micropython-m5stacj | ||||
| 
 | ||||
| from micropython import const | ||||
| 
 | ||||
| BUTTON_A_PIN = const(39) | ||||
| BUTTON_B_PIN = const(38) | ||||
| BUTTON_C_PIN = const(37) | ||||
| SPEAKER_PIN = const(25) | ||||
| 
 | ||||
| TFT_LED_PIN = const(32) | ||||
| TFT_DC_PIN = const(27) | ||||
| TFT_CS_PIN = const(14) | ||||
| TFT_MOSI_PIN = const(23) | ||||
| TFT_CLK_PIN = const(18) | ||||
| TFT_RST_PIN = const(33) | ||||
| TFT_MISO_PIN = const(19) | ||||
							
								
								
									
										365
									
								
								src/main.py
									
										
									
									
									
								
							
							
						
						
									
										365
									
								
								src/main.py
									
										
									
									
									
								
							|  | @ -1,299 +1,128 @@ | |||
| from machine import Pin, I2C, Timer, UART | ||||
| import uasyncio | ||||
| import json | ||||
| # test of printing multiple fonts to the ILI9341 on an M5Stack using H/W SP | ||||
| # MIT License; Copyright (c) 2017 Jeffrey N. Magee | ||||
| 
 | ||||
| import ssd1306 | ||||
| from ili934xnew import ILI9341, color565 | ||||
| from machine import Pin, SPI,Timer | ||||
| import m5stack | ||||
| import tt14 | ||||
| import glcdfont | ||||
| import tt14 | ||||
| import tt24 | ||||
| import tt32 | ||||
| from rotary_irq_esp import RotaryIRQ | ||||
| from dshot import Dshot | ||||
| from pid import PID | ||||
| 
 | ||||
| 
 | ||||
| def splash(): | ||||
|     # display.fill(0) | ||||
|     # display.fill_rect(0, 0, 32, 32, 1) | ||||
|     # display.fill_rect(2, 2, 28, 28, 0) | ||||
|     # display.vline(9, 8, 22, 1) | ||||
|     # display.vline(16, 2, 22, 1) | ||||
|     # display.vline(23, 8, 22, 1) | ||||
|     # display.fill_rect(26, 24, 2, 4, 1) | ||||
|     # display.text("MicroPython", 40, 0, 1) | ||||
|     # display.text("SSD1306", 40, 12, 1) | ||||
|     # display.text("OLED 128x64", 40, 24, 1) | ||||
| 
 | ||||
|     display.fill(0) | ||||
|     display.text("SPIN", 34, 4, 1) | ||||
|     display.text("COATER", 50, 14, 1) | ||||
| 
 | ||||
|     display.show() | ||||
| 
 | ||||
| 
 | ||||
| def start_view(state, rotary): | ||||
|     display.text("SPIN", 34, 4, 1) | ||||
|     display.text("COATER", 50, 14, 1) | ||||
| 
 | ||||
|     before = "> " if rotary.value() == 0 else "  " | ||||
|     display.text(before + "Edit", 12, 36, 1) | ||||
|     before = "> " if rotary.value() == 1 else "  " | ||||
|     display.text(before + "Start", 12, 46, 1) | ||||
| 
 | ||||
| 
 | ||||
| def draw_edit_menu(state, rotary): | ||||
|     display.text("Deposit speed:", 0, 0, 1) | ||||
|     display.text("{: >{w}} RPM".format(config["deposit_rpm"], w=5), 56, 10, 1) | ||||
|     display.text("Coating speed:", 0, 21, 1) | ||||
|     display.text("{: >{w}} RPM".format(config["coating_rpm"], w=5), 56, 31, 1) | ||||
|     display.text("Coating time:", 0, 42, 1) | ||||
|     display.text("{: >{w}} sec".format(config["coating_time"], w=5), 56, 52, 1) | ||||
| 
 | ||||
| 
 | ||||
| def edit_deposit_view(state, rotary): | ||||
|     config["deposit_rpm"] = rotary.value() * 100 | ||||
|     draw_edit_menu(state, rotary) | ||||
|     display.text(">", 40, 10, 1) | ||||
| 
 | ||||
| 
 | ||||
| def edit_coating_rpm_view(state, rotary): | ||||
|     config["coating_rpm"] = rotary.value() * 100 | ||||
|     draw_edit_menu(state, rotary) | ||||
|     display.text(">", 40, 32, 1) | ||||
| 
 | ||||
| 
 | ||||
| def edit_coating_time_view(state, rotary): | ||||
|     config["coating_time"] = rotary.value() | ||||
|     draw_edit_menu(state, rotary) | ||||
|     display.text(">", 40, 54, 1) | ||||
| 
 | ||||
| 
 | ||||
| def draw_rpm(rpm): | ||||
|     display.text("RPM:{: >{w}.0f}".format(rpm, w=5), 30, 27, 1) | ||||
| 
 | ||||
| 
 | ||||
| def deposit_view(state, rotary): | ||||
|     display.fill_rect(0, 0, 127, 14, 1) | ||||
|     display.text("Deposit", 36, 3, 0) | ||||
|     draw_rpm(state["rpm"]) | ||||
|     display.text("Press to", 32, 42, 1) | ||||
|     display.text("continue", 32, 52, 1) | ||||
| 
 | ||||
| 
 | ||||
| def coating_view(state, rotary): | ||||
|     display.fill_rect(0, 0, 127, 14, 1) | ||||
|     display.text("Coating", 36, 3, 0) | ||||
|     draw_rpm(state["rpm"]) | ||||
|     display.text("{: >{w}} sec".format(state["timer"], w=4), 30, 48, 1) | ||||
| 
 | ||||
| 
 | ||||
| def decode_ESC_telemetry(data, motor_poles=14): | ||||
|     if len(data) > 10: | ||||
|         # use latest telemetry | ||||
|         data = data[-10:] | ||||
| 
 | ||||
|     temperature = int(data[0])  # degrees Celsius | ||||
|     voltage = int((data[1] << 8) | data[2]) * 0.01  # Volt | ||||
|     current = ( | ||||
|         int((data[3] << 8) | data[4]) * 0.01 | ||||
|     )  # Amps, only available if the ESC has a current meter | ||||
|     consumption = int( | ||||
|         (data[5] << 8) | data[6] | ||||
|     )  # mAh, only available if the ESC has a current meter | ||||
|     erpm = int((data[7] << 8) | data[8]) * 100 | ||||
|     rpm = erpm / (motor_poles / 2) | ||||
|     crc = data[9] | ||||
| 
 | ||||
|     # print("         Temp (C):", temperature) | ||||
|     # print("      Voltage (V):", voltage) | ||||
|     # print("      Current (A):", current) | ||||
|     # print("Consumption (mAh):", consumption) | ||||
|     # print("             Erpm:", erpm) | ||||
|     # print("              RPM:", rpm) | ||||
|     # print("              CRC:", crc) | ||||
|     # print() | ||||
| 
 | ||||
|     return temperature, voltage, current, consumption, erpm, rpm | ||||
| 
 | ||||
| 
 | ||||
| async def update_display(): | ||||
|     global state | ||||
|     global rotary | ||||
|     while True: | ||||
|         display.fill(0) | ||||
|         state["view"](state, rotary) | ||||
|         display.show() | ||||
|         await uasyncio.sleep_ms(33) | ||||
| 
 | ||||
| 
 | ||||
| async def update_motor(): | ||||
|     global state | ||||
|     dshot = Dshot(pin=Pin(18)) | ||||
|     rpm_pid = PID( | ||||
|         Kp=config["PID"]["Kp"], | ||||
|         Ki=config["PID"]["Ki"], | ||||
|         Kd=config["PID"]["Kd"], | ||||
|         setpoint=0, | ||||
|         sample_time=None, | ||||
|         output_limits=(0.0, 1.0), | ||||
|         # proportional_on_measurement=True, | ||||
|     ) | ||||
|     while True: | ||||
|         rpm_pid.setpoint = state["target_rpm"] | ||||
| 
 | ||||
|         # read ESC telemetry | ||||
|         if uart.any() >= 10: | ||||
|             telemetry = decode_ESC_telemetry(uart.read()) | ||||
|             if telemetry is not None: | ||||
|                 state["rpm"] = telemetry[5] | ||||
|                 throttle = rpm_pid(state["rpm"]) | ||||
|                 # print( | ||||
|                 #     "Throttle:", | ||||
|                 #     throttle, | ||||
|                 #     "pid components:", | ||||
|                 #     rpm_pid.components, | ||||
|                 #     "RPM:", | ||||
|                 #     state["rpm"], | ||||
|                 # ) | ||||
| 
 | ||||
|         if state["target_rpm"] == 0 and state["rpm"] < 1000: | ||||
|             throttle = 0 | ||||
|             rpm_pid.reset() | ||||
|         dshot.set_throttle(throttle) | ||||
| 
 | ||||
|         await uasyncio.sleep_ms(1) | ||||
| 
 | ||||
| 
 | ||||
| fonts = [glcdfont,tt14,tt24,tt32] | ||||
| def debounce_button(p): | ||||
|     p.irq(trigger=Pin.IRQ_FALLING, handler=None)  # remove irq | ||||
|     timer0 = Timer(0) | ||||
|     print("Button debounced!") | ||||
|     timer0.init(period=20, mode=Timer.ONE_SHOT, callback=lambda t: on_button_press(p)) | ||||
| 
 | ||||
| 
 | ||||
| def on_button_press(p): | ||||
|     p.irq(trigger=Pin.IRQ_FALLING, handler=debounce_button)  # restore irq | ||||
|     print("Button pressed") | ||||
|     if p.value() == 1:  # debounce | ||||
|         return | ||||
|     global state | ||||
|     global config | ||||
|     global rotary | ||||
|     if state["view"] == start_view: | ||||
|         if rotary.value() == 0: | ||||
|             state["view"] = edit_deposit_view | ||||
|             rotary.set( | ||||
|                 min_val=0, | ||||
|                 max_val=1000, | ||||
|                 range_mode=RotaryIRQ.RANGE_BOUNDED, | ||||
|                 value=int(0.01 * config["deposit_rpm"]), | ||||
|             ) | ||||
|             return | ||||
|         if rotary.value() == 1: | ||||
|             state["view"] = deposit_view | ||||
|             state["target_rpm"] = config["deposit_rpm"] | ||||
|             return | ||||
|     if state["view"] == edit_deposit_view: | ||||
|         state["view"] = edit_coating_rpm_view | ||||
|         rotary.set( | ||||
|             min_val=0, | ||||
|             max_val=1000, | ||||
|             range_mode=RotaryIRQ.RANGE_BOUNDED, | ||||
|             value=int(0.01 * config["coating_rpm"]), | ||||
|         ) | ||||
|         return | ||||
|     if state["view"] == edit_coating_rpm_view: | ||||
|         state["view"] = edit_coating_time_view | ||||
|         rotary.set( | ||||
|             min_val=0, | ||||
|             max_val=9999, | ||||
|             range_mode=RotaryIRQ.RANGE_BOUNDED, | ||||
|             value=config["coating_time"], | ||||
|         ) | ||||
|         return | ||||
|     if state["view"] == edit_coating_time_view: | ||||
|         save_config() | ||||
|         rotary.set(min_val=0, max_val=1, range_mode=RotaryIRQ.RANGE_BOUNDED, value=0) | ||||
|         state["view"] = start_view | ||||
|         return | ||||
|     if state["view"] == deposit_view: | ||||
|         state["view"] = coating_view | ||||
|         start_coating(state) | ||||
|         return | ||||
|     if state["view"] == coating_view: | ||||
|         stop_coating() | ||||
|         return | ||||
|      | ||||
|     #     return | ||||
|     # global state | ||||
|     # global config | ||||
|     # global rotary | ||||
|     # if state["view"] == start_view: | ||||
|     #     if rotary.value() == 0: | ||||
|     #         state["view"] = edit_deposit_view | ||||
|     #         rotary.set( | ||||
|     #             min_val=0, | ||||
|     #             max_val=1000, | ||||
|     #             range_mode=RotaryIRQ.RANGE_BOUNDED, | ||||
|     #             value=int(0.01 * config["deposit_rpm"]), | ||||
|     #         ) | ||||
|     #         return | ||||
|     #     if rotary.value() == 1: | ||||
|     #         state["view"] = deposit_view | ||||
|     #         state["target_rpm"] = config["deposit_rpm"] | ||||
|     #         return | ||||
|     # if state["view"] == edit_deposit_view: | ||||
|     #     state["view"] = edit_coating_rpm_view | ||||
|     #     rotary.set( | ||||
|     #         min_val=0, | ||||
|     #         max_val=1000, | ||||
|     #         range_mode=RotaryIRQ.RANGE_BOUNDED, | ||||
|     #         value=int(0.01 * config["coating_rpm"]), | ||||
|     #     ) | ||||
|     #     return | ||||
|     # if state["view"] == edit_coating_rpm_view: | ||||
|     #     state["view"] = edit_coating_time_view | ||||
|     #     rotary.set( | ||||
|     #         min_val=0, | ||||
|     #         max_val=9999, | ||||
|     #         range_mode=RotaryIRQ.RANGE_BOUNDED, | ||||
|     #         value=config["coating_time"], | ||||
|     #     ) | ||||
|     #     return | ||||
|     # if state["view"] == edit_coating_time_view: | ||||
|     #     save_config() | ||||
|     #     rotary.set(min_val=0, max_val=1, range_mode=RotaryIRQ.RANGE_BOUNDED, value=0) | ||||
|     #     state["view"] = start_view | ||||
|     #     return | ||||
|     # if state["view"] == deposit_view: | ||||
|     #     state["view"] = coating_view | ||||
|     #     start_coating(state) | ||||
|     #     return | ||||
|     # if state["view"] == coating_view: | ||||
|     #     stop_coating() | ||||
|     #     return | ||||
| 
 | ||||
| 
 | ||||
| def start_coating(state): | ||||
|     global timer1 | ||||
|     global timer2 | ||||
| 
 | ||||
|     state["timer"] = config["coating_time"] | ||||
| text = 'Now is the time for all good men to come to the aid of the party.' | ||||
| 
 | ||||
|     timer1.init( | ||||
|         period=config["coating_time"] * 1000, | ||||
|         mode=Timer.ONE_SHOT, | ||||
|         callback=lambda t: stop_coating(), | ||||
|     ) | ||||
| 
 | ||||
|     def decrement_timer(t): | ||||
|         state["timer"] -= 1 | ||||
| 
 | ||||
|     timer2.init(period=1000, mode=Timer.PERIODIC, callback=decrement_timer) | ||||
| 
 | ||||
|     # state["throttle"] = 0.10 | ||||
|     state["target_rpm"] = config["coating_rpm"] | ||||
| power = Pin(m5stack.TFT_LED_PIN, Pin.OUT) | ||||
| power.value(1) | ||||
| 
 | ||||
| 
 | ||||
| def stop_coating(): | ||||
|     global state | ||||
|     global rotary | ||||
|     global timer1 | ||||
|     global timer2 | ||||
|     timer1.deinit() | ||||
|     timer2.deinit() | ||||
|     state["target_rpm"] = 0 | ||||
|     rotary.set(min_val=0, max_val=1, range_mode=RotaryIRQ.RANGE_BOUNDED, value=0) | ||||
|     state["view"] = start_view | ||||
| # No need to change the software. It's just a matter of different names.. Use this translation: | ||||
| 
 | ||||
| # SDO(MISO)	<not used> | ||||
| # LED		BL | ||||
| # SCK		CLK/SCK | ||||
| # SDI(MOSI)	DIN/SDA | ||||
| # DC		D/C (A0) | ||||
| # RESET		RST | ||||
| # CS		CS | ||||
| # GND		GND | ||||
| # VCC		VCC | ||||
| print("BOOOOOOTTTT") | ||||
| spi = SPI( | ||||
|     2, | ||||
|     baudrate=40000000, | ||||
|     miso=Pin(m5stack.TFT_MISO_PIN), | ||||
|     mosi=Pin(m5stack.TFT_MOSI_PIN), | ||||
|     sck=Pin(m5stack.TFT_CLK_PIN)) | ||||
| 
 | ||||
| def save_config(): | ||||
|     global config | ||||
|     with open("config.json", "w") as f: | ||||
|         json.dump(config, f) | ||||
| 
 | ||||
| 
 | ||||
| # using default address 0x3c | ||||
| i2c = I2C(1, sda=Pin(21), scl=Pin(22)) | ||||
| display = ssd1306.SSD1306_I2C(128, 64, i2c) | ||||
| display.rotate(0) | ||||
| 
 | ||||
| timer1 = Timer(1) | ||||
| timer2 = Timer(2) | ||||
| 
 | ||||
| 
 | ||||
| splash() | ||||
| 
 | ||||
| display = ILI9341( | ||||
|     spi, | ||||
|     cs=Pin(m5stack.TFT_CS_PIN), | ||||
|     dc=Pin(m5stack.TFT_DC_PIN), | ||||
|     rst=Pin(m5stack.TFT_RST_PIN), | ||||
|     w=128, | ||||
|     h=160, | ||||
|     r=3) | ||||
| rotary = RotaryIRQ( | ||||
|     pin_num_clk=14, | ||||
|     pin_num_clk=25, | ||||
|     pin_num_dt=13, | ||||
|     min_val=0, | ||||
|     max_val=1, | ||||
|     range_mode=RotaryIRQ.RANGE_BOUNDED, | ||||
|     pull_up=True, | ||||
| ) | ||||
| 
 | ||||
| button = Pin(19, Pin.IN, Pin.PULL_UP) | ||||
| button = Pin(15, Pin.IN, Pin.PULL_UP) | ||||
| button.irq(trigger=Pin.IRQ_FALLING, handler=on_button_press) | ||||
| 
 | ||||
| uart = UART(1, baudrate=115200, rx=5)  # to receive ESC telemetry | ||||
| 
 | ||||
| state = { | ||||
|     "view": start_view, | ||||
|     "rpm": 0, | ||||
|     "target_rpm": 0, | ||||
|     "timer": 0, | ||||
| } | ||||
| display.erase() | ||||
| display.set_pos(0,0) | ||||
| for ff in fonts: | ||||
|     display.set_font(ff) | ||||
|     display.print(text) | ||||
| 
 | ||||
| with open("config.json", "r") as f: | ||||
|     config = json.load(f) | ||||
| 
 | ||||
| event_loop = uasyncio.get_event_loop() | ||||
| event_loop.create_task(update_display()) | ||||
| event_loop.create_task(update_motor()) | ||||
| event_loop.run_forever() | ||||
|  |  | |||
|  | @ -90,7 +90,7 @@ class Rotary(object): | |||
|             max_val=None, reverse=None, range_mode=None): | ||||
|         # disable DT and CLK pin interrupts | ||||
|         self._hal_disable_irq() | ||||
| 
 | ||||
|         #print("SETTING VALUE!") | ||||
|         if value is not None: | ||||
|             self._value = value | ||||
|         if min_val is not None: | ||||
|  | @ -124,6 +124,7 @@ class Rotary(object): | |||
|         self._listener.remove(l) | ||||
|          | ||||
|     def _process_rotary_pins(self, pin): | ||||
|         print(self._value) | ||||
|         old_value = self._value | ||||
|         clk_dt_pins = (self._hal_get_clk_value() << | ||||
|                        1) | self._hal_get_dt_value() | ||||
|  |  | |||
							
								
								
									
										16
									
								
								src/rotations_test.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/rotations_test.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| from ili934xnew import ILI9341, color565 | ||||
| from machine import Pin, SPI | ||||
| import tt14 | ||||
| 
 | ||||
| text = 'F' | ||||
| spi = SPI(2, baudrate=20000000, miso=Pin(19),mosi=Pin(23), sck=Pin(18)) | ||||
| display = ILI9341(spi, cs=Pin(2), dc=Pin(27), rst=Pin(33), w=320, h=240, r=0) | ||||
| display.erase() | ||||
| display.set_font(tt14) | ||||
| display.set_pos(0,0) | ||||
| display.print(text) | ||||
| display.set_pos(0,20) | ||||
| display.print(text) | ||||
| display.set_pos(40,20) | ||||
| display.print(text) | ||||
| 
 | ||||
							
								
								
									
										159
									
								
								src/tt14.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								src/tt14.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,159 @@ | |||
| # Code generated by font-to-py.py. | ||||
| # Font: CM Sans Serif 2012.ttf | ||||
| version = '0.2' | ||||
| 
 | ||||
| def height(): | ||||
|     return 15 | ||||
| 
 | ||||
| def max_width(): | ||||
|     return 12 | ||||
| 
 | ||||
| def hmap(): | ||||
|     return False | ||||
| 
 | ||||
| def reverse(): | ||||
|     return False | ||||
| 
 | ||||
| def monospaced(): | ||||
|     return False | ||||
| 
 | ||||
| def min_ch(): | ||||
|     return 32 | ||||
| 
 | ||||
| def max_ch(): | ||||
|     return 126 | ||||
| 
 | ||||
| _font =\ | ||||
| b'\x08\x00\x08\x00\x0c\x00\x8c\x07\xcc\x07\xcc\x00\x7c\x00\x38\x00'\ | ||||
| b'\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\xfc\x06'\ | ||||
| b'\xfc\x06\x00\x00\x05\x00\x1c\x00\x3c\x00\x00\x00\x3c\x00\x00\x00'\ | ||||
| b'\x07\x00\x40\x03\xf0\x03\xf0\x03\x30\x03\xf0\x03\x30\x03\x30\x00'\ | ||||
| b'\x07\x00\x30\x00\x78\x03\x6c\x02\xfc\x07\xd8\x03\x90\x03\x00\x00'\ | ||||
| b'\x0b\x00\x18\x00\x3c\x00\x3c\x04\x3c\x03\xd8\x01\xf0\x03\xd8\x07'\ | ||||
| b'\xc4\x06\xc0\x07\x80\x03\x00\x00\x09\x00\x80\x03\xf8\x07\x7c\x06'\ | ||||
| b'\x4c\x06\xfc\x06\x98\x07\xc0\x07\xc0\x05\x00\x04\x02\x00\x1c\x00'\ | ||||
| b'\x3c\x00\x04\x00\xf0\x03\xfc\x0f\x0e\x1c\x02\x10\x05\x00\x02\x10'\ | ||||
| b'\x0e\x1c\xfc\x0f\xf0\x03\x00\x00\x05\x00\x0c\x00\x3c\x00\x18\x00'\ | ||||
| b'\x2c\x00\x0c\x00\x07\x00\xc0\x00\xc0\x00\xf0\x03\xf0\x03\xc0\x00'\ | ||||
| b'\xc0\x00\x00\x00\x03\x00\x00\x16\x00\x0e\x00\x00\x04\x00\xc0\x00'\ | ||||
| b'\xc0\x00\xc0\x00\xc0\x00\x03\x00\x00\x06\x00\x06\x00\x00\x04\x00'\ | ||||
| b'\x00\x06\xe0\x07\xfc\x00\x0e\x00\x08\x00\xf0\x01\xf8\x03\x1c\x07'\ | ||||
| b'\x0c\x06\x1c\x07\xf8\x03\xf0\x01\x00\x00\x04\x00\x18\x00\xfc\x07'\ | ||||
| b'\xfc\x07\x00\x00\x08\x00\x18\x04\x1c\x07\x8c\x06\x8c\x06\x4c\x06'\ | ||||
| b'\x7c\x06\x38\x06\x00\x00\x07\x00\x08\x02\x0c\x06\x0c\x06\x6c\x06'\ | ||||
| b'\x6c\x06\xfc\x07\xd8\x03\x07\x00\x80\x01\xe0\x01\xb0\x01\x9c\x01'\ | ||||
| b'\xfc\x07\xfc\x07\x80\x01\x07\x00\x00\x02\xfc\x06\x6c\x06\x6c\x06'\ | ||||
| b'\x6c\x06\xcc\x03\xc0\x03\x08\x00\xf0\x01\xf8\x03\x6c\x06\x6c\x06'\ | ||||
| b'\x6c\x06\xe8\x07\xc0\x03\x00\x00\x06\x00\x0c\x00\x0c\x07\xcc\x07'\ | ||||
| b'\xfc\x00\x1c\x00\x0c\x00\x07\x00\x98\x03\xfc\x07\x6c\x06\x6c\x06'\ | ||||
| b'\x6c\x06\xfc\x07\x98\x03\x08\x00\x78\x02\xfc\x06\xcc\x06\xcc\x06'\ | ||||
| b'\xcc\x06\xf8\x03\xf0\x01\x00\x00\x03\x00\x30\x06\x30\x06\x00\x00'\ | ||||
| b'\x03\x00\x30\x16\x30\x0e\x00\x00\x06\x00\xc0\x01\xc0\x01\x60\x03'\ | ||||
| b'\x60\x03\x30\x06\x00\x00\x06\x00\x60\x03\x60\x03\x60\x03\x60\x03'\ | ||||
| b'\x60\x03\x60\x03\x06\x00\x30\x06\x60\x03\x60\x03\x40\x01\xc0\x01'\ | ||||
| b'\x00\x00\x08\x00\x08\x00\x0c\x00\x8c\x07\xcc\x07\xcc\x00\x7c\x00'\ | ||||
| b'\x38\x00\x00\x00\x0b\x00\xe0\x00\xf8\x01\x18\x03\xec\x07\xbc\x07'\ | ||||
| b'\xfc\x06\xfc\x07\x9c\x03\xf8\x01\xf0\x00\x00\x00\x08\x00\x00\x06'\ | ||||
| b'\x80\x07\xf0\x01\x9c\x01\x8c\x01\xf8\x01\xc0\x07\x00\x07\x08\x00'\ | ||||
| b'\xfc\x07\xfc\x07\x6c\x06\x6c\x06\x6c\x06\xfc\x07\xd8\x03\x00\x00'\ | ||||
| b'\x09\x00\xe0\x00\xf8\x03\x18\x03\x0c\x06\x0c\x06\x0c\x06\x1c\x07'\ | ||||
| b'\x18\x03\x20\x01\x09\x00\xfc\x07\xfc\x07\x0c\x06\x0c\x06\x1c\x07'\ | ||||
| b'\xf8\x03\xf0\x01\x00\x00\x00\x00\x08\x00\xfc\x07\xfc\x07\x6c\x06'\ | ||||
| b'\x6c\x06\x6c\x06\x6c\x06\x0c\x06\x00\x00\x07\x00\xfc\x07\xfc\x07'\ | ||||
| b'\xcc\x00\xcc\x00\xcc\x00\xcc\x00\x0c\x00\x0a\x00\xe0\x01\xf8\x03'\ | ||||
| b'\x18\x07\x0c\x06\x0c\x06\xcc\x06\xdc\x02\xd8\x07\xe0\x07\x00\x00'\ | ||||
| b'\x09\x00\xfc\x07\xfc\x07\x60\x00\x60\x00\x60\x00\xfc\x07\xfc\x07'\ | ||||
| b'\x00\x00\x00\x00\x03\x00\xfc\x07\xfc\x07\x00\x00\x07\x00\x80\x03'\ | ||||
| b'\x80\x07\x00\x06\x00\x06\xfc\x07\xfc\x03\x00\x00\x08\x00\xfc\x07'\ | ||||
| b'\xfc\x07\x60\x00\xf0\x00\xd8\x01\x0c\x07\x04\x06\x04\x04\x07\x00'\ | ||||
| b'\xfc\x07\xfc\x07\x00\x06\x00\x06\x00\x06\x00\x06\x00\x00\x0b\x00'\ | ||||
| b'\xfc\x07\xfc\x07\x3c\x00\xe0\x03\x00\x06\xe0\x03\x3c\x00\xfc\x07'\ | ||||
| b'\xfc\x07\x00\x00\x00\x00\x09\x00\xfc\x07\xfc\x07\x38\x00\xe0\x00'\ | ||||
| b'\x80\x03\xfc\x07\xfc\x07\x00\x00\x00\x00\x0a\x00\xf0\x01\xf8\x03'\ | ||||
| b'\x1c\x07\x0c\x06\x0c\x06\x0c\x06\x1c\x07\xf8\x03\xf0\x01\x00\x00'\ | ||||
| b'\x09\x00\xfc\x07\xfc\x07\xcc\x00\xcc\x00\xcc\x00\xfc\x00\x78\x00'\ | ||||
| b'\x00\x00\x00\x00\x0a\x00\xf0\x01\xf8\x03\x1c\x07\x0c\x06\x8c\x06'\ | ||||
| b'\x8c\x07\x1c\x07\xf8\x07\xf0\x05\x00\x00\x09\x00\xfc\x07\xfc\x07'\ | ||||
| b'\xcc\x00\xcc\x00\xcc\x03\x7c\x07\x78\x04\x00\x00\x00\x00\x09\x00'\ | ||||
| b'\x38\x01\x3c\x03\x4c\x06\x4c\x06\x4c\x06\x4c\x06\x98\x07\x90\x03'\ | ||||
| b'\x00\x00\x07\x00\x0c\x00\x0c\x00\xfc\x07\xfc\x07\x0c\x00\x0c\x00'\ | ||||
| b'\x00\x00\x09\x00\xfc\x03\xfc\x07\x00\x06\x00\x06\x00\x06\xfc\x07'\ | ||||
| b'\xfc\x01\x00\x00\x00\x00\x08\x00\x0c\x00\x7c\x00\xe0\x03\x00\x07'\ | ||||
| b'\x80\x07\xf8\x01\x3c\x00\x04\x00\x0b\x00\x0c\x00\xfc\x00\xe0\x07'\ | ||||
| b'\x80\x07\xf8\x03\x1c\x00\xfc\x00\xc0\x07\x80\x07\xfc\x01\x1c\x00'\ | ||||
| b'\x08\x00\x04\x04\x0c\x07\xb8\x03\xf0\x00\xf0\x01\x9c\x07\x0c\x06'\ | ||||
| b'\x04\x04\x08\x00\x04\x00\x1c\x00\x78\x00\xe0\x07\xe0\x07\x78\x00'\ | ||||
| b'\x1c\x00\x04\x00\x07\x00\x0c\x06\x0c\x07\x8c\x07\xcc\x06\x2c\x06'\ | ||||
| b'\x1c\x06\x0c\x06\x04\x00\xff\x1f\xff\x1f\x03\x18\x00\x00\x04\x00'\ | ||||
| b'\x0e\x00\xfe\x00\xe0\x07\x00\x07\x04\x00\x03\x18\xff\x1f\xff\x1f'\ | ||||
| b'\x00\x00\x07\x00\x80\x00\xe0\x00\x7c\x00\x0c\x00\x7c\x00\xe0\x00'\ | ||||
| b'\x80\x00\x0a\x00\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18\x00\x18'\ | ||||
| b'\x00\x18\x00\x18\x00\x18\x00\x18\x05\x00\x04\x00\x0c\x00\x08\x00'\ | ||||
| b'\x00\x00\x00\x00\x08\x00\x00\x03\xe0\x07\xb0\x06\xb0\x06\xb0\x02'\ | ||||
| b'\xf0\x07\xe0\x07\x00\x00\x09\x00\xfe\x07\xfe\x07\x30\x02\x30\x06'\ | ||||
| b'\x30\x06\xe0\x07\xc0\x01\x00\x00\x00\x00\x07\x00\xc0\x01\xe0\x03'\ | ||||
| b'\x30\x06\x30\x06\x30\x06\x60\x03\x40\x01\x08\x00\xc0\x01\xf0\x07'\ | ||||
| b'\x30\x06\x30\x06\x30\x06\xfe\x07\xfe\x07\x00\x00\x07\x00\xc0\x01'\ | ||||
| b'\xe0\x03\xb0\x07\xb0\x07\xb0\x07\xe0\x03\xc0\x01\x04\x00\x20\x00'\ | ||||
| b'\xfc\x07\xfe\x07\x00\x00\x08\x00\xc0\x11\xf0\x1f\x30\x36\x30\x36'\ | ||||
| b'\x20\x36\xf0\x1f\xf0\x0f\x00\x00\x08\x00\xfe\x07\xfe\x07\x30\x00'\ | ||||
| b'\x30\x00\xf0\x07\xe0\x07\x00\x00\x00\x00\x03\x00\xfc\x07\xfc\x07'\ | ||||
| b'\x00\x00\x03\x00\xec\x7f\xec\x3f\x00\x00\x07\x00\xfe\x07\xfe\x07'\ | ||||
| b'\xc0\x00\xe0\x01\xb0\x07\x10\x06\x10\x04\x03\x00\xfe\x07\xfe\x07'\ | ||||
| b'\x00\x00\x0c\x00\xf0\x07\xf0\x07\x30\x00\x30\x00\xf0\x07\xe0\x07'\ | ||||
| b'\x30\x00\x30\x00\xf0\x07\xe0\x07\x00\x00\x00\x00\x08\x00\xf0\x07'\ | ||||
| b'\xf0\x07\x30\x00\x30\x00\xf0\x07\xe0\x07\x00\x00\x00\x00\x08\x00'\ | ||||
| b'\xc0\x01\xe0\x03\x30\x06\x30\x06\x30\x06\xe0\x03\xc0\x01\x00\x00'\ | ||||
| b'\x09\x00\xf0\x3f\xf0\x3f\x30\x06\x30\x06\x30\x06\xf0\x07\xc0\x01'\ | ||||
| b'\x00\x00\x00\x00\x08\x00\xc0\x01\xf0\x07\x30\x06\x30\x06\x30\x06'\ | ||||
| b'\xf0\x3f\xf0\x3f\x00\x00\x04\x00\xf0\x07\xf0\x07\x30\x00\x30\x00'\ | ||||
| b'\x08\x00\x60\x00\x70\x03\xb0\x07\xf0\x06\xb0\x06\xa0\x07\x00\x03'\ | ||||
| b'\x00\x00\x04\x00\x30\x00\xfe\x03\xfe\x07\x00\x00\x08\x00\xf0\x03'\ | ||||
| b'\xf0\x07\x00\x06\x00\x06\xf0\x07\xf0\x07\x00\x00\x00\x00\x07\x00'\ | ||||
| b'\x30\x00\xf0\x00\x80\x07\x00\x06\xc0\x03\xf0\x00\x10\x00\x0a\x00'\ | ||||
| b'\x30\x00\xf0\x01\x80\x07\xc0\x07\xf0\x00\xf0\x00\x80\x07\x80\x07'\ | ||||
| b'\xf0\x01\x30\x00\x07\x00\x10\x04\x30\x07\xe0\x03\xc0\x01\x70\x07'\ | ||||
| b'\x10\x06\x00\x04\x07\x00\x30\x00\xf0\x30\xc0\x3f\x00\x1f\xe0\x03'\ | ||||
| b'\x70\x00\x10\x00\x06\x00\x30\x06\x30\x07\xb0\x07\xf0\x06\x70\x06'\ | ||||
| b'\x30\x06\x05\x00\x40\x00\xbe\x0f\xbe\x0f\x00\x00\x00\x00\x04\x00'\ | ||||
| b'\xfe\x07\xfe\x07\x00\x00\x00\x00\x04\x00\xbe\x0f\xbe\x0f\x40\x00'\ | ||||
| b'\x00\x00\x05\x00\x04\x00\x04\x00\x04\x00\x06\x00\x04\x00' | ||||
| 
 | ||||
| _index =\ | ||||
| b'\x00\x00\x12\x00\x1c\x00\x24\x00\x30\x00\x40\x00\x50\x00\x68\x00'\ | ||||
| b'\x7c\x00\x82\x00\x8c\x00\x98\x00\xa4\x00\xb4\x00\xbc\x00\xc6\x00'\ | ||||
| b'\xce\x00\xd8\x00\xea\x00\xf4\x00\x06\x01\x16\x01\x26\x01\x36\x01'\ | ||||
| b'\x48\x01\x56\x01\x66\x01\x78\x01\x80\x01\x88\x01\x96\x01\xa4\x01'\ | ||||
| b'\xb2\x01\xc4\x01\xdc\x01\xee\x01\x00\x02\x14\x02\x28\x02\x3a\x02'\ | ||||
| b'\x4a\x02\x60\x02\x74\x02\x7c\x02\x8c\x02\x9e\x02\xae\x02\xc6\x02'\ | ||||
| b'\xda\x02\xf0\x02\x04\x03\x1a\x03\x2e\x03\x42\x03\x52\x03\x66\x03'\ | ||||
| b'\x78\x03\x90\x03\xa2\x03\xb4\x03\xc4\x03\xce\x03\xd8\x03\xe2\x03'\ | ||||
| b'\xf2\x03\x08\x04\x14\x04\x26\x04\x3a\x04\x4a\x04\x5c\x04\x6c\x04'\ | ||||
| b'\x76\x04\x88\x04\x9a\x04\xa2\x04\xaa\x04\xba\x04\xc2\x04\xdc\x04'\ | ||||
| b'\xee\x04\x00\x05\x14\x05\x26\x05\x30\x05\x42\x05\x4c\x05\x5e\x05'\ | ||||
| b'\x6e\x05\x84\x05\x94\x05\xa4\x05\xb2\x05\xbe\x05\xc8\x05\xd2\x05'\ | ||||
| b'\xde\x05' | ||||
| 
 | ||||
| _mvfont = memoryview(_font) | ||||
| 
 | ||||
| def _chr_addr(ordch): | ||||
|     offset = 2 * (ordch - 32) | ||||
|     return int.from_bytes(_index[offset:offset + 2], 'little') | ||||
| 
 | ||||
| def get_width(s): | ||||
|     width = 0 | ||||
|     for ch in s: | ||||
|         ordch = ord(ch) | ||||
|         ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 | ||||
|         offset = _chr_addr(ordch) | ||||
|         width += int.from_bytes(_font[offset:offset + 2], 'little') | ||||
|     return width | ||||
| 
 | ||||
| def get_ch(ch): | ||||
|     ordch = ord(ch) | ||||
|     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 _mvfont[offset + 2:next_offs], width | ||||
|   | ||||
							
								
								
									
										286
									
								
								src/tt24.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								src/tt24.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,286 @@ | |||
| # Code generated by font-to-py.py. | ||||
| # Font: CM Sans Serif 2012.ttf | ||||
| version = '0.2' | ||||
| 
 | ||||
| def height(): | ||||
|     return 24 | ||||
| 
 | ||||
| def max_width(): | ||||
|     return 20 | ||||
| 
 | ||||
| def hmap(): | ||||
|     return False | ||||
| 
 | ||||
| def reverse(): | ||||
|     return False | ||||
| 
 | ||||
| def monospaced(): | ||||
|     return False | ||||
| 
 | ||||
| def min_ch(): | ||||
|     return 32 | ||||
| 
 | ||||
| def max_ch(): | ||||
|     return 126 | ||||
| 
 | ||||
| _font =\ | ||||
| b'\x0c\x00\xc0\x00\x00\xf0\x00\x00\xf0\x00\x00\x78\x70\x07\x38\x78'\ | ||||
| b'\x07\x38\x7c\x07\x78\x1e\x00\xf0\x0f\x00\xf0\x07\x00\xc0\x03\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00'\ | ||||
| b'\x00\x02\xf8\x3f\x07\xf8\x3f\x07\xf8\x3f\x02\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x08\x00\xf8\x03\x00\xf8\x03\x00\x08\x00\x00\x00\x00\x00\xf8'\ | ||||
| b'\x03\x00\xf8\x03\x00\x08\x00\x00\x00\x00\x00\x0c\x00\x00\xe0\x00'\ | ||||
| b'\x80\xe3\x00\x80\xf3\x03\xe0\xff\x03\xe0\xff\x00\xe0\xe3\x00\x80'\ | ||||
| b'\xe3\x03\x80\xff\x03\xe0\xff\x01\xe0\xe7\x00\x80\xe3\x00\x80\x03'\ | ||||
| b'\x00\x0b\x00\x00\xe0\x00\xc0\xe3\x01\xe0\xc7\x01\x70\x8e\x03\xf8'\ | ||||
| b'\xef\x07\xf8\xff\x07\x70\x8c\x03\xe0\x9d\x01\xc0\xf9\x01\x00\xf0'\ | ||||
| b'\x00\x00\x00\x00\x12\x00\xe0\x01\x00\xf0\x03\x00\x38\x07\x00\x38'\ | ||||
| b'\x07\x04\x38\x07\x07\x38\xc7\x07\xf0\xf3\x01\xe0\x79\x00\x00\x1e'\ | ||||
| b'\x00\x80\x07\x00\xe0\xe3\x01\xf8\xf0\x03\x38\x38\x07\x08\x38\x07'\ | ||||
| b'\x00\x38\x07\x00\xf0\x03\x00\xe0\x01\x00\x00\x00\x0f\x00\x00\xf0'\ | ||||
| b'\x00\x00\xf8\x01\xe0\xfd\x03\xf0\x8f\x07\xf8\x07\x07\x38\x0e\x07'\ | ||||
| b'\x38\x1f\x07\xf8\x3f\x07\xf0\xfb\x07\xe0\xf0\x07\x00\xe0\x03\x00'\ | ||||
| b'\xf8\x07\x00\xf8\x07\x00\x78\x06\x00\x00\x04\x04\x00\xf8\x03\x00'\ | ||||
| b'\xf8\x03\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x7f\x00\xe0\xff'\ | ||||
| b'\x03\xf8\xff\x0f\x7c\x00\x1f\x0e\x00\x38\x02\x00\x20\x02\x00\x20'\ | ||||
| b'\x07\x00\x02\x00\x20\x0e\x00\x38\x7c\x00\x1f\xf8\xff\x0f\xe0\xff'\ | ||||
| b'\x03\x00\x7f\x00\x00\x00\x00\x09\x00\x60\x00\x00\x60\x00\x00\x78'\ | ||||
| b'\x03\x00\xf0\x01\x00\xe0\x00\x00\xf8\x03\x00\x68\x01\x00\x60\x00'\ | ||||
| b'\x00\x00\x00\x00\x0c\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ | ||||
| b'\x38\x00\x80\xff\x03\x80\xff\x03\x80\xff\x03\x00\x38\x00\x00\x38'\ | ||||
| b'\x00\x00\x38\x00\x00\x38\x00\x00\x00\x00\x05\x00\x00\x00\x37\x00'\ | ||||
| b'\x00\x3f\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x07\x00\x00\x38\x00'\ | ||||
| b'\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ | ||||
| b'\x38\x00\x05\x00\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x08\x00\x00\x00\x06\x00\xe0\x07\x00\xfc\x07\xc0\xff'\ | ||||
| b'\x01\xf8\x3f\x00\xfc\x03\x00\x7c\x00\x00\x04\x00\x00\x0d\x00\x80'\ | ||||
| b'\x7f\x00\xe0\xff\x01\xf0\xff\x03\xf8\xc0\x07\x38\x00\x07\x38\x00'\ | ||||
| b'\x07\x38\x00\x07\xf8\xc0\x07\xf0\xff\x03\xe0\xff\x01\x80\x7f\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x08\x00\xc0\x01\x00\xc0\x01\x00\xe0\x01'\ | ||||
| b'\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x0d\x00\xc0\x81\x07\xe0\xe1\x07\xf0\xe1\x07\x78\x70\x07\x38\x38'\ | ||||
| b'\x07\x38\x38\x07\x38\x1c\x07\x78\x1e\x07\xf0\x0f\x07\xf0\x07\x07'\ | ||||
| b'\xc0\x03\x07\x00\x00\x00\x00\x00\x00\x0c\x00\xc0\xc0\x00\xf0\xc0'\ | ||||
| b'\x03\xf0\xc0\x03\x78\x80\x07\x38\x00\x07\x38\x0e\x07\x38\x0e\x07'\ | ||||
| b'\x78\x9e\x07\xf0\xff\x03\xf0\xff\x03\xe0\xf1\x00\x00\x00\x00\x0c'\ | ||||
| b'\x00\x00\xf0\x00\x00\xf8\x00\x00\xfe\x00\x00\xef\x00\xc0\xe7\x00'\ | ||||
| b'\xf0\xe1\x00\xf8\xe0\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00'\ | ||||
| b'\xe0\x00\x00\xe0\x00\x0c\x00\x00\xce\x00\xf8\xcf\x03\xf8\xcf\x03'\ | ||||
| b'\x38\x8e\x07\x38\x07\x07\x38\x07\x07\x38\x07\x07\x38\x8f\x07\x38'\ | ||||
| b'\xfe\x03\x38\xfc\x01\x00\xf8\x00\x00\x00\x00\x0d\x00\x00\x7f\x00'\ | ||||
| b'\xe0\xff\x01\xf0\xff\x03\x78\x8e\x07\x38\x07\x07\x38\x07\x07\x38'\ | ||||
| b'\x07\x07\x78\x8f\x07\xf0\xfe\x03\xe0\xfc\x01\xc0\xf8\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x0b\x00\x38\x00\x00\x38\x00\x00\x38\xc0\x07\x38'\ | ||||
| b'\xf8\x07\x38\xfe\x07\xb8\x3f\x00\xf8\x07\x00\xf8\x01\x00\xf8\x00'\ | ||||
| b'\x00\x78\x00\x00\x38\x00\x00\x0c\x00\x00\xf0\x00\xe0\xf9\x01\xf0'\ | ||||
| b'\xff\x03\xf0\x9f\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e'\ | ||||
| b'\x07\xf0\x9f\x07\xf0\xff\x03\xe0\xf9\x01\x00\xf0\x00\x0d\x00\xc0'\ | ||||
| b'\x07\x00\xe0\x0f\x01\xf0\x1f\x03\x78\x3c\x07\x38\x38\x07\x38\x38'\ | ||||
| b'\x07\x38\x38\x07\x38\x38\x07\x70\x9c\x07\xf0\xff\x03\xe0\xff\x01'\ | ||||
| b'\x80\x7f\x00\x00\x00\x00\x05\x00\x00\x07\x07\x00\x07\x07\x00\x07'\ | ||||
| b'\x07\x00\x00\x00\x00\x00\x00\x05\x00\x00\x07\x37\x00\x07\x3f\x00'\ | ||||
| b'\x07\x1f\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x38\x00\x00\x38\x00'\ | ||||
| b'\x00\x7c\x00\x00\x6c\x00\x00\xee\x00\x00\xee\x00\x00\xc7\x01\x00'\ | ||||
| b'\xc7\x01\x80\x83\x03\x00\x00\x00\x0b\x00\x00\xce\x01\x00\xce\x01'\ | ||||
| b'\x00\xce\x01\x00\xce\x01\x00\xce\x01\x00\xce\x01\x00\xce\x01\x00'\ | ||||
| b'\xce\x01\x00\xce\x01\x00\xce\x01\x00\x00\x00\x0a\x00\x80\x83\x03'\ | ||||
| b'\x80\x83\x03\x00\xc7\x01\x00\xc7\x01\x00\xee\x00\x00\xee\x00\x00'\ | ||||
| b'\x7c\x00\x00\x7c\x00\x00\x38\x00\x00\x00\x00\x0c\x00\xc0\x00\x00'\ | ||||
| b'\xf0\x00\x00\xf0\x00\x00\x78\x70\x07\x38\x78\x07\x38\x7c\x07\x78'\ | ||||
| b'\x1e\x00\xf0\x0f\x00\xf0\x07\x00\xc0\x03\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x11\x00\x00\x3f\x00\xc0\xff\x00\xe0\xe1\x01\xf0\xc0\x03\x70'\ | ||||
| b'\xbc\x03\x78\x7e\x07\x38\x7f\x07\xb8\x73\x07\xb8\x33\x07\xb8\x3f'\ | ||||
| b'\x07\x38\x7f\x07\x70\xf3\x03\x70\x70\x03\xe0\x38\x02\xe0\x3f\x00'\ | ||||
| b'\x80\x0f\x00\x00\x00\x00\x0f\x00\x00\x00\x06\x00\xc0\x07\x00\xf0'\ | ||||
| b'\x07\x00\xfe\x03\xc0\xff\x00\xf8\xef\x00\xf8\xe1\x00\x78\xe0\x00'\ | ||||
| b'\xf8\xe3\x00\xf0\xff\x00\xc0\xff\x00\x00\xfe\x07\x00\xf0\x07\x00'\ | ||||
| b'\x80\x07\x00\x00\x04\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07'\ | ||||
| b'\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38'\ | ||||
| b'\x9e\x07\xf8\xff\x07\xf0\xff\x03\xe0\xf1\x01\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x10\x00\x00\x3f\x00\xc0\xff\x00\xe0\xff\x01\xf0'\ | ||||
| b'\xe1\x03\x70\x80\x03\x78\x80\x07\x38\x00\x07\x38\x00\x07\x38\x00'\ | ||||
| b'\x07\x38\x00\x07\x78\x80\x03\xf0\xc0\x03\xe0\xc0\x01\xc0\xc0\x00'\ | ||||
| b'\x80\x40\x00\x00\x00\x00\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff'\ | ||||
| b'\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07'\ | ||||
| b'\x78\x80\x07\xf0\xc0\x03\xe0\xff\x01\xc0\xff\x00\x00\x3f\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x0e\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07'\ | ||||
| b'\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38\x0e\x07\x38'\ | ||||
| b'\x0e\x07\x38\x0e\x07\x38\x00\x07\x38\x00\x07\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x0d\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x38\x1c\x00\x38'\ | ||||
| b'\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c'\ | ||||
| b'\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x3f\x00\xc0'\ | ||||
| b'\xff\x00\xe0\xff\x01\xf0\xe1\x03\x70\x80\x03\x78\x80\x07\x38\x00'\ | ||||
| b'\x07\x38\x00\x07\x38\x1c\x07\x38\x1c\x07\x78\x9c\x03\xf0\xdc\x01'\ | ||||
| b'\xe0\xfc\x07\xc0\xfc\x07\x80\xfc\x07\x00\x00\x00\x00\x00\x00\x0f'\ | ||||
| b'\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x0e\x00\x00\x0e\x00'\ | ||||
| b'\x00\x0e\x00\x00\x0e\x00\x00\x0e\x00\x00\x0e\x00\x00\x0e\x00\xf8'\ | ||||
| b'\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00\x00\x06\x00'\ | ||||
| b'\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x0c\x00\x00\xe0\x00\x00\xe0\x01\x00\xe0\x03\x00\x80\x07'\ | ||||
| b'\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x80\x07\xf8\xff\x03\xf8'\ | ||||
| b'\xff\x03\xf8\xff\x00\x00\x00\x00\x0e\x00\xf8\xff\x07\xf8\xff\x07'\ | ||||
| b'\xf8\xff\x07\x00\x1e\x00\x00\x0f\x00\x80\x1f\x00\xc0\x7f\x00\xe0'\ | ||||
| b'\xf9\x00\xf0\xf0\x03\x78\xc0\x07\x38\x80\x07\x18\x00\x07\x08\x00'\ | ||||
| b'\x04\x00\x00\x00\x0c\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00'\ | ||||
| b'\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x00'\ | ||||
| b'\x07\x00\x00\x07\x00\x00\x07\x00\x00\x00\x12\x00\xf8\xff\x07\xf8'\ | ||||
| b'\xff\x07\xf8\xff\x07\xf8\x01\x00\xf8\x1f\x00\xc0\xff\x00\x00\xfc'\ | ||||
| b'\x07\x00\xe0\x07\x00\xe0\x07\x00\xfc\x07\xc0\xff\x00\xf8\x1f\x00'\ | ||||
| b'\xf8\x01\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\xf8\x00\x00'\ | ||||
| b'\xe0\x03\x00\xc0\x0f\x00\x00\x3f\x00\x00\xfc\x00\x00\xf0\x01\x00'\ | ||||
| b'\xe0\x07\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x11\x00\x00\x3f\x00\xc0\xff\x00\xe0\xff\x01\xf0\xe1\x03\x70'\ | ||||
| b'\x80\x03\x78\x80\x07\x38\x00\x07\x38\x00\x07\x38\x00\x07\x78\x80'\ | ||||
| b'\x07\x70\x80\x03\xf0\xe1\x03\xe0\xff\x01\xc0\xff\x00\x00\x3f\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x0e\x00\xf8\xff\x07\xf8\xff\x07\xf8\xff'\ | ||||
| b'\x07\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00'\ | ||||
| b'\x78\x1e\x00\xf0\x0f\x00\xf0\x0f\x00\xc0\x03\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x11\x00\x00\x3f\x00\xc0\xff\x00\xe0\xff\x01\xf0\xe1\x03'\ | ||||
| b'\x70\x80\x03\x78\x80\x07\x38\x00\x07\x38\x10\x07\x38\x38\x07\x38'\ | ||||
| b'\x70\x07\x78\xf0\x07\x70\xe0\x03\xf0\xe1\x03\xe0\xff\x07\xc0\xff'\ | ||||
| b'\x03\x00\x3f\x02\x00\x00\x00\x0f\x00\xf8\xff\x07\xf8\xff\x07\xf8'\ | ||||
| b'\xff\x07\x38\x1c\x00\x38\x1c\x00\x38\x1c\x00\x38\x3c\x00\x38\xfc'\ | ||||
| b'\x00\x38\xfc\x03\x78\xfe\x07\xf0\x9f\x07\xf0\x0f\x07\xc0\x07\x04'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x0e\x00\x00\xc0\x00\xe0\xc1\x01\xf0\xe3'\ | ||||
| b'\x03\xf0\x87\x03\x78\x06\x07\x38\x0e\x07\x38\x0e\x07\x38\x0c\x07'\ | ||||
| b'\x38\x0c\x07\x78\x9c\x07\xf0\xf8\x03\xe0\xf8\x03\xc0\xf0\x00\x00'\ | ||||
| b'\x00\x00\x0c\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ | ||||
| b'\xf8\xff\x07\xf8\xff\x07\xf8\xff\x07\x38\x00\x00\x38\x00\x00\x38'\ | ||||
| b'\x00\x00\x38\x00\x00\x00\x00\x00\x0e\x00\xf8\xff\x00\xf8\xff\x01'\ | ||||
| b'\xf8\xff\x03\x00\x80\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00'\ | ||||
| b'\x00\x07\x00\x80\x07\xf8\xff\x03\xf8\xff\x01\xf8\xff\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x0e\x00\x18\x00\x00\xf8\x00\x00\xf8\x07\x00\xf0'\ | ||||
| b'\x3f\x00\x00\xff\x01\x00\xf8\x07\x00\x80\x07\x00\xe0\x07\x00\xfe'\ | ||||
| b'\x07\xc0\x7f\x00\xf8\x0f\x00\xf8\x01\x00\x38\x00\x00\x08\x00\x00'\ | ||||
| b'\x14\x00\x18\x00\x00\xf8\x01\x00\xf8\x1f\x00\xe0\xff\x00\x00\xfe'\ | ||||
| b'\x07\x00\xe0\x07\x00\xf8\x07\xc0\xff\x07\xf8\x3f\x00\xf8\x03\x00'\ | ||||
| b'\xf8\x01\x00\xf8\x3f\x00\xc0\xff\x07\x00\xf8\x07\x00\xc0\x07\x00'\ | ||||
| b'\xfe\x07\xe0\xff\x01\xf8\x1f\x00\xf8\x01\x00\x38\x00\x00\x0e\x00'\ | ||||
| b'\x08\x00\x04\x18\x00\x07\x78\x80\x07\xf8\xe0\x07\xf0\xf3\x01\xc0'\ | ||||
| b'\xff\x00\x00\x3f\x00\x80\x7f\x00\xe0\xff\x00\xf0\xf1\x03\xf8\xc0'\ | ||||
| b'\x07\x38\x80\x07\x18\x00\x06\x08\x00\x04\x0d\x00\x18\x00\x00\x38'\ | ||||
| b'\x00\x00\xf8\x00\x00\xf0\x03\x00\xc0\x0f\x00\x00\xff\x07\x00\xfc'\ | ||||
| b'\x07\x00\xff\x07\xc0\x0f\x00\xf0\x03\x00\xf8\x00\x00\x38\x00\x00'\ | ||||
| b'\x18\x00\x00\x0d\x00\x00\x00\x07\x38\x80\x07\x38\xc0\x07\x38\xe0'\ | ||||
| b'\x07\x38\x78\x07\x38\x3c\x07\x38\x1e\x07\x38\x0f\x07\xf8\x07\x07'\ | ||||
| b'\xf8\x01\x07\xf8\x00\x07\x78\x00\x07\x38\x00\x07\x07\x00\xff\xff'\ | ||||
| b'\x3f\xff\xff\x3f\xff\xff\x3f\x07\x00\x38\x07\x00\x38\x07\x00\x38'\ | ||||
| b'\x00\x00\x00\x08\x00\x04\x00\x00\x3c\x00\x00\xfc\x01\x00\xfc\x1f'\ | ||||
| b'\x00\xe0\xff\x00\x00\xfe\x07\x00\xf0\x07\x00\x00\x07\x07\x00\x07'\ | ||||
| b'\x00\x38\x07\x00\x38\x07\x00\x38\xff\xff\x3f\xff\xff\x3f\xff\xff'\ | ||||
| b'\x3f\x00\x00\x00\x0c\x00\x00\x18\x00\x00\x1f\x00\xc0\x1f\x00\xf8'\ | ||||
| b'\x03\x00\xf8\x00\x00\x78\x00\x00\xf8\x03\x00\xe0\x0f\x00\x00\x1f'\ | ||||
| b'\x00\x00\x1c\x00\x00\x10\x00\x00\x00\x00\x12\x00\x00\x00\x38\x00'\ | ||||
| b'\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00'\ | ||||
| b'\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38'\ | ||||
| b'\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00\x00\x38\x00'\ | ||||
| b'\x00\x38\x09\x00\x04\x00\x00\x04\x00\x00\x0c\x00\x00\x1c\x00\x00'\ | ||||
| b'\x18\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d'\ | ||||
| b'\x00\x00\xc0\x01\x00\xe4\x03\x00\xe6\x07\x00\x37\x07\x80\x37\x07'\ | ||||
| b'\x80\x33\x07\x80\x33\x07\x80\x33\x07\x80\x93\x03\x80\xff\x07\x00'\ | ||||
| b'\xff\x07\x00\xfe\x07\x00\x00\x00\x0e\x00\xfc\xff\x07\xfc\xff\x07'\ | ||||
| b'\xfc\xff\x07\x00\x87\x03\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80'\ | ||||
| b'\x03\x07\x80\x87\x07\x00\xff\x03\x00\xfe\x01\x00\xf8\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x0d\x00\x00\x78\x00\x00\xfe\x01\x00\xff\x03\x00'\ | ||||
| b'\x87\x03\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x87'\ | ||||
| b'\x07\x00\x87\x03\x00\x86\x01\x00\x88\x00\x00\x00\x00\x0e\x00\x00'\ | ||||
| b'\x78\x00\x00\xfe\x01\x00\xff\x03\x00\x87\x03\x80\x87\x07\x80\x03'\ | ||||
| b'\x07\x80\x03\x07\x80\x03\x07\x80\x87\x07\x00\x87\x03\xfc\xff\x07'\ | ||||
| b'\xfc\xff\x07\xfc\xff\x07\x00\x00\x00\x0d\x00\x00\x30\x00\x00\xfc'\ | ||||
| b'\x00\x00\xfe\x01\x00\xff\x03\x80\x77\x07\x80\x73\x07\x80\x73\x07'\ | ||||
| b'\x80\x73\x07\x80\xf7\x07\x00\xff\x03\x00\x7e\x03\x00\x7c\x00\x00'\ | ||||
| b'\x60\x00\x07\x00\x80\x03\x00\xf0\xff\x07\xfc\xff\x07\xfc\xff\x07'\ | ||||
| b'\x9e\x03\x00\x8e\x03\x00\x00\x00\x00\x0e\x00\x00\x78\x00\x00\xfe'\ | ||||
| b'\x01\x00\xff\x23\x00\x87\x73\x80\x87\xf7\x80\x03\xe7\x80\x03\xe7'\ | ||||
| b'\x80\x03\xe7\x00\x87\xe7\x00\x87\xf3\x80\xff\x7f\x80\xff\x3f\x80'\ | ||||
| b'\xff\x1f\x00\x00\x00\x0d\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff\x07'\ | ||||
| b'\x00\x07\x00\x80\x03\x00\x80\x03\x00\x80\x03\x00\x80\x07\x00\x00'\ | ||||
| b'\xff\x07\x00\xff\x07\x00\xfc\x07\x00\x00\x00\x00\x00\x00\x05\x00'\ | ||||
| b'\xb8\xff\x07\xb8\xff\x07\xb8\xff\x07\x00\x00\x00\x00\x00\x00\x05'\ | ||||
| b'\x00\x00\x00\xe0\x00\x00\xe0\xb8\xff\xff\xb8\xff\xff\xb8\xff\x7f'\ | ||||
| b'\x0c\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff\x07\x00\x78\x00\x00\x3c'\ | ||||
| b'\x00\x00\xfe\x00\x80\xff\x01\x80\xe7\x07\x80\x83\x07\x80\x01\x07'\ | ||||
| b'\x80\x00\x04\x00\x00\x00\x05\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff'\ | ||||
| b'\x07\x00\x00\x00\x00\x00\x00\x14\x00\x80\xff\x07\x80\xff\x07\x80'\ | ||||
| b'\xff\x07\x00\x07\x00\x80\x03\x00\x80\x03\x00\x80\x03\x00\x80\x07'\ | ||||
| b'\x00\x00\xff\x07\x00\xfe\x07\x00\xff\x07\x80\x07\x00\x80\x03\x00'\ | ||||
| b'\x80\x03\x00\x80\x07\x00\x00\xff\x07\x00\xff\x07\x00\xfc\x07\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x0d\x00\x80\xff\x07\x80\xff\x07\x80\xff\x07'\ | ||||
| b'\x00\x07\x00\x80\x03\x00\x80\x03\x00\x80\x03\x00\x80\x07\x00\x00'\ | ||||
| b'\xff\x07\x00\xff\x07\x00\xfc\x07\x00\x00\x00\x00\x00\x00\x0d\x00'\ | ||||
| b'\x00\x78\x00\x00\xfe\x01\x00\xff\x03\x00\x87\x03\x80\x03\x07\x80'\ | ||||
| b'\x03\x07\x80\x03\x07\x80\x03\x07\x00\x87\x03\x00\xff\x03\x00\xfe'\ | ||||
| b'\x01\x00\x78\x00\x00\x00\x00\x0e\x00\x80\xff\xff\x80\xff\xff\x80'\ | ||||
| b'\xff\xff\x00\x87\x03\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x03'\ | ||||
| b'\x07\x80\x87\x07\x00\xff\x03\x00\xfe\x01\x00\x7c\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x0e\x00\x00\x78\x00\x00\xfe\x01\x00\xff\x03\x00\x87'\ | ||||
| b'\x03\x80\x87\x07\x80\x03\x07\x80\x03\x07\x80\x03\x07\x80\x87\x07'\ | ||||
| b'\x00\x87\x03\x80\xff\xff\x80\xff\xff\x80\xff\xff\x00\x00\x00\x08'\ | ||||
| b'\x00\x80\xff\x07\x80\xff\x07\x80\xff\x07\x00\x07\x00\x80\x03\x00'\ | ||||
| b'\x80\x03\x00\x80\x03\x00\x00\x00\x00\x0c\x00\x00\x80\x00\x00\x8e'\ | ||||
| b'\x01\x00\x9f\x03\x80\x9f\x07\x80\x3b\x07\x80\x33\x07\x80\x33\x07'\ | ||||
| b'\x80\x33\x07\x00\xf7\x07\x00\xe7\x03\x00\xc6\x01\x00\x00\x00\x07'\ | ||||
| b'\x00\x80\x03\x00\xfc\xff\x00\xfc\xff\x03\xfc\xff\x07\x80\x03\x07'\ | ||||
| b'\x80\x03\x07\x00\x00\x00\x0d\x00\x80\xff\x00\x80\xff\x03\x80\xff'\ | ||||
| b'\x03\x00\x80\x07\x00\x00\x07\x00\x00\x07\x00\x00\x07\x00\x80\x03'\ | ||||
| b'\x80\xff\x07\x80\xff\x07\x80\xff\x07\x00\x00\x00\x00\x00\x00\x0c'\ | ||||
| b'\x00\x80\x01\x00\x80\x0f\x00\x80\x3f\x00\x00\xfe\x01\x00\xf0\x07'\ | ||||
| b'\x00\x80\x07\x00\xc0\x07\x00\xf8\x07\x00\xff\x00\x80\x3f\x00\x80'\ | ||||
| b'\x07\x00\x80\x00\x00\x12\x00\x80\x01\x00\x80\x0f\x00\x80\xff\x00'\ | ||||
| b'\x00\xfe\x07\x00\xe0\x07\x00\xc0\x07\x00\xfc\x07\x80\xff\x00\x80'\ | ||||
| b'\x0f\x00\x80\x3f\x00\x00\xff\x01\x00\xf0\x07\x00\x80\x07\x00\xf8'\ | ||||
| b'\x07\x80\xff\x03\x80\x3f\x00\x80\x07\x00\x80\x00\x00\x0c\x00\x80'\ | ||||
| b'\x00\x04\x80\x01\x07\x80\x87\x07\x80\xef\x07\x00\xfe\x01\x00\x7c'\ | ||||
| b'\x00\x00\xfe\x00\x00\xff\x03\x80\xc7\x07\x80\x03\x07\x80\x00\x06'\ | ||||
| b'\x00\x00\x04\x0c\x00\x80\x01\x00\x80\x07\xe0\x80\x3f\xe0\x00\xff'\ | ||||
| b'\xf0\x00\xf8\xff\x00\xc0\x7f\x00\xc0\x1f\x00\xf8\x07\x00\xff\x00'\ | ||||
| b'\x80\x1f\x00\x80\x07\x00\x80\x00\x00\x0b\x00\x80\x03\x07\x80\x83'\ | ||||
| b'\x07\x80\xc3\x07\x80\xe3\x07\x80\xf3\x07\x80\x7b\x07\x80\x3f\x07'\ | ||||
| b'\x80\x1f\x07\x80\x0f\x07\x80\x07\x07\x00\x00\x07\x08\x00\x00\x0c'\ | ||||
| b'\x00\x00\x1e\x00\xfc\xff\x0f\xfe\xff\x1f\xfe\xf3\x1f\x06\x00\x38'\ | ||||
| b'\x06\x00\x38\x00\x00\x00\x05\x00\xfc\xff\x07\xfc\xff\x07\xfc\xff'\ | ||||
| b'\x07\x00\x00\x00\x00\x00\x00\x07\x00\x06\x00\x38\xfe\xf3\x1f\xfe'\ | ||||
| b'\xff\x1f\xfc\xff\x0f\x00\x1e\x00\x00\x0c\x00\x00\x00\x00\x09\x00'\ | ||||
| b'\x18\x00\x00\x0c\x00\x00\x0c\x00\x00\x0c\x00\x00\x18\x00\x00\x18'\ | ||||
| b'\x00\x00\x1c\x00\x00\x04\x00\x00\x00\x00\x00' | ||||
| 
 | ||||
| _index =\ | ||||
| b'\x00\x00\x26\x00\x3d\x00\x51\x00\x6b\x00\x91\x00\xb4\x00\xec\x00'\ | ||||
| b'\x1b\x01\x29\x01\x40\x01\x57\x01\x74\x01\x9a\x01\xab\x01\xc2\x01'\ | ||||
| b'\xd3\x01\xed\x01\x16\x02\x30\x02\x59\x02\x7f\x02\xa5\x02\xcb\x02'\ | ||||
| b'\xf4\x02\x17\x03\x3d\x03\x66\x03\x77\x03\x88\x03\xa8\x03\xcb\x03'\ | ||||
| b'\xeb\x03\x11\x04\x46\x04\x75\x04\xa4\x04\xd6\x04\x05\x05\x31\x05'\ | ||||
| b'\x5a\x05\x8f\x05\xbe\x05\xd2\x05\xf8\x05\x24\x06\x4a\x06\x82\x06'\ | ||||
| b'\xb1\x06\xe6\x06\x12\x07\x47\x07\x76\x07\xa2\x07\xc8\x07\xf4\x07'\ | ||||
| b'\x20\x08\x5e\x08\x8a\x08\xb3\x08\xdc\x08\xf3\x08\x0d\x09\x24\x09'\ | ||||
| b'\x4a\x09\x82\x09\x9f\x09\xc8\x09\xf4\x09\x1d\x0a\x49\x0a\x72\x0a'\ | ||||
| b'\x89\x0a\xb5\x0a\xde\x0a\xef\x0a\x00\x0b\x26\x0b\x37\x0b\x75\x0b'\ | ||||
| b'\x9e\x0b\xc7\x0b\xf3\x0b\x1f\x0c\x39\x0c\x5f\x0c\x76\x0c\x9f\x0c'\ | ||||
| b'\xc5\x0c\xfd\x0c\x23\x0d\x49\x0d\x6c\x0d\x86\x0d\x97\x0d\xae\x0d'\ | ||||
| b'\xcb\x0d' | ||||
| 
 | ||||
| _mvfont = memoryview(_font) | ||||
| 
 | ||||
| def _chr_addr(ordch): | ||||
|     offset = 2 * (ordch - 32) | ||||
|     return int.from_bytes(_index[offset:offset + 2], 'little') | ||||
|      | ||||
| def get_width(s): | ||||
|     width = 0 | ||||
|     for ch in s: | ||||
|         ordch = ord(ch) | ||||
|         ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 | ||||
|         offset = _chr_addr(ordch) | ||||
|         width += int.from_bytes(_font[offset:offset + 2], 'little') | ||||
|     return width | ||||
| 
 | ||||
| def get_ch(ch): | ||||
|     ordch = ord(ch) | ||||
|     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 _mvfont[offset + 2:next_offs], width | ||||
|   | ||||
							
								
								
									
										430
									
								
								src/tt32.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										430
									
								
								src/tt32.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,430 @@ | |||
| # Code generated by font-to-py.py. | ||||
| # Font: CM Sans Serif 2012.ttf | ||||
| version = '0.2' | ||||
| 
 | ||||
| def height(): | ||||
|     return 31 | ||||
| 
 | ||||
| def max_width(): | ||||
|     return 26 | ||||
| 
 | ||||
| def hmap(): | ||||
|     return False | ||||
| 
 | ||||
| def reverse(): | ||||
|     return False | ||||
| 
 | ||||
| def monospaced(): | ||||
|     return False | ||||
| 
 | ||||
| def min_ch(): | ||||
|     return 32 | ||||
| 
 | ||||
| def max_ch(): | ||||
|     return 126 | ||||
| 
 | ||||
| _font =\ | ||||
| b'\x0f\x00\x00\x07\x00\x00\xc0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07'\ | ||||
| b'\x00\x00\xf0\x01\x67\x00\xf0\xc0\xf7\x00\xf0\xe0\xf7\x00\xf0\xe0'\ | ||||
| b'\x67\x00\xf0\xf1\x01\x00\xe0\xff\x00\x00\xe0\x7f\x00\x00\xc0\x3f'\ | ||||
| b'\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\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\x08\x00\xf0\xff\xf3\x00\xf0\xff\xf3\x00\xf0\xff'\ | ||||
| b'\xf3\x00\xf0\xff\x63\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x0a\x00\xf0\x0f\x00\x00\xf0\x0f\x00\x00'\ | ||||
| b'\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\x00\x00'\ | ||||
| b'\xf0\x0f\x00\x00\xf0\x0f\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x0f\x00\x00\x00\x0e\x00\x00\x0e\x0e\x00\x00\x0e\x7e\x00\x00\xfe'\ | ||||
| b'\x7f\x00\xe0\xff\x7f\x00\xe0\xff\x0f\x00\xe0\x0f\x0e\x00\x00\x0e'\ | ||||
| b'\x0e\x00\x00\x0e\x7f\x00\x00\xfe\x7f\x00\xe0\xff\x7f\x00\xe0\xff'\ | ||||
| b'\x0f\x00\xe0\x0f\x0e\x00\x00\x0e\x0e\x00\x00\x0e\x00\x00\x0e\x00'\ | ||||
| b'\x00\x1f\x0e\x00\x80\x3f\x1e\x00\xc0\x3f\x3e\x00\xc0\x79\x3c\x00'\ | ||||
| b'\xc0\x71\x38\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xc0\xe1\x38\x00'\ | ||||
| b'\xc0\xe3\x38\x00\xc0\xe7\x3f\x00\x80\xc7\x1f\x00\x00\x86\x0f\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x80\x07\x00\x00\xc0\x0f'\ | ||||
| b'\x00\x00\xe0\x1f\x00\x00\xf0\x3c\x00\x00\x70\x38\x80\x00\x70\x38'\ | ||||
| b'\xe0\x00\x70\x38\xf8\x00\xf0\x3c\x7e\x00\xe0\x1f\x1f\x00\xc0\xcf'\ | ||||
| b'\x0f\x00\x80\xf7\x03\x00\x00\xfc\x00\x00\x00\x3f\x1e\x00\x80\x8f'\ | ||||
| b'\x7f\x00\xe0\x87\x7f\x00\xf0\xc1\xf3\x00\x70\xc0\xe1\x00\x10\xc0'\ | ||||
| b'\xe1\x00\x00\xc0\xf3\x00\x00\x80\x7f\x00\x00\x80\x7f\x00\x00\x00'\ | ||||
| b'\x1e\x00\x00\x00\x00\x00\x13\x00\x00\x00\x0f\x00\x00\x80\x3f\x00'\ | ||||
| b'\x00\xc0\x3f\x00\x80\xe7\x7f\x00\xe0\x7f\xf8\x00\xe0\x3f\xf8\x00'\ | ||||
| b'\xf0\x3f\xf0\x00\xf0\x78\xf0\x00\xf0\xf8\xf0\x00\xf0\xff\xf3\x00'\ | ||||
| b'\xe0\xdf\xff\x00\xe0\x8f\xff\x00\x80\x07\x7e\x00\x00\xc0\xff\x00'\ | ||||
| b'\x00\xc0\xff\x00\x00\xc0\xff\x00\x00\xc0\xc3\x00\x00\x00\x80\x00'\ | ||||
| b'\x00\x00\x00\x00\x05\x00\xf0\x0f\x00\x00\xf0\x0f\x00\x00\xf0\x0f'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\xfc\x03\x00'\ | ||||
| b'\x80\xff\x1f\x00\xe0\xff\x7f\x00\xf8\xff\xff\x01\xfc\x01\xf8\x03'\ | ||||
| b'\x3e\x00\xc0\x07\x0e\x00\x00\x07\x02\x00\x00\x04\x00\x00\x00\x00'\ | ||||
| b'\x09\x00\x02\x00\x00\x04\x0e\x00\x00\x07\x3e\x00\xc0\x07\xfc\x01'\ | ||||
| b'\xf8\x03\xf8\xff\xff\x01\xe0\xff\x7f\x00\x80\xff\x1f\x00\x00\xfc'\ | ||||
| b'\x03\x00\x00\x00\x00\x00\x0b\x00\x80\x01\x00\x00\xa0\x09\x00\x00'\ | ||||
| b'\xf0\x1f\x00\x00\xe0\x0f\x00\x00\xc0\x07\x00\x00\xe0\x0f\x00\x00'\ | ||||
| b'\xf0\x1d\x00\x00\xa0\x09\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x0f\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0'\ | ||||
| b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xfe\x7f\x00\x00\xfe'\ | ||||
| b'\x7f\x00\x00\xfe\x7f\x00\x00\xfe\x7f\x00\x00\xc0\x03\x00\x00\xc0'\ | ||||
| b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\x00'\ | ||||
| b'\x00\x00\x06\x00\x00\x00\x60\x0c\x00\x00\xf0\x0c\x00\x00\xf0\x07'\ | ||||
| b'\x00\x00\xe0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\xc0'\ | ||||
| b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0'\ | ||||
| b'\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x06\x00\x00\x00\x60\x00\x00\x00\xf0\x00\x00\x00\xf0\x00'\ | ||||
| b'\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00'\ | ||||
| b'\xe0\x00\x00\x00\xfc\x00\x00\xc0\xff\x00\x00\xf8\xff\x00\x80\xff'\ | ||||
| b'\x1f\x00\xf8\xff\x03\x00\xfc\x3f\x00\x00\xfc\x07\x00\x00\x7c\x00'\ | ||||
| b'\x00\x00\x04\x00\x00\x00\x11\x00\x00\xfc\x03\x00\x80\xff\x1f\x00'\ | ||||
| b'\xc0\xff\x3f\x00\xe0\xff\x7f\x00\xe0\x07\x7e\x00\xf0\x01\xf8\x00'\ | ||||
| b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x01\xf8\x00'\ | ||||
| b'\xe0\x07\x7e\x00\xe0\xff\x7f\x00\xc0\xff\x3f\x00\x80\xff\x1f\x00'\ | ||||
| b'\x00\xfc\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x80\x03'\ | ||||
| b'\x00\x00\x80\x03\x00\x00\xc0\x03\x00\x00\xe0\xff\xff\x00\xf0\xff'\ | ||||
| b'\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x10\x00\x00\x07\xf8\x00\xc0\x07\xfc\x00\xc0\x07\xfe\x00'\ | ||||
| b'\xe0\x07\xff\x00\xf0\x81\xf7\x00\xf0\x80\xf3\x00\xf0\xc0\xf1\x00'\ | ||||
| b'\xf0\xe0\xf1\x00\xf0\xe0\xf0\x00\xf0\xf1\xf0\x00\xe0\x7f\xf0\x00'\ | ||||
| b'\xe0\x7f\xf0\x00\xc0\x3f\xf0\x00\x00\x0f\xf0\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x10\x00\x00\x00\x0e\x00\x00\x07\x3e\x00\xc0\x07'\ | ||||
| b'\x3e\x00\xe0\x07\x7e\x00\xe0\x07\xf8\x00\xf0\x01\xf0\x00\xf0\xf0'\ | ||||
| b'\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf9\xf0\x00\xf0\xff'\ | ||||
| b'\xf9\x00\xe0\xff\x7f\x00\xc0\xdf\x7f\x00\x80\x8f\x3f\x00\x00\x00'\ | ||||
| b'\x0f\x00\x00\x00\x00\x00\x10\x00\x00\x00\x0f\x00\x00\x80\x0f\x00'\ | ||||
| b'\x00\xe0\x0f\x00\x00\xf8\x0f\x00\x00\x7c\x0f\x00\x00\x3f\x0f\x00'\ | ||||
| b'\x80\x0f\x0f\x00\xe0\x07\x0f\x00\xf0\x01\x0f\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x0f\x00'\ | ||||
| b'\x00\x00\x0f\x00\x00\x00\x00\x00\x0f\x00\x00\x70\x1c\x00\xf0\x7f'\ | ||||
| b'\x3c\x00\xf0\x7f\x7c\x00\xf0\xff\x7c\x00\xf0\x78\xf8\x00\xf0\x3c'\ | ||||
| b'\xf0\x00\xf0\x3c\xf0\x00\xf0\x3c\xf0\x00\xf0\x3c\xf0\x00\xf0\x7c'\ | ||||
| b'\x78\x00\xf0\xf8\x7f\x00\xf0\xf0\x3f\x00\xf0\xe0\x1f\x00\x00\xc0'\ | ||||
| b'\x0f\x00\x00\x00\x00\x00\x10\x00\x00\xfc\x07\x00\x00\xff\x1f\x00'\ | ||||
| b'\xc0\xff\x3f\x00\xe0\xff\x7f\x00\xe0\xf3\x78\x00\xf0\x79\xf0\x00'\ | ||||
| b'\xf0\x78\xf0\x00\xf0\x78\xf0\x00\xf0\x78\xf0\x00\xf0\xf9\xf8\x00'\ | ||||
| b'\xe0\xf3\x7f\x00\xe0\xf3\x7f\x00\xc0\xe3\x3f\x00\x00\x83\x0f\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xf0\x00\x00\x00\xf0\x00'\ | ||||
| b'\x00\x00\xf0\x00\x00\x00\xf0\x00\xf8\x00\xf0\x80\xff\x00\xf0\xe0'\ | ||||
| b'\xff\x00\xf0\xf8\xff\x00\xf0\xfc\x07\x00\xf0\x7e\x00\x00\xf0\x1f'\ | ||||
| b'\x00\x00\xf0\x07\x00\x00\xf0\x03\x00\x00\xf0\x01\x00\x00\xf0\x00'\ | ||||
| b'\x00\x00\x10\x00\x00\x00\x0f\x00\x80\xc7\x3f\x00\xc0\xef\x7f\x00'\ | ||||
| b'\xe0\xff\x7f\x00\xe0\xff\xf8\x00\xf0\x7d\xf0\x00\xf0\x78\xf0\x00'\ | ||||
| b'\xf0\x78\xf0\x00\xf0\x78\xf0\x00\xf0\x7d\xf0\x00\xe0\xff\xf8\x00'\ | ||||
| b'\xe0\xff\x7f\x00\xc0\xef\x7f\x00\x80\xc7\x3f\x00\x00\x00\x0f\x00'\ | ||||
| b'\x00\x00\x00\x00\x10\x00\x00\x3f\x00\x00\x80\xff\x30\x00\xc0\xff'\ | ||||
| b'\x71\x00\xe0\xff\x71\x00\xf0\xe1\xf3\x00\xf0\xc1\xf3\x00\xf0\xc0'\ | ||||
| b'\xf3\x00\xf0\xc0\xf3\x00\xf0\xc0\xf3\x00\xf0\xc1\xf9\x00\xe0\xe1'\ | ||||
| b'\x7d\x00\xe0\xff\x7f\x00\xc0\xff\x3f\x00\x80\xff\x1f\x00\x00\xfc'\ | ||||
| b'\x03\x00\x00\x00\x00\x00\x06\x00\x00\x18\x60\x00\x00\x3c\xf0\x00'\ | ||||
| b'\x00\x3c\xf0\x00\x00\x18\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x06\x00\x00\x18\x60\x0c\x00\x3c\xf0\x0c\x00\x3c\xf0\x07\x00\x18'\ | ||||
| b'\xe0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\xc0\x03\x00'\ | ||||
| b'\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xf0\x0f\x00\x00\xf0\x0f\x00'\ | ||||
| b'\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x38\x1c\x00\x00\x3c\x3c\x00'\ | ||||
| b'\x00\x1c\x38\x00\x00\x1e\x78\x00\x00\x00\x00\x00\x0e\x00\x00\x78'\ | ||||
| b'\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78'\ | ||||
| b'\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78'\ | ||||
| b'\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x1e\x78\x00\x00\x3c\x3c\x00'\ | ||||
| b'\x00\x3c\x3c\x00\x00\x78\x1e\x00\x00\x78\x1e\x00\x00\x70\x0e\x00'\ | ||||
| b'\x00\xf0\x0f\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xc0\x07\x00'\ | ||||
| b'\x00\xc0\x03\x00\x00\x00\x00\x00\x0f\x00\x00\x07\x00\x00\xc0\x07'\ | ||||
| b'\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xf0\x01\x67\x00\xf0\xc0'\ | ||||
| b'\xf7\x00\xf0\xe0\xf7\x00\xf0\xe0\x67\x00\xf0\xf1\x01\x00\xe0\xff'\ | ||||
| b'\x00\x00\xe0\x7f\x00\x00\xc0\x3f\x00\x00\x00\x1f\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x16\x00\x00\xf8\x01\x00\x00\xfe\x07\x00'\ | ||||
| b'\x80\xff\x1f\x00\xc0\x0f\x1e\x00\xc0\x03\x3c\x00\xe0\xe1\x79\x00'\ | ||||
| b'\xe0\xf8\x73\x00\xf0\xfc\xf7\x00\x70\x1c\xe7\x00\x70\x0e\xe7\x00'\ | ||||
| b'\x70\x8e\xe3\x00\x70\xfe\xe1\x00\x70\xfc\xe3\x00\xf0\xfc\xe7\x00'\ | ||||
| b'\xe0\x0c\x77\x00\xe0\x01\x77\x00\xc0\xc3\x23\x00\xc0\xff\x43\x00'\ | ||||
| b'\x00\xff\x01\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x13\x00\x00\x00\xc0\x00\x00\x00\xf8\x00\x00\x00\xfe\x00\x00\xc0'\ | ||||
| b'\xff\x00\x00\xf8\x3f\x00\x00\xff\x0f\x00\xe0\xff\x0f\x00\xf0\x1f'\ | ||||
| b'\x0f\x00\xf0\x03\x0f\x00\xf0\x00\x0f\x00\xf0\x07\x0f\x00\xf0\x3f'\ | ||||
| b'\x0f\x00\xc0\xff\x0f\x00\x00\xfe\x0f\x00\x00\xf0\x7f\x00\x00\x80'\ | ||||
| b'\xff\x00\x00\x00\xfc\x00\x00\x00\xf0\x00\x00\x00\x80\x00\x12\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00'\ | ||||
| b'\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf9\xf0\x00'\ | ||||
| b'\xf0\xff\xf9\x00\xe0\xff\x7f\x00\xc0\xdf\x7f\x00\x80\x8f\x3f\x00'\ | ||||
| b'\x00\x00\x1f\x00\x00\x00\x00\x00\x14\x00\x00\xf8\x01\x00\x00\xfe'\ | ||||
| b'\x07\x00\x80\xff\x1f\x00\xc0\xff\x3f\x00\xc0\x0f\x3f\x00\xe0\x03'\ | ||||
| b'\x7c\x00\xe0\x01\x78\x00\xf0\x01\xf8\x00\xf0\x00\xf0\x00\xf0\x00'\ | ||||
| b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x01\xf8\x00\xe0\x01'\ | ||||
| b'\x78\x00\xe0\x07\x7e\x00\xc0\x07\x3e\x00\x80\x07\x1e\x00\x00\x03'\ | ||||
| b'\x0c\x00\x00\x04\x04\x00\x00\x00\x00\x00\x13\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\x00\xf0\x00'\ | ||||
| b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00'\ | ||||
| b'\xf0\x00\xf8\x00\xe0\x01\x78\x00\xe0\x07\x7e\x00\xc0\xff\x3f\x00'\ | ||||
| b'\x80\xff\x1f\x00\x00\xff\x0f\x00\x00\xfc\x03\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\xf0\xff\xff\x00\xf0\xff'\ | ||||
| b'\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xf0\xf0\x00\xf0\xf0'\ | ||||
| b'\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0'\ | ||||
| b'\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\xf0\xf0\x00\xf0\x00'\ | ||||
| b'\xf0\x00\xf0\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00'\ | ||||
| b'\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00\xf0\xf0\x00\x00'\ | ||||
| b'\xf0\xf0\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x15\x00\x00\xf8\x01\x00\x00\xfe\x0f\x00\x80\xff\x1f\x00\xc0\xff'\ | ||||
| b'\x3f\x00\xc0\x0f\x7f\x00\xe0\x03\x7c\x00\xe0\x01\xf8\x00\xf0\x01'\ | ||||
| b'\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\xe0\xf1\x00\xf0\xe0'\ | ||||
| b'\xf1\x00\xf0\xe1\x79\x00\xe0\xe1\x79\x00\xe0\xe3\x3d\x00\xc0\xe7'\ | ||||
| b'\xff\x00\x80\xe7\xff\x00\x00\xe3\xff\x00\x00\xe4\xff\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x14\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\xf0\x00\x00\x00\xf0\x00\x00'\ | ||||
| b'\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00'\ | ||||
| b'\x00\xf0\x00\x00\x00\xf0\x00\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\xf0\xff\xff\x00\xf0\xff'\ | ||||
| b'\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x3f\x00'\ | ||||
| b'\x00\x00\x7f\x00\x00\x00\x7f\x00\x00\x00\xf8\x00\x00\x00\xf0\x00'\ | ||||
| b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf8\x00'\ | ||||
| b'\xf0\xff\x7f\x00\xf0\xff\x7f\x00\xf0\xff\x3f\x00\xf0\xff\x0f\x00'\ | ||||
| b'\x00\x00\x00\x00\x12\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff'\ | ||||
| b'\xff\x00\xf0\xff\xff\x00\x00\xf0\x01\x00\x00\xfc\x00\x00\x00\xfe'\ | ||||
| b'\x00\x00\x00\xff\x01\x00\x80\xff\x07\x00\xc0\xef\x0f\x00\xe0\x87'\ | ||||
| b'\x3f\x00\xf0\x01\x7f\x00\xf0\x00\xfc\x00\x70\x00\xf8\x00\x30\x00'\ | ||||
| b'\xf0\x00\x10\x00\xc0\x00\x10\x00\x80\x00\x00\x00\x00\x00\x10\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00'\ | ||||
| b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00'\ | ||||
| b'\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x18\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff'\ | ||||
| b'\xff\x00\xf0\x07\x00\x00\xf0\x7f\x00\x00\x80\xff\x07\x00\x00\xfc'\ | ||||
| b'\x3f\x00\x00\xc0\xff\x00\x00\x00\xfe\x00\x00\x00\xfe\x00\x00\xc0'\ | ||||
| b'\xff\x00\x00\xfc\x3f\x00\x80\xff\x07\x00\xf0\x7f\x00\x00\xf0\x07'\ | ||||
| b'\x00\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff'\ | ||||
| b'\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x14\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\x07\x00\x00\xc0\x1f\x00\x00\x00\x3f\x00\x00'\ | ||||
| b'\x00\xfc\x00\x00\x00\xf0\x03\x00\x00\xc0\x0f\x00\x00\x80\x3f\x00'\ | ||||
| b'\x00\x00\xfe\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x16\x00\x00\xf8\x01\x00\x00\xfe\x07\x00\x80\xff'\ | ||||
| b'\x1f\x00\xc0\xff\x3f\x00\xc0\x0f\x3f\x00\xe0\x03\x7c\x00\xe0\x01'\ | ||||
| b'\x78\x00\xf0\x01\xf8\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00\xf0\x00'\ | ||||
| b'\xf0\x00\xf0\x00\xf0\x00\xf0\x01\xf8\x00\xe0\x01\x78\x00\xe0\x03'\ | ||||
| b'\x7c\x00\xc0\x0f\x3f\x00\xc0\xff\x3f\x00\x80\xff\x1f\x00\x00\xfe'\ | ||||
| b'\x07\x00\x00\xf8\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x01\x00'\ | ||||
| b'\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xf1\x01\x00\xe0\xff\x00\x00'\ | ||||
| b'\xe0\xff\x00\x00\xc0\x7f\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\xf8\x01\x00\x00\xff'\ | ||||
| b'\x0f\x00\x80\xff\x1f\x00\xc0\xff\x3f\x00\xe0\x0f\x7e\x00\xe0\x03'\ | ||||
| b'\x7c\x00\xf0\x01\xf8\x00\xf0\x00\xf0\x00\xf0\x00\xf1\x00\xf0\x80'\ | ||||
| b'\xf3\x00\xf0\xc0\xf7\x00\xf0\x80\xff\x00\xf0\x01\xff\x00\xe0\x03'\ | ||||
| b'\x7e\x00\xe0\x0f\x7e\x00\xc0\xff\x7f\x00\x80\xff\xff\x00\x00\xfe'\ | ||||
| b'\x77\x00\x00\xf8\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x01\x00\xf0\xe0\x03\x00'\ | ||||
| b'\xf0\xe0\x0f\x00\xf0\xe0\x3f\x00\xf0\xf1\x7f\x00\xe0\xff\xfc\x00'\ | ||||
| b'\xe0\xff\xf0\x00\xc0\x7f\xe0\x00\x00\x1f\x80\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x04\x00\x80\x0f'\ | ||||
| b'\x1e\x00\xc0\x1f\x3e\x00\xe0\x3f\x7e\x00\xe0\x3f\x7c\x00\xf0\x39'\ | ||||
| b'\xf8\x00\xf0\x70\xf0\x00\xf0\x70\xf0\x00\xf0\x70\xf0\x00\xf0\x70'\ | ||||
| b'\xf0\x00\xf0\x60\xf0\x00\xf0\xe1\xf8\x00\xe0\xe3\x78\x00\xe0\xc7'\ | ||||
| b'\x7f\x00\xc0\xc3\x7f\x00\x80\x83\x3f\x00\x00\x02\x0f\x00\x00\x00'\ | ||||
| b'\x00\x00\x0f\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00'\ | ||||
| b'\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf0\xff\xff\x00\xf0\x00\x00\x00\xf0\x00\x00\x00'\ | ||||
| b'\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x12\x00\xf0\xff\x07\x00\xf0\xff\x1f\x00\xf0\xff\x3f\x00\xf0\xff'\ | ||||
| b'\x7f\x00\x00\x00\x7c\x00\x00\x00\xf8\x00\x00\x00\xf0\x00\x00\x00'\ | ||||
| b'\xf0\x00\x00\x00\xf0\x00\x00\x00\xf0\x00\x00\x00\xf8\x00\x00\x00'\ | ||||
| b'\x7c\x00\xf0\xff\x7f\x00\xf0\xff\x3f\x00\xf0\xff\x1f\x00\xf0\xff'\ | ||||
| b'\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x30\x00\x00\x00'\ | ||||
| b'\xf0\x01\x00\x00\xf0\x0f\x00\x00\xf0\x7f\x00\x00\xc0\xff\x03\x00'\ | ||||
| b'\x00\xfe\x1f\x00\x00\xe0\xff\x00\x00\x00\xff\x00\x00\x00\xf8\x00'\ | ||||
| b'\x00\x00\xff\x00\x00\xe0\xff\x00\x00\xfe\x1f\x00\xc0\xff\x03\x00'\ | ||||
| b'\xf0\x7f\x00\x00\xf0\x0f\x00\x00\xf0\x01\x00\x00\x30\x00\x00\x00'\ | ||||
| b'\x19\x00\x70\x00\x00\x00\xf0\x03\x00\x00\xf0\x3f\x00\x00\xf0\xff'\ | ||||
| b'\x01\x00\x80\xff\x1f\x00\x00\xf8\xff\x00\x00\x80\xff\x00\x00\x00'\ | ||||
| b'\xfc\x00\x00\xe0\xff\x00\x00\xff\xff\x00\xf0\xff\x07\x00\xf0\x3f'\ | ||||
| b'\x00\x00\xf0\x03\x00\x00\xf0\x1f\x00\x00\xf0\xff\x03\x00\x80\xff'\ | ||||
| b'\x7f\x00\x00\xf8\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\xf0'\ | ||||
| b'\xff\x00\x00\xff\x3f\x00\xf0\xff\x07\x00\xf0\x7f\x00\x00\xf0\x07'\ | ||||
| b'\x00\x00\xf0\x00\x00\x00\x11\x00\x10\x00\x80\x00\x30\x00\xe0\x00'\ | ||||
| b'\xf0\x00\xf0\x00\xf0\x01\xfc\x00\xf0\x07\xfe\x00\xc0\x9f\x3f\x00'\ | ||||
| b'\x80\xff\x0f\x00\x00\xfe\x07\x00\x00\xfc\x01\x00\x00\xfe\x07\x00'\ | ||||
| b'\x80\xff\x0f\x00\xc0\x9f\x3f\x00\xf0\x07\x7f\x00\xf0\x03\xfc\x00'\ | ||||
| b'\xf0\x00\xf8\x00\x70\x00\xe0\x00\x10\x00\x80\x00\x12\x00\x10\x00'\ | ||||
| b'\x00\x00\x30\x00\x00\x00\xf0\x00\x00\x00\xf0\x03\x00\x00\xf0\x0f'\ | ||||
| b'\x00\x00\xc0\x3f\x00\x00\x00\x7f\x00\x00\x00\xfc\xff\x00\x00\xf0'\ | ||||
| b'\xff\x00\x00\xf0\xff\x00\x00\xfc\xff\x00\x00\x7f\x00\x00\xc0\x3f'\ | ||||
| b'\x00\x00\xf0\x0f\x00\x00\xf0\x03\x00\x00\xf0\x00\x00\x00\x30\x00'\ | ||||
| b'\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\xe0\x00\xf0\x00\xf8\x00'\ | ||||
| b'\xf0\x00\xfc\x00\xf0\x00\xfe\x00\xf0\x00\xff\x00\xf0\x80\xff\x00'\ | ||||
| b'\xf0\xc0\xf3\x00\xf0\xf0\xf1\x00\xf0\xf8\xf0\x00\xf0\x7c\xf0\x00'\ | ||||
| b'\xf0\x3e\xf0\x00\xf0\x0f\xf0\x00\xf0\x07\xf0\x00\xf0\x03\xf0\x00'\ | ||||
| b'\xf0\x01\xf0\x00\xf0\x00\xf0\x00\x00\x00\x00\x00\x09\x00\xff\xff'\ | ||||
| b'\xff\x0f\xff\xff\xff\x0f\xff\xff\xff\x0f\xff\xff\xff\x0f\x0f\x00'\ | ||||
| b'\x00\x0f\x0f\x00\x00\x0f\x0f\x00\x00\x0f\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x0a\x00\x04\x00\x00\x00\x3c\x00\x00\x00\xfc\x03\x00\x00'\ | ||||
| b'\xfc\x1f\x00\x00\xf8\xff\x01\x00\xc0\xff\x1f\x00\x00\xfc\xff\x00'\ | ||||
| b'\x00\xe0\xff\x00\x00\x00\xfe\x00\x00\x00\xe0\x00\x09\x00\x0f\x00'\ | ||||
| b'\x00\x0f\x0f\x00\x00\x0f\x0f\x00\x00\x0f\xff\xff\xff\x0f\xff\xff'\ | ||||
| b'\xff\x0f\xff\xff\xff\x0f\xff\xff\xff\x0f\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x0f\x00\x00\x80\x01\x00\x00\xf0\x01\x00\x00\xfc\x01\x00'\ | ||||
| b'\x80\xff\x01\x00\xe0\x3f\x00\x00\xf0\x07\x00\x00\xf0\x01\x00\x00'\ | ||||
| b'\xf0\x03\x00\x00\xf0\x1f\x00\x00\xc0\xff\x00\x00\x00\xfe\x01\x00'\ | ||||
| b'\x00\xf8\x01\x00\x00\xc0\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00'\ | ||||
| b'\x17\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ | ||||
| b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ | ||||
| b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ | ||||
| b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ | ||||
| b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00'\ | ||||
| b'\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x0c\x00'\ | ||||
| b'\x08\x00\x00\x00\x18\x00\x00\x00\x38\x00\x00\x00\x78\x00\x00\x00'\ | ||||
| b'\x70\x00\x00\x00\x60\x00\x00\x00\x40\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'\x11\x00\x00\x40\x3c\x00\x00\x30\x7e\x00\x00\x38\x7f\x00\x00\x7c'\ | ||||
| b'\xff\x00\x00\x3e\xf3\x00\x00\x1e\xf3\x00\x00\x1e\xf3\x00\x00\x1e'\ | ||||
| b'\xf1\x00\x00\x9e\x71\x00\x00\xbe\x79\x00\x00\xfc\xff\x00\x00\xfc'\ | ||||
| b'\xff\x00\x00\xf8\xff\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x12\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ | ||||
| b'\xfc\xff\xff\x00\xfc\xff\xff\x00\x00\x7c\x3c\x00\x00\x3c\x78\x00'\ | ||||
| b'\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00'\ | ||||
| b'\x00\x3e\xf8\x00\x00\x7c\x7c\x00\x00\xfc\x7f\x00\x00\xf8\x3f\x00'\ | ||||
| b'\x00\xf0\x1f\x00\x00\xc0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x10\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc'\ | ||||
| b'\x7f\x00\x00\x7c\x7c\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00\x00\x1e'\ | ||||
| b'\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x3c\xf8\x00\x00\x7c'\ | ||||
| b'\x7c\x00\x00\x78\x38\x00\x00\x30\x18\x00\x00\x20\x08\x00\x00\x00'\ | ||||
| b'\x00\x00\x12\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00'\ | ||||
| b'\x00\xfc\x7f\x00\x00\x7e\xfc\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00'\ | ||||
| b'\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x3c\x78\x00\x00\x7c\x7c\x00'\ | ||||
| b'\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\xe0'\ | ||||
| b'\x0f\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc\x7f\x00\x00\xdc'\ | ||||
| b'\x7b\x00\x00\xde\xf3\x00\x00\xde\xf3\x00\x00\xde\xf3\x00\x00\xde'\ | ||||
| b'\xf3\x00\x00\xde\xfb\x00\x00\xfc\x7b\x00\x00\xfc\x7b\x00\x00\xf8'\ | ||||
| b'\x33\x00\x00\xf0\x03\x00\x00\x80\x03\x00\x00\x00\x00\x00\x09\x00'\ | ||||
| b'\x00\x1c\x00\x00\x00\x1c\x00\x00\xc0\xff\xff\x00\xf0\xff\xff\x00'\ | ||||
| b'\xf0\xff\xff\x00\xf8\xff\xff\x00\x78\x1c\x00\x00\x3c\x1c\x00\x00'\ | ||||
| b'\x3c\x1c\x00\x00\x11\x00\x00\xc0\x07\x08\x00\xf0\x1f\x1c\x00\xf8'\ | ||||
| b'\x3f\x3c\x00\xfc\x7f\x3c\x00\x7e\xfc\x7c\x00\x3e\xf8\x78\x00\x1e'\ | ||||
| b'\xf0\x78\x00\x1e\xf0\x78\x00\x1e\xf0\x78\x00\x3c\x78\x7c\x00\x78'\ | ||||
| b'\x7c\x3e\x00\xfe\xff\x3f\x00\xfe\xff\x1f\x00\xfe\xff\x0f\x00\xfe'\ | ||||
| b'\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xfc\xff\xff\x00'\ | ||||
| b'\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\x00\x3c\x00\x00'\ | ||||
| b'\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00'\ | ||||
| b'\x00\x3e\x00\x00\x00\xfc\xff\x00\x00\xfc\xff\x00\x00\xf8\xff\x00'\ | ||||
| b'\x00\xe0\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x60\xfe'\ | ||||
| b'\xff\x00\xf0\xfe\xff\x00\xf0\xfe\xff\x00\x60\xfe\xff\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x78'\ | ||||
| b'\x00\x00\x00\x78\x60\xfe\xff\x7f\xf0\xfe\xff\x3f\xf0\xfe\xff\x3f'\ | ||||
| b'\x60\xfe\xff\x0f\x10\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff'\ | ||||
| b'\xff\x00\xfc\xff\xff\x00\x00\xc0\x07\x00\x00\xe0\x03\x00\x00\xf0'\ | ||||
| b'\x07\x00\x00\xfc\x0f\x00\x00\xfe\x3f\x00\x00\x3e\xff\x00\x00\x1e'\ | ||||
| b'\xfc\x00\x00\x0e\xf8\x00\x00\x06\xe0\x00\x00\x02\xc0\x00\x00\x00'\ | ||||
| b'\x80\x00\x00\x00\x00\x00\x07\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ | ||||
| b'\xfc\xff\xff\x00\xfc\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x1a\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe'\ | ||||
| b'\xff\x00\x00\xfe\xff\x00\x00\x3c\x00\x00\x00\x1e\x00\x00\x00\x1e'\ | ||||
| b'\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x3e\x00\x00\x00\xfc'\ | ||||
| b'\xff\x00\x00\xfc\xff\x00\x00\xf8\xff\x00\x00\xfc\xff\x00\x00\x3e'\ | ||||
| b'\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x3e'\ | ||||
| b'\x00\x00\x00\xfc\xff\x00\x00\xfc\xff\x00\x00\xf8\xff\x00\x00\xe0'\ | ||||
| b'\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'\ | ||||
| b'\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00'\ | ||||
| b'\x00\x3c\x00\x00\x00\x1c\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00'\ | ||||
| b'\x00\x1e\x00\x00\x00\x3e\x00\x00\x00\xfc\xff\x00\x00\xfc\xff\x00'\ | ||||
| b'\x00\xf8\xff\x00\x00\xe0\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x11\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc'\ | ||||
| b'\x7f\x00\x00\x7c\x7c\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00\x00\x1e'\ | ||||
| b'\xf0\x00\x00\x1e\xf0\x00\x00\x3e\xf8\x00\x00\x7c\x7c\x00\x00\xfc'\ | ||||
| b'\x7f\x00\x00\xf8\x3f\x00\x00\xf0\x1f\x00\x00\xc0\x07\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x12\x00\x00\xfe\xff\x7f\x00\xfe\xff\x7f'\ | ||||
| b'\x00\xfe\xff\x7f\x00\xfe\xff\x7f\x00\x7c\x7c\x00\x00\x3c\x78\x00'\ | ||||
| b'\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00\x00\x1e\xf0\x00'\ | ||||
| b'\x00\x3e\xf8\x00\x00\x7c\x7c\x00\x00\xfc\x7f\x00\x00\xf8\x3f\x00'\ | ||||
| b'\x00\xf0\x1f\x00\x00\xc0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x11\x00\x00\xc0\x07\x00\x00\xf0\x1f\x00\x00\xf8\x3f\x00\x00\xfc'\ | ||||
| b'\x7f\x00\x00\x7e\xfc\x00\x00\x3e\xf8\x00\x00\x1e\xf0\x00\x00\x1e'\ | ||||
| b'\xf0\x00\x00\x1e\xf0\x00\x00\x3c\x78\x00\x00\x7c\x7c\x00\x00\xfe'\ | ||||
| b'\xff\x7f\x00\xfe\xff\x7f\x00\xfe\xff\x7f\x00\xfe\xff\x7f\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x0a\x00\x00\xfe\xff\x00\x00\xfe\xff\x00'\ | ||||
| b'\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\x3c\x00\x00\x00\x1e\x00\x00'\ | ||||
| b'\x00\x1e\x00\x00\x00\x0e\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x0f\x00\x00\x00\x08\x00\x00\x70\x18\x00\x00\xfc\x38\x00\x00\xfc'\ | ||||
| b'\x7d\x00\x00\xfe\xf9\x00\x00\x9e\xf1\x00\x00\x9e\xf1\x00\x00\x9e'\ | ||||
| b'\xf1\x00\x00\x9e\xf3\x00\x00\x3e\xf3\x00\x00\x3c\x7f\x00\x00\x3c'\ | ||||
| b'\x7f\x00\x00\x38\x3e\x00\x00\x20\x1c\x00\x00\x00\x00\x00\x09\x00'\ | ||||
| b'\x00\x0e\x00\x00\x00\x0e\x00\x00\xfc\xff\x1f\x00\xfc\xff\x3f\x00'\ | ||||
| b'\xfc\xff\x7f\x00\xfc\xff\xff\x00\x00\x0e\xf0\x00\x00\x0e\xf0\x00'\ | ||||
| b'\x00\x0e\xf0\x00\x10\x00\x00\xfe\x0f\x00\x00\xfe\x3f\x00\x00\xfe'\ | ||||
| b'\x7f\x00\x00\xfe\x7f\x00\x00\x00\xf8\x00\x00\x00\xf0\x00\x00\x00'\ | ||||
| b'\xf0\x00\x00\x00\xf0\x00\x00\x00\x70\x00\x00\x00\x78\x00\x00\xfe'\ | ||||
| b'\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\xfe\xff\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x06\x00\x00\x00\x3e\x00\x00'\ | ||||
| b'\x00\xfe\x00\x00\x00\xfe\x07\x00\x00\xf8\x3f\x00\x00\xc0\xff\x00'\ | ||||
| b'\x00\x00\xfe\x00\x00\x00\xf0\x00\x00\x00\xfe\x00\x00\xc0\xff\x00'\ | ||||
| b'\x00\xf8\x1f\x00\x00\xfe\x07\x00\x00\xfe\x00\x00\x00\x1e\x00\x00'\ | ||||
| b'\x00\x06\x00\x00\x16\x00\x00\x06\x00\x00\x00\x7e\x00\x00\x00\xfe'\ | ||||
| b'\x03\x00\x00\xfe\x1f\x00\x00\xf0\xff\x00\x00\x00\xff\x00\x00\x00'\ | ||||
| b'\xf8\x00\x00\x80\xff\x00\x00\xf8\xff\x00\x00\xfe\x0f\x00\x00\xfe'\ | ||||
| b'\x00\x00\x00\xfe\x00\x00\x00\xfe\x07\x00\x00\xf8\x7f\x00\x00\x80'\ | ||||
| b'\xff\x00\x00\x00\xf8\x00\x00\x00\xff\x00\x00\xf0\xff\x00\x00\xfe'\ | ||||
| b'\x3f\x00\x00\xfe\x03\x00\x00\x7e\x00\x00\x00\x0e\x00\x00\x0f\x00'\ | ||||
| b'\x00\x02\x80\x00\x00\x06\xe0\x00\x00\x1e\xf0\x00\x00\x3e\xfc\x00'\ | ||||
| b'\x00\xfe\x7e\x00\x00\xf8\x3f\x00\x00\xe0\x0f\x00\x00\xe0\x07\x00'\ | ||||
| b'\x00\xf8\x1f\x00\x00\xfc\x7f\x00\x00\x7e\xfc\x00\x00\x1e\xf8\x00'\ | ||||
| b'\x00\x0e\xe0\x00\x00\x02\xc0\x00\x00\x00\x80\x00\x0f\x00\x00\x06'\ | ||||
| b'\x00\x00\x00\x3e\x00\x00\x00\xfe\x00\x78\x00\xfe\x07\x78\x00\xf8'\ | ||||
| b'\x1f\x7c\x00\xc0\xff\x7f\x00\x00\xfe\x3f\x00\x00\xf0\x1f\x00\x00'\ | ||||
| b'\xfe\x07\x00\xc0\xff\x00\x00\xf8\x1f\x00\x00\xfe\x07\x00\x00\xfe'\ | ||||
| b'\x00\x00\x00\x1e\x00\x00\x00\x06\x00\x00\x0e\x00\x00\x00\xe0\x00'\ | ||||
| b'\x00\x1e\xf0\x00\x00\x1e\xf8\x00\x00\x1e\xfc\x00\x00\x1e\xfe\x00'\ | ||||
| b'\x00\x1e\xff\x00\x00\x9e\xf7\x00\x00\xde\xf3\x00\x00\xfe\xf1\x00'\ | ||||
| b'\x00\xfe\xf0\x00\x00\x7e\xf0\x00\x00\x3e\xf0\x00\x00\x1e\xf0\x00'\ | ||||
| b'\x00\x00\x00\x00\x0a\x00\x00\x60\x00\x00\x00\xf0\x00\x00\x00\xf0'\ | ||||
| b'\x00\x00\xf8\xff\xff\x01\xfc\xff\xff\x03\xfe\x9f\xff\x07\xfe\x0f'\ | ||||
| b'\xff\x07\x0e\x00\x00\x07\x0e\x00\x00\x07\x00\x00\x00\x00\x08\x00'\ | ||||
| b'\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00\xfc\xff\xff\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ | ||||
| b'\x09\x00\x0e\x00\x00\x07\x0e\x00\x00\x07\xfe\x0f\xff\x07\xfe\x9f'\ | ||||
| b'\xff\x07\xfc\xff\xff\x03\xf8\xff\xff\x01\x00\xf0\x00\x00\x00\xf0'\ | ||||
| b'\x00\x00\x00\x60\x00\x00\x0c\x00\x30\x00\x00\x00\x38\x00\x00\x00'\ | ||||
| b'\x18\x00\x00\x00\x18\x00\x00\x00\x18\x00\x00\x00\x30\x00\x00\x00'\ | ||||
| b'\x30\x00\x00\x00\x30\x00\x00\x00\x38\x00\x00\x00\x18\x00\x00\x00'\ | ||||
| b'\x00\x00\x00\x00\x00\x00\x00\x00' | ||||
| 
 | ||||
| _index =\ | ||||
| b'\x00\x00\x3e\x00\x64\x00\x86\x00\xb0\x00\xee\x00\x28\x01\x86\x01'\ | ||||
| b'\xd4\x01\xea\x01\x10\x02\x36\x02\x64\x02\xa2\x02\xbc\x02\xe2\x02'\ | ||||
| b'\xfc\x02\x26\x03\x6c\x03\x92\x03\xd4\x03\x16\x04\x58\x04\x96\x04'\ | ||||
| b'\xd8\x04\x12\x05\x54\x05\x96\x05\xb0\x05\xca\x05\xfc\x05\x36\x06'\ | ||||
| b'\x68\x06\xa6\x06\x00\x07\x4e\x07\x98\x07\xea\x07\x38\x08\x7e\x08'\ | ||||
| b'\xc0\x08\x16\x09\x68\x09\x86\x09\xc4\x09\x0e\x0a\x50\x0a\xb2\x0a'\ | ||||
| b'\x04\x0b\x5e\x0b\xa8\x0b\xfe\x0b\x48\x0c\x92\x0c\xd0\x0c\x1a\x0d'\ | ||||
| b'\x60\x0d\xc6\x0d\x0c\x0e\x56\x0e\x9c\x0e\xc2\x0e\xec\x0e\x12\x0f'\ | ||||
| b'\x50\x0f\xae\x0f\xe0\x0f\x26\x10\x70\x10\xb2\x10\xfc\x10\x3e\x11'\ | ||||
| b'\x64\x11\xaa\x11\xec\x11\x0a\x12\x24\x12\x66\x12\x84\x12\xee\x12'\ | ||||
| b'\x30\x13\x76\x13\xc0\x13\x06\x14\x30\x14\x6e\x14\x94\x14\xd6\x14'\ | ||||
| b'\x14\x15\x6e\x15\xac\x15\xea\x15\x24\x16\x4e\x16\x70\x16\x96\x16'\ | ||||
| b'\xc8\x16' | ||||
| 
 | ||||
| _mvfont = memoryview(_font) | ||||
| 
 | ||||
| def _chr_addr(ordch): | ||||
|     offset = 2 * (ordch - 32) | ||||
|     return int.from_bytes(_index[offset:offset + 2], 'little') | ||||
|      | ||||
| def get_width(s): | ||||
|     width = 0 | ||||
|     for ch in s: | ||||
|         ordch = ord(ch) | ||||
|         ordch = ordch + 1 if ordch >= 32 and ordch <= 126 else 32 | ||||
|         offset = _chr_addr(ordch) | ||||
|         width += int.from_bytes(_font[offset:offset + 2], 'little') | ||||
|     return width | ||||
| 
 | ||||
| def get_ch(ch): | ||||
|     ordch = ord(ch) | ||||
|     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 _mvfont[offset + 2:next_offs], width | ||||
|   | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue