pull/7/head
Peter Hinch 2016-11-15 08:54:19 +00:00
rodzic eda4e2bbd9
commit 8bff972a29
9 zmienionych plików z 1252 dodań i 0 usunięć

Wyświetl plik

@ -1,6 +1,10 @@
# micropython-samples
A place for assorted code ideas for MicroPython. Most are targeted at the Pyboard variants.
## ssd1306
A means of rendering multiple larger fonts to the SSD1306 OLED display
## mutex
A class providing mutal exclusion enabling interrupt handlers and the main program to access shared
data in a manner which ensures data integrity.

120
SSD1306/README.md 100644
Wyświetl plik

@ -0,0 +1,120 @@
# ssd1306: Introduction
The official SSD1306 OLED display driver supports a single 8x8 pixel monospaced
font. Users of the 128x64 displays in particular may wish to use larger fonts.
This provides a means of extending the official driver to support this. Suitable
font files may be created from standard ``ttf`` or ``otf`` files using the utility
presented [here](https://github.com/peterhinch/micropython-font-to-py.git).
![Picture](ssd1306.JPG)
# Files
1. ssd1306_test.py A simple test program.
2. ssd1306.py A snapshot of the current official driver.
3. ssd1306_drv.py A temporary Python fix for a bug in the above.
4. writer.py A generic Writer class. Keeps track of the text insertion point
over multiple fonts, handles newline and vertical scrolling if required.
In addition several font files are provided as samples.
# Getting started
Edit ``ssd1306_test.py`` to match your hardware, namely whether it uses SPI or
I2C and the value of HEIGHT. The file contains details of how to wire the device
to a Pyboard. It is untested on other platforms, but I'd expect it to be
portable to any device supporting the official driver. If in doubt, install and
test this first.
Copy files 1-4 and ``freesans20.py`` to the target and issue
```python
import ssd1306_test
```
# Principle of Operation
Font files are converted to Python modules for ease of use and also (optionally)
to enable the modules to be frozen as bytecode to reduce RAM requirements.
The user program should import all fonts which are to be used and declare a
``Writer`` instance for each one. Rendering text at the current insertion point
is then simply a matter of issuing the appropriate writer's ``printstring``
method. After issuing all such calls required by your application the display
should be updated by issuing
```python
ssd.show()
```
# The Writer class
The principal interaction with the driver is via this class. One instance should
be created for each font in use. Its function is to keep track of the text
insertion point over successive uses with multiple fonts and to handle newline
characters and vertical scrolling. Its behaviour when text overruns the end of
a line or the bottom of the screen may be controlled using its ``set_clip``
method.
## Methods
1. ``Constructor`` This takes the ``ssd`` display instance and the font module
as mandatory args.
2. ``printstring`` Takes a text string as argument and renders it at the current
insertion point. Respects newline characters.
## Class methods
1. ``set_textpos`` Mandatory integer args ``row``, ``col`` defined in pixels
relative to the top left hand corner of the display. Sets the current text
insertion point. The coordinates of a glyph refer to its top left corner. The
initial default is (0,0) with text being rendered at the top left of the display.
2. ``set_clip`` Mandatory boolean args ``row_clip``, ``col_clip``. These define
behaviour when text overruns the physical width or height of the display. By
default text overrunning the display width will continue on the next row. Setting
``col_clip`` overrides this such that overrunning text is lost. Similarly, by
default text overrunning the bottom of the display will cause text above to
scroll up to accommodate it. Setting ``row_clip`` will override this behaviour
causing text to be clipped.
A final classmethod is provided for possible future use.
``mapping`` The current official ssd1306 driver configures the hardware to use
an unorthodox mapping of bytes onto pixels. The original plan for the
``framebuf`` module was that it should support vertical and horizontal mappings
only. Should the official ssd1306 driver be changed to use vertical mapping
(which the device supports) this method may be used to accommodate it. This mode
has been tested.
# Note
The official SSD1306 driver is based on the framebuf module which is in a state
of active development. The code presented here extends the official driver and
consequently may be less than stable if there is significant change to the
underlying framebuffer class. Further, the official driver's scroll method is
buggy and at the time of writing there is a moratorium on PR's. I have coded a
Python workround in the file ssd1306_drv.py. Hopefully in time this file will
become redundant and the official driver will support vertical scrolling over
long distances.
# License
Any code placed here is released under the MIT License (MIT).
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.

Wyświetl plik

@ -0,0 +1,248 @@
# Code generated by font-to-py.py.
# Font: FreeSans.ttf
version = '0.1'
def height():
return 20
def max_width():
return 20
def hmap():
return False
def reverse():
return False
def monospaced():
return False
_font =\
b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x07\x00\xfe\xcf\x00\xfe\xcf\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x7c\x00\x00\x3c\x00\x00'\
b'\x00\x00\x00\x7c\x00\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x0b'\
b'\x00\x00\x0c\x00\x60\x0c\x00\x60\xfc\x00\xe0\x3f\x00\xfc\x0c\x00'\
b'\x64\x0c\x00\x60\xfc\x00\xe0\x3f\x00\xfc\x0c\x00\x64\x0c\x00\x60'\
b'\x00\x00\x0b\x00\xf8\x30\x00\xfc\x71\x00\x8e\xe1\x00\x06\xc3\x00'\
b'\xff\xff\x01\x06\xc3\x00\x06\xc2\x00\x0c\x66\x00\x3c\x7e\x00\x38'\
b'\x3c\x00\x00\x00\x00\x12\x00\x70\x00\x00\xf8\x00\x00\x8c\x01\x00'\
b'\x8c\x01\x00\x8c\x81\x00\xf8\x60\x00\x70\x18\x00\x00\x06\x00\x80'\
b'\x01\x00\xc0\x38\x00\x30\x7c\x00\x0c\xee\x00\x00\xc6\x00\x00\xc6'\
b'\x00\x00\xee\x00\x00\x7c\x00\x00\x38\x00\x00\x00\x00\x0d\x00\x00'\
b'\x3c\x00\x00\x7e\x00\x70\xe6\x00\xf8\xc3\x00\x8c\xc1\x00\x8c\xc3'\
b'\x00\x8c\xc6\x00\xf8\x6c\x00\x70\x38\x00\x00\x7e\x00\x00\xc6\x00'\
b'\x00\x80\x00\x00\x00\x00\x04\x00\x7c\x00\x00\x3c\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x07\x00\x80\x3f\x00\xe0\xff\x00\x38\x80\x03\x06'\
b'\x00\x0e\x00\x00\x08\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x08'\
b'\x06\x00\x0e\x38\x80\x03\xe0\xff\x00\x80\x3f\x00\x00\x00\x00\x00'\
b'\x00\x00\x08\x00\x08\x00\x00\x68\x00\x00\x1e\x00\x00\x68\x00\x00'\
b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x0c'\
b'\x00\x00\x0c\x00\x00\x0c\x00\x80\xff\x00\x80\xff\x00\x00\x0c\x00'\
b'\x00\x0c\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x06\x00\x00\xc0\x04\x00\xc0\x03\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x07\x00\x00\x06\x00\x00\x06\x00\x00\x06'\
b'\x00\x00\x06\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00'\
b'\xc0\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00'\
b'\x00\xc0\x00\x00\x78\x00\x00\x0f\x00\xe0\x01\x00\x3c\x00\x00\x06'\
b'\x00\x00\x0b\x00\xe0\x1f\x00\xf8\x7f\x00\x3c\xf0\x00\x0c\xc0\x00'\
b'\x0c\xc0\x00\x0c\xc0\x00\x3c\xf0\x00\xf8\x7f\x00\xe0\x1f\x00\x00'\
b'\x00\x00\x00\x00\x00\x0b\x00\x30\x00\x00\x30\x00\x00\xf8\xff\x00'\
b'\xfc\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x30\xe0\x00\x38\xf0\x00'\
b'\x1c\xd8\x00\x0c\xcc\x00\x0c\xc6\x00\x0c\xc6\x00\x1c\xc3\x00\xf8'\
b'\xc1\x00\xf0\xc0\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x30\x30\x00'\
b'\x38\x70\x00\x1c\xe0\x00\x0c\xc0\x00\x8c\xc1\x00\x8c\xc1\x00\x9c'\
b'\xe3\x00\xf8\x7f\x00\x70\x3e\x00\x00\x00\x00\x00\x00\x00\x0b\x00'\
b'\x00\x1c\x00\x00\x1b\x00\x80\x18\x00\x60\x18\x00\x30\x18\x00\xfc'\
b'\xff\x00\xfc\xff\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x0b\x00\xc0\x21\x00\xfc\x61\x00\xbc\xc1\x00\xcc\xc0\x00\xcc'\
b'\xc0\x00\xcc\xc0\x00\xcc\xe1\x00\x8c\x7f\x00\x00\x1f\x00\x00\x00'\
b'\x00\x00\x00\x00\x0b\x00\xc0\x1f\x00\xf0\x7f\x00\x38\xe3\x00\x8c'\
b'\xc1\x00\x8c\xc1\x00\x8c\xc1\x00\x9c\xe3\x00\x38\x7f\x00\x20\x3e'\
b'\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x0c\x00\x00\x0c\x00\x00\x0c'\
b'\xc0\x00\x0c\xf8\x00\x0c\x1e\x00\x8c\x03\x00\xec\x00\x00\x3c\x00'\
b'\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x1c\x00\x70'\
b'\x7e\x00\xf8\x63\x00\x8c\xc1\x00\x8c\xc1\x00\x8c\xc1\x00\xf8\x63'\
b'\x00\x70\x7e\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x0b\x00\xf0'\
b'\x21\x00\xf8\x63\x00\x1c\xe7\x00\x0c\xc6\x00\x0c\xc6\x00\x0c\xc6'\
b'\x00\x1c\x73\x00\xf8\x3f\x00\xe0\x0f\x00\x00\x00\x00\x00\x00\x00'\
b'\x05\x00\x60\xc0\x00\x60\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x05\x00\xc0\xc0\x04\xc0\xc0\x03\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x0c\x00\x00\x0c\x00\x00\x1c\x00\x00\x1e\x00\x00\x12\x00'\
b'\x00\x32\x00\x00\x23\x00\x00\x61\x00\x80\x61\x00\x80\x40\x00\xc0'\
b'\xc0\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x33\x00\x00\x33\x00'\
b'\x00\x33\x00\x00\x33\x00\x00\x33\x00\x00\x33\x00\x00\x33\x00\x00'\
b'\x33\x00\x00\x33\x00\x00\x33\x00\x00\x00\x00\x00\x00\x00\x0c\x00'\
b'\x80\xc0\x00\x80\x41\x00\x80\x61\x00\x00\x61\x00\x00\x23\x00\x00'\
b'\x32\x00\x00\x16\x00\x00\x1c\x00\x00\x0c\x00\x00\x0c\x00\x00\x00'\
b'\x00\x00\x00\x00\x0b\x00\x18\x00\x00\x1c\x00\x00\x06\x00\x00\x06'\
b'\xcc\x00\x06\xcf\x00\x8e\x01\x00\xfc\x00\x00\x78\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x1f\x00\xe0\x7f\x00\xf0'\
b'\xe0\x01\x38\x80\x01\x1c\x1f\x03\x8c\x3f\x03\xce\x71\x06\xe6\x60'\
b'\x06\x66\x60\x06\x66\x30\x06\x66\x38\x06\x86\x7f\x06\xcc\x63\x02'\
b'\x0c\x60\x00\x18\x70\x00\x78\x38\x00\xf0\x1f\x00\xc0\x07\x00\x00'\
b'\x00\x00\x00\x00\x00\x0d\x00\x00\x80\x00\x00\xe0\x00\x00\x7c\x00'\
b'\x80\x1f\x00\xf0\x0d\x00\x3e\x0c\x00\x0e\x0c\x00\x3e\x0c\x00\xf8'\
b'\x0d\x00\xc0\x0f\x00\x00\x7e\x00\x00\xf0\x00\x00\xc0\x00\x0d\x00'\
b'\xfe\xff\x00\xfe\xff\x00\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00\x86'\
b'\xc1\x00\x86\xc1\x00\xce\xc1\x00\x7c\xe3\x00\x78\x7e\x00\x00\x3c'\
b'\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xe0\x0f\x00\xf8\x3f\x00\x3c'\
b'\x78\x00\x0c\x60\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0'\
b'\x00\x06\xc0\x00\x0c\x70\x00\x1c\x78\x00\x10\x18\x00\x00\x00\x00'\
b'\x00\x00\x00\x0e\x00\xfe\xff\x00\xfe\xff\x00\x06\xc0\x00\x06\xc0'\
b'\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x0e\xe0\x00\x1c\x70\x00'\
b'\xf8\x3f\x00\xe0\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d'\
b'\x00\xfe\xff\x00\xfe\xff\x00\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00'\
b'\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00\x86\xc1\x00\x06\xc0\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\xfe\xff\x00\xfe\xff\x00'\
b'\x86\x01\x00\x86\x01\x00\x86\x01\x00\x86\x01\x00\x86\x01\x00\x86'\
b'\x01\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00'\
b'\xc0\x0f\x00\xf0\x3f\x00\x3c\x78\x00\x0c\x60\x00\x0e\xe0\x00\x06'\
b'\xc0\x00\x06\xc0\x00\x06\xc3\x00\x06\xc3\x00\x06\x63\x00\x0c\x33'\
b'\x00\x1c\x7f\x00\x10\xff\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xfe'\
b'\xff\x00\xfe\xff\x00\x80\x01\x00\x80\x01\x00\x80\x01\x00\x80\x01'\
b'\x00\x80\x01\x00\x80\x01\x00\x80\x01\x00\xfe\xff\x00\xfe\xff\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\xfe\xff\x00\xfe\xff'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00'\
b'\x38\x00\x00\x78\x00\x00\xe0\x00\x00\xc0\x00\x00\xc0\x00\x00\xe0'\
b'\x00\xfe\x7f\x00\xfe\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x0d\x00\xfe\xff\x00\xfe\xff\x00\x00\x03\x00\x80\x01\x00\xc0\x00'\
b'\x00\xe0\x03\x00\x30\x07\x00\x18\x1c\x00\x0c\x38\x00\x06\xe0\x00'\
b'\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x0b\x00\xfe\xff\x00\xfe\xff'\
b'\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00'\
b'\x00\xc0\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x11\x00\xfe\xff'\
b'\x00\xfe\xff\x00\x1e\x00\x00\xf8\x00\x00\xc0\x07\x00\x00\x3e\x00'\
b'\x00\xf0\x00\x00\xe0\x00\x00\x3e\x00\xc0\x07\x00\xf8\x00\x00\x1e'\
b'\x00\x00\xfe\xff\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x0f\x00\xfe\xff\x00\xfe\xff\x00\x1e\x00\x00\x78\x00\x00\xe0'\
b'\x00\x00\x80\x03\x00\x00\x0e\x00\x00\x38\x00\x00\xf0\x00\xfe\xff'\
b'\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x10\x00\xc0\x07\x00\xf0\x1f\x00\x38\x38\x00\x0c\x60\x00\x0e\xe0'\
b'\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x06\xc0\x00\x0e\xe0\x00'\
b'\x0c\x60\x00\x38\x38\x00\xf0\x1f\x00\xe0\x0f\x00\x00\x00\x00\x00'\
b'\x00\x00\x0d\x00\xfe\xff\x00\xfe\xff\x00\x06\x03\x00\x06\x03\x00'\
b'\x06\x03\x00\x06\x03\x00\x06\x03\x00\x8e\x03\x00\xfc\x01\x00\xf8'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xc0\x07\x00'\
b'\xf0\x1f\x00\x38\x38\x00\x0c\x60\x00\x0e\xe0\x00\x06\xc0\x00\x06'\
b'\xc0\x00\x06\xc0\x00\x06\xd0\x00\x0e\x70\x00\x0c\x60\x00\x38\xf8'\
b'\x00\xf0\xdf\x01\xe0\x07\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xfe'\
b'\xff\x00\xfe\xff\x00\x06\x03\x00\x06\x03\x00\x06\x03\x00\x06\x03'\
b'\x00\x06\x03\x00\x06\x03\x00\x8e\x07\x00\xfc\xfe\x00\x78\xfc\x00'\
b'\x00\x80\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x78\x18\x00\xfc\x78'\
b'\x00\xcc\x61\x00\x86\xe1\x00\x86\xc1\x00\x06\xc1\x00\x06\xc3\x00'\
b'\x06\xc3\x00\x06\xc3\x00\x0c\x66\x00\x1c\x7e\x00\x18\x1c\x00\x00'\
b'\x00\x00\x0d\x00\x06\x00\x00\x06\x00\x00\x06\x00\x00\x06\x00\x00'\
b'\xfe\xff\x00\xfe\xff\x00\x06\x00\x00\x06\x00\x00\x06\x00\x00\x06'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xfe\x1f\x00'\
b'\xfe\x7f\x00\x00\x60\x00\x00\xc0\x00\x00\xc0\x00\x00\xc0\x00\x00'\
b'\xc0\x00\x00\xc0\x00\x00\x60\x00\xfe\x7f\x00\xfe\x1f\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x02\x00\x00\x0e\x00\x00\x7c'\
b'\x00\x00\xe0\x03\x00\x00\x1f\x00\x00\xf8\x00\x00\xe0\x00\x00\xf8'\
b'\x00\x00\x1f\x00\xe0\x03\x00\x7e\x00\x00\x0e\x00\x00\x00\x00\x00'\
b'\x13\x00\x02\x00\x00\x3e\x00\x00\xfc\x03\x00\xc0\x3f\x00\x00\xf8'\
b'\x00\x00\xf8\x00\x00\x7f\x00\xf0\x0f\x00\xfe\x00\x00\x1e\x00\x00'\
b'\xfc\x00\x00\xe0\x0f\x00\x00\x7e\x00\x00\xe0\x00\x00\xfc\x00\xe0'\
b'\x1f\x00\xfe\x01\x00\x1e\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x00'\
b'\x02\xc0\x00\x0e\xe0\x00\x1c\x78\x00\x70\x1c\x00\xe0\x07\x00\x80'\
b'\x03\x00\xc0\x07\x00\x70\x1c\x00\x3c\x38\x00\x0e\xf0\x00\x06\xc0'\
b'\x00\x00\x80\x00\x0e\x00\x00\x00\x00\x06\x00\x00\x0e\x00\x00\x3c'\
b'\x00\x00\xf0\x00\x00\xc0\x01\x00\x80\xff\x00\x80\xff\x00\xc0\x01'\
b'\x00\xf0\x00\x00\x3c\x00\x00\x0e\x00\x00\x06\x00\x00\x00\x00\x00'\
b'\x0c\x00\x06\xe0\x00\x06\xf0\x00\x06\xdc\x00\x06\xce\x00\x06\xc7'\
b'\x00\x86\xc3\x00\xe6\xc0\x00\x76\xc0\x00\x3e\xc0\x00\x0e\xc0\x00'\
b'\x06\xc0\x00\x00\x00\x00\x06\x00\xfe\xff\x0f\xfe\xff\x0f\x06\x00'\
b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x06\x00\x00\x3c'\
b'\x00\x00\xe0\x01\x00\x00\x0f\x00\x00\x78\x00\x00\xc0\x00\x06\x00'\
b'\x06\x00\x0c\xfe\xff\x0f\xfe\xff\x0f\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x09\x00\x00\x03\x00\xc0\x01\x00\x78\x00\x00\x0c\x00\x00'\
b'\x3c\x00\x00\xe0\x00\x00\x80\x03\x00\x00\x00\x00\x00\x00\x00\x0c'\
b'\x00\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01'\
b'\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00'\
b'\x00\x01\x00\x00\x01\x05\x00\x02\x00\x00\x06\x00\x00\x0c\x00\x00'\
b'\x08\x00\x00\x00\x00\x00\x0b\x00\xc0\x78\x00\xc0\xf8\x00\x60\xcc'\
b'\x00\x60\xcc\x00\x60\xc4\x00\x60\x44\x00\x60\x64\x00\xc0\x7f\x00'\
b'\xc0\xff\x00\x00\xc0\x00\x00\x00\x00\x0b\x00\xfe\xff\x00\xfe\xff'\
b'\x00\xc0\x60\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00'\
b'\xe0\x60\x00\xc0\x7f\x00\x00\x1f\x00\x00\x00\x00\x0a\x00\x00\x1f'\
b'\x00\xc0\x7f\x00\xc0\xe0\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00'\
b'\x60\xe0\x00\xc0\x70\x00\x80\x30\x00\x00\x00\x00\x0b\x00\x00\x1f'\
b'\x00\xc0\x7f\x00\xe0\xe0\x00\x60\xc0\x00\x60\xc0\x00\x60\xc0\x00'\
b'\xc0\x60\x00\xfe\xff\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x0b'\
b'\x00\x00\x1f\x00\xc0\x7f\x00\xe0\xe6\x00\x60\xc6\x00\x60\xc6\x00'\
b'\x60\xc6\x00\xe0\xe6\x00\xc0\x67\x00\x00\x27\x00\x00\x00\x00\x00'\
b'\x00\x00\x06\x00\x60\x00\x00\xfc\xff\x00\xfe\xff\x00\x66\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x1f\x02\xc0\x7f\x06\xe0\xe0'\
b'\x0c\x60\xc0\x0c\x60\xc0\x0c\x60\xc0\x0c\xc0\x60\x0e\xe0\xff\x07'\
b'\xe0\xff\x03\x00\x00\x00\x00\x00\x00\x0b\x00\xfe\xff\x00\xfe\xff'\
b'\x00\x80\x00\x00\x60\x00\x00\x60\x00\x00\x60\x00\x00\xe0\x00\x00'\
b'\xe0\xff\x00\xc0\xff\x00\x00\x00\x00\x00\x00\x00\x04\x00\xe6\xff'\
b'\x00\xe6\xff\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x0c\x00'\
b'\x00\x0c\xe6\xff\x0f\xe6\xff\x07\x00\x00\x00\x0a\x00\xfe\xff\x00'\
b'\xfe\xff\x00\x00\x06\x00\x00\x03\x00\x80\x0f\x00\xc0\x1c\x00\x60'\
b'\x78\x00\x20\xe0\x00\x00\x80\x00\x00\x00\x00\x04\x00\xfe\xff\x00'\
b'\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x10\x00\xe0\xff\x00\xe0\xff'\
b'\x00\xc0\x00\x00\x60\x00\x00\x60\x00\x00\x60\x00\x00\xe0\xff\x00'\
b'\x80\xff\x00\xc0\x00\x00\x60\x00\x00\x60\x00\x00\x60\x00\x00\xe0'\
b'\xff\x00\xc0\xff\x00\x00\x00\x00\x00\x00\x00\x0b\x00\xe0\xff\x00'\
b'\xe0\xff\x00\x80\x00\x00\x40\x00\x00\x60\x00\x00\x60\x00\x00\xe0'\
b'\x00\x00\xe0\xff\x00\xc0\xff\x00\x00\x00\x00\x00\x00\x00\x0b\x00'\
b'\x00\x1f\x00\xc0\x7f\x00\xe0\xe0\x00\x60\xc0\x00\x60\xc0\x00\x60'\
b'\xc0\x00\xe0\xe0\x00\xc0\x7f\x00\x00\x1f\x00\x00\x00\x00\x00\x00'\
b'\x00\x0b\x00\xe0\xff\x07\xe0\xff\x07\xc0\x60\x00\x60\xc0\x00\x60'\
b'\xc0\x00\x60\xc0\x00\x60\xc0\x00\xc0\x60\x00\xc0\x7f\x00\x00\x1f'\
b'\x00\x00\x00\x00\x0b\x00\x00\x1f\x00\xc0\x7f\x00\xe0\xe0\x00\x60'\
b'\xc0\x00\x60\xc0\x00\x60\xc0\x00\xc0\x60\x00\xe0\xff\x07\xe0\xff'\
b'\x07\x00\x00\x00\x00\x00\x00\x07\x00\xe0\xff\x00\xe0\xff\x00\xc0'\
b'\x00\x00\x60\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00'\
b'\x80\x63\x00\xc0\xe7\x00\x60\xc6\x00\x60\xc6\x00\x60\xcc\x00\x60'\
b'\xcc\x00\xc0\x7c\x00\xc0\x38\x00\x00\x00\x00\x00\x00\x00\x06\x00'\
b'\x60\x00\x00\xf8\xff\x00\xf8\xff\x00\x60\xc0\x00\x00\x00\x00\x00'\
b'\x00\x00\x0b\x00\xe0\x7f\x00\xe0\xff\x00\x00\xe0\x00\x00\xc0\x00'\
b'\x00\xc0\x00\x00\x40\x00\x00\x20\x00\xe0\xff\x00\xe0\xff\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x20\x00\x00\xe0\x01\x00\xc0\x0f\x00'\
b'\x00\x7c\x00\x00\xe0\x00\x00\xf0\x00\x00\x3e\x00\xc0\x07\x00\xe0'\
b'\x00\x00\x20\x00\x00\x0e\x00\x60\x00\x00\xe0\x03\x00\x80\x3f\x00'\
b'\x00\xf8\x00\x00\xf0\x00\x00\x3f\x00\xe0\x03\x00\xe0\x01\x00\xc0'\
b'\x1f\x00\x00\xfc\x00\x00\xe0\x00\x00\x7e\x00\xe0\x07\x00\xe0\x00'\
b'\x00\x0a\x00\x00\x00\x00\x60\xc0\x00\xe0\x60\x00\x80\x3b\x00\x00'\
b'\x0f\x00\x00\x1f\x00\xc0\x71\x00\xe0\xe0\x00\x20\x80\x00\x00\x00'\
b'\x00\x0a\x00\x20\x00\x00\xe0\x01\x0c\x80\x0f\x0c\x00\x7c\x0e\x00'\
b'\xe0\x07\x00\xf0\x00\x00\x1e\x00\xc0\x07\x00\xe0\x00\x00\x00\x00'\
b'\x00\x0a\x00\x60\xe0\x00\x60\xf0\x00\x60\xd8\x00\x60\xcc\x00\x60'\
b'\xc6\x00\xe0\xc3\x00\xe0\xc1\x00\x60\xc0\x00\x00\x00\x00\x00\x00'\
b'\x00\x07\x00\x00\x04\x00\x00\x0e\x00\xfc\xfb\x07\xfe\xfb\x0f\x06'\
b'\x00\x0c\x00\x00\x00\x00\x00\x00\x05\x00\xfe\xff\x0f\xfe\xff\x0f'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x06\x00\x0c\xfe\xfb'\
b'\x0f\xfc\xfb\x07\x00\x0e\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'\
b'\x0a\x00\x00\x03\x00\x80\x01\x00\x80\x01\x00\x00\x03\x00\x00\x02'\
b'\x00\x00\x06\x00\x00\x06\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'\
_index =\
b'\x00\x00\x11\x00\x28\x00\x3f\x00\x62\x00\x85\x00\xbd\x00\xe6\x00'\
b'\xf4\x00\x0b\x01\x22\x01\x3c\x01\x62\x01\x76\x01\x8d\x01\x9e\x01'\
b'\xb2\x01\xd5\x01\xf8\x01\x1b\x02\x3e\x02\x61\x02\x84\x02\xa7\x02'\
b'\xca\x02\xed\x02\x10\x03\x21\x03\x32\x03\x58\x03\x7e\x03\xa4\x03'\
b'\xc7\x03\x05\x04\x2e\x04\x57\x04\x83\x04\xaf\x04\xd8\x04\xfe\x04'\
b'\x2d\x05\x59\x05\x6d\x05\x90\x05\xb9\x05\xdc\x05\x11\x06\x40\x06'\
b'\x72\x06\x9b\x06\xcd\x06\xf9\x06\x22\x07\x4b\x07\x77\x07\xa0\x07'\
b'\xdb\x07\x04\x08\x30\x08\x56\x08\x6a\x08\x7e\x08\x92\x08\xaf\x08'\
b'\xd5\x08\xe6\x08\x09\x09\x2c\x09\x4c\x09\x6f\x09\x92\x09\xa6\x09'\
b'\xc9\x09\xec\x09\xfa\x09\x0b\x0a\x2b\x0a\x39\x0a\x6b\x0a\x8e\x0a'\
b'\xb1\x0a\xd4\x0a\xf7\x0a\x0e\x0b\x2e\x0b\x42\x0b\x65\x0b\x85\x0b'\
b'\xb1\x0b\xd1\x0b\xf1\x0b\x11\x0c\x28\x0c\x39\x0c\x50\x0c\x70\x0c'\
def _chr_addr(ordch):
offset = 2 * (ordch - 32)
return int.from_bytes(_index[offset:offset + 2], 'little')
def get_ch(ch):
ordch = ord(ch)
ordch = ordch if ordch >= 32 and ordch <= 126 else ord('?')
offset = _chr_addr(ordch)
width = int.from_bytes(_font[offset:offset + 2], 'little')
next_offs = _chr_addr(ordch +1)
return memoryview(_font[offset + 2:next_offs]), 20, width

Wyświetl plik

@ -0,0 +1,242 @@
# Code generated by font-to-py.py.
# Font: FreeSerif.ttf
version = '0.1'
def height():
return 19
def max_width():
return 19
def hmap():
return False
def reverse():
return False
def monospaced():
return False
_font =\
b'\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x07\x00\xfe\x31\x00\x7e\x30\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x1f\x00\x00\x0f\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x0f\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x0a\x00\x00\x02\x00\x20\x02\x00\x20\x3f\x00\xfc\x03\x00'\
b'\x26\x02\x00\x20\x02\x00\xa0\x3f\x00\xfe\x02\x00\x22\x02\x00\x20'\
b'\x00\x00\x0a\x00\x38\x1c\x00\x7c\x30\x00\x66\x20\x00\xc2\x20\x00'\
b'\xff\x7f\x00\x82\x21\x00\x86\x31\x00\x0c\x1f\x00\x00\x0e\x00\x00'\
b'\x00\x00\x11\x00\x78\x00\x00\xfc\x01\x00\x0c\x01\x00\x06\x21\x00'\
b'\x82\x10\x00\xc2\x0c\x00\x3c\x03\x00\xc4\x00\x00\x24\x1e\x00\x1c'\
b'\x3f\x00\x86\x23\x00\xc0\x20\x00\x40\x30\x00\x40\x18\x00\x80\x07'\
b'\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x1e\x00\x00\x3f\x00\x80'\
b'\x31\x00\xbc\x20\x00\xfe\x20\x00\xe1\x21\x00\xa1\x27\x00\x11\x1e'\
b'\x00\x0e\x1c\x00\x20\x32\x00\xe0\x21\x00\x60\x20\x00\x20\x20\x00'\
b'\x00\x10\x00\x00\x00\x00\x00\x00\x00\x04\x00\x1f\x00\x00\x0f\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x07\x00\xc0\x0f\x00\xf0\x3f\x00\x18'\
b'\x60\x00\x04\x80\x00\x02\x00\x01\x00\x00\x00\x00\x00\x00\x07\x00'\
b'\x02\x00\x01\x04\x80\x00\x18\x60\x00\xf0\x3f\x00\xc0\x0f\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x4c\x00\x00\xb2\x01\x00\xfe\x01\x00'\
b'\x30\x00\x00\x48\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x0b\x00\x00\x02\x00\x00\x02\x00\x00\x02\x00'\
b'\x00\x02\x00\xe0\x3f\x00\x00\x02\x00\x00\x02\x00\x00\x02\x00\x00'\
b'\x02\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\xb0\x00'\
b'\x00\x70\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x02\x00\x00\x02'\
b'\x00\x00\x02\x00\x00\x02\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00'\
b'\x05\x00\x00\x30\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x06\x00\x00\x20\x00\x00\x3c\x00\x80\x07\x00\xf0\x00\x00\x1e'\
b'\x00\x00\x03\x00\x00\x0a\x00\xf0\x03\x00\xfc\x0f\x00\x06\x18\x00'\
b'\x03\x30\x00\x01\x20\x00\x01\x20\x00\x03\x30\x00\x06\x18\x00\xfc'\
b'\x0f\x00\xf0\x03\x00\x0a\x00\x02\x00\x00\x02\x20\x00\xff\x3f\x00'\
b'\xff\x3f\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x18\x20\x00\x04\x30\x00\x02\x38\x00'\
b'\x02\x2c\x00\x02\x26\x00\x86\x21\x00\xfc\x20\x00\x38\x20\x00\x00'\
b'\x10\x00\x00\x00\x00\x0a\x00\x04\x20\x00\x02\x20\x00\x42\x20\x00'\
b'\x62\x20\x00\xe6\x20\x00\xfe\x10\x00\xcc\x0f\x00\x80\x07\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x00\x07\x00\x80\x04\x00\x60\x04\x00'\
b'\x10\x04\x00\x08\x04\x00\xfc\x3f\x00\xfe\x3f\x00\x00\x04\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x00\x20\x00\x10\x20\x00\x3c\x20\x00'\
b'\x32\x20\x00\x32\x20\x00\xe2\x10\x00\xe2\x0f\x00\xc2\x07\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\xe0\x07\x00\xf8\x1f\x00\x7c\x18\x00'\
b'\x2c\x20\x00\x26\x20\x00\x22\x20\x00\x63\x30\x00\xc1\x1f\x00\x81'\
b'\x0f\x00\x00\x00\x00\x0a\x00\x04\x00\x00\x02\x00\x00\x02\x00\x00'\
b'\x02\x30\x00\x02\x0e\x00\xc2\x01\x00\x3a\x00\x00\x06\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x1c\x0e\x00\x3e\x1f\x00\xf3\x30\x00'\
b'\x61\x20\x00\xc1\x20\x00\xa3\x31\x00\x1e\x1f\x00\x1c\x0e\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x7c\x00\x00\xfe\x40\x00\x83\x61\x00'\
b'\x01\x31\x00\x01\x39\x00\x03\x1f\x00\xfe\x07\x00\xf8\x01\x00\x00'\
b'\x00\x00\x00\x00\x00\x05\x00\x60\x30\x00\x60\x30\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x05\x00\x60\x00\x01\x60\xb0\x00\x00\x70'\
b'\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x03\x00\x80\x03\x00\x80'\
b'\x06\x00\xc0\x04\x00\x40\x0c\x00\x60\x08\x00\x20\x18\x00\x30\x10'\
b'\x00\x10\x10\x00\x10\x30\x00\x00\x00\x00\x0b\x00\x80\x08\x00\x80'\
b'\x08\x00\x80\x08\x00\x80\x08\x00\x80\x08\x00\x80\x08\x00\x80\x08'\
b'\x00\x80\x08\x00\x80\x08\x00\x80\x08\x00\x00\x00\x00\x0b\x00\x30'\
b'\x20\x00\x20\x20\x00\x20\x30\x00\x60\x10\x00\x40\x18\x00\xc0\x08'\
b'\x00\x80\x0c\x00\x80\x05\x00\x00\x07\x00\x00\x03\x00\x00\x00\x00'\
b'\x09\x00\x0e\x00\x00\x02\x00\x00\x01\x00\x00\x01\x30\x00\x81\x37'\
b'\x00\x7f\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\xe0'\
b'\x03\x00\xf8\x07\x00\x1c\x0c\x00\x06\x18\x00\x82\x13\x00\xe1\x27'\
b'\x00\x71\x24\x00\x11\x24\x00\x11\x22\x00\xe1\x27\x00\x72\x24\x00'\
b'\x06\x14\x00\x0c\x02\x00\xf0\x01\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x0e\x00\x00\x20\x00\x00\x30\x00\x00\x38\x00\x00\x27\x00'\
b'\xc0\x03\x00\x30\x02\x00\x0c\x02\x00\x3e\x02\x00\xf8\x02\x00\xc0'\
b'\x23\x00\x00\x3f\x00\x00\x3c\x00\x00\x30\x00\x00\x20\x00\x0d\x00'\
b'\x02\x20\x00\x02\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x82\x20\x00\x82'\
b'\x20\x00\x82\x20\x00\x82\x20\x00\x82\x20\x00\x46\x31\x00\x7c\x1f'\
b'\x00\x38\x0e\x00\x00\x00\x00\x0d\x00\xf0\x03\x00\xfc\x0f\x00\x0e'\
b'\x1c\x00\x02\x10\x00\x03\x30\x00\x01\x20\x00\x01\x20\x00\x01\x20'\
b'\x00\x01\x20\x00\x02\x20\x00\x0e\x10\x00\x1f\x08\x00\x00\x00\x00'\
b'\x0e\x00\x02\x20\x00\x02\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x02\x20'\
b'\x00\x02\x20\x00\x02\x20\x00\x02\x20\x00\x06\x20\x00\x04\x30\x00'\
b'\x0c\x18\x00\x1c\x1c\x00\xf8\x0f\x00\xe0\x03\x00\x0c\x00\x02\x20'\
b'\x00\xfe\x3f\x00\xfe\x3f\x00\x82\x20\x00\x82\x20\x00\x82\x20\x00'\
b'\x82\x20\x00\x82\x20\x00\xc2\x21\x00\x06\x30\x00\x00\x08\x00\x00'\
b'\x00\x00\x0b\x00\x02\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x82\x20\x00'\
b'\x82\x00\x00\x82\x00\x00\x82\x00\x00\x82\x00\x00\xc2\x01\x00\x06'\
b'\x00\x00\x00\x00\x00\x0e\x00\xf0\x03\x00\xfc\x0f\x00\x0e\x1c\x00'\
b'\x02\x10\x00\x03\x30\x00\x01\x20\x00\x01\x20\x00\x01\x20\x00\x01'\
b'\x20\x00\x42\x20\x00\xc6\x1f\x00\xcf\x1f\x00\x40\x00\x00\x00\x00'\
b'\x00\x0e\x00\x02\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x82\x20\x00\x80'\
b'\x00\x00\x80\x00\x00\x80\x00\x00\x80\x00\x00\x82\x20\x00\xfe\x3f'\
b'\x00\xfe\x3f\x00\x02\x20\x00\x00\x00\x00\x00\x00\x00\x07\x00\x02'\
b'\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x02\x20\x00\x02\x20\x00\x00\x00'\
b'\x00\x00\x00\x00\x08\x00\x00\x30\x00\x00\x30\x00\x00\x20\x00\x02'\
b'\x20\x00\xfe\x1f\x00\xfe\x0f\x00\x02\x00\x00\x00\x00\x00\x0e\x00'\
b'\x02\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x82\x20\x00\xc0\x01\x00\xa0'\
b'\x01\x00\x30\x03\x00\x1a\x26\x00\x0e\x3c\x00\x06\x38\x00\x02\x30'\
b'\x00\x02\x20\x00\x00\x20\x00\x00\x00\x00\x0c\x00\x02\x20\x00\xfe'\
b'\x3f\x00\xfe\x3f\x00\x02\x20\x00\x00\x20\x00\x00\x20\x00\x00\x20'\
b'\x00\x00\x20\x00\x00\x20\x00\x00\x30\x00\x00\x38\x00\x00\x08\x00'\
b'\x12\x00\x02\x00\x00\x02\x20\x00\xfe\x3f\x00\x1e\x20\x00\x7e\x00'\
b'\x00\xf8\x01\x00\xe0\x03\x00\x80\x0f\x00\x00\x3e\x00\x00\x0c\x00'\
b'\x00\x03\x00\xc0\x00\x00\x30\x00\x00\x0c\x20\x00\xfe\x3f\x00\xfe'\
b'\x3f\x00\x02\x20\x00\x00\x00\x00\x0f\x00\x02\x20\x00\xfe\x3f\x00'\
b'\x0e\x20\x00\x3c\x00\x00\x78\x00\x00\xe0\x00\x00\xc0\x01\x00\x80'\
b'\x03\x00\x00\x0f\x00\x02\x1c\x00\xfe\x3f\x00\x02\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xf0\x03\x00\xfc\x0f\x00\x0e'\
b'\x1c\x00\x02\x10\x00\x01\x20\x00\x01\x20\x00\x01\x20\x00\x01\x20'\
b'\x00\x02\x10\x00\x0e\x1c\x00\xfc\x0f\x00\xf0\x03\x00\x00\x00\x00'\
b'\x00\x00\x00\x0c\x00\x02\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x02\x21'\
b'\x00\x02\x01\x00\x02\x01\x00\x02\x01\x00\x86\x01\x00\xfc\x00\x00'\
b'\x78\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\xf0\x03\x00\xfc\x0f'\
b'\x00\x0e\x18\x00\x02\x30\x00\x01\x20\x00\x01\x60\x00\x01\xe0\x00'\
b'\x01\xe0\x01\x02\xb0\x01\x0e\x1c\x03\xfc\x0f\x02\xf0\x03\x02\x00'\
b'\x00\x00\x00\x00\x00\x0d\x00\x02\x20\x00\xfe\x3f\x00\xfe\x3f\x00'\
b'\x82\x20\x00\x82\x00\x00\x82\x03\x00\x82\x07\x00\x46\x0e\x00\x7c'\
b'\x1c\x00\x38\x38\x00\x00\x30\x00\x00\x20\x00\x00\x00\x00\x0b\x00'\
b'\x00\x04\x00\x1c\x38\x00\x3e\x10\x00\x73\x20\x00\x61\x20\x00\xc1'\
b'\x20\x00\xc1\x20\x00\x82\x31\x00\x87\x1f\x00\x08\x0f\x00\x00\x00'\
b'\x00\x0c\x00\x0e\x00\x00\x06\x00\x00\x02\x00\x00\x02\x00\x00\x02'\
b'\x20\x00\xfe\x3f\x00\xfe\x3f\x00\x02\x20\x00\x02\x00\x00\x02\x00'\
b'\x00\x06\x00\x00\x0e\x00\x00\x0e\x00\x02\x00\x00\xfe\x0f\x00\xfe'\
b'\x1f\x00\x02\x30\x00\x00\x20\x00\x00\x20\x00\x00\x20\x00\x00\x20'\
b'\x00\x00\x20\x00\x02\x10\x00\xfe\x0f\x00\x02\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x0e\x00\x02\x00\x00\x06\x00\x00\x0e\x00\x00\x3e\x00'\
b'\x00\xf2\x00\x00\xc2\x03\x00\x00\x0f\x00\x00\x3c\x00\x00\x0e\x00'\
b'\x80\x01\x00\x62\x00\x00\x1e\x00\x00\x06\x00\x00\x02\x00\x00\x13'\
b'\x00\x02\x00\x00\x06\x00\x00\x1e\x00\x00\x7e\x00\x00\xe2\x03\x00'\
b'\x80\x0f\x00\x02\x3e\x00\x02\x06\x00\xce\x01\x00\x3e\x00\x00\xf2'\
b'\x01\x00\xc2\x07\x00\x00\x3f\x00\x00\x1c\x00\x80\x03\x00\x62\x00'\
b'\x00\x1e\x00\x00\x06\x00\x00\x02\x00\x00\x0e\x00\x02\x20\x00\x02'\
b'\x20\x00\x06\x30\x00\x0e\x28\x00\x1e\x26\x00\x72\x03\x00\xe0\x01'\
b'\x00\xc0\x01\x00\xa0\x27\x00\x12\x2e\x00\x0a\x3c\x00\x06\x38\x00'\
b'\x02\x30\x00\x02\x20\x00\x0e\x00\x02\x00\x00\x06\x00\x00\x0e\x00'\
b'\x00\x1e\x00\x00\x3a\x20\x00\xf2\x20\x00\xc0\x3f\x00\x80\x3f\x00'\
b'\x40\x20\x00\x22\x20\x00\x1a\x00\x00\x06\x00\x00\x02\x00\x00\x02'\
b'\x00\x00\x0c\x00\x00\x20\x00\x0c\x30\x00\x06\x3c\x00\x02\x3e\x00'\
b'\x02\x2f\x00\xc2\x23\x00\xe2\x20\x00\x72\x20\x00\x1e\x20\x00\x0e'\
b'\x20\x00\x02\x30\x00\x00\x0c\x00\x07\x00\xfe\xff\x01\xfe\xff\x01'\
b'\x02\x00\x01\x02\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06'\
b'\x00\x03\x00\x00\x1e\x00\x00\xf0\x00\x00\x80\x07\x00\x00\x3c\x00'\
b'\x00\x20\x00\x07\x00\x02\x00\x01\x02\x00\x01\xfe\xff\x01\xfe\xff'\
b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\xc0'\
b'\x00\x00\x70\x00\x00\x1c\x00\x00\x06\x00\x00\x0e\x00\x00\x38\x00'\
b'\x00\xe0\x00\x00\x80\x00\x00\x0a\x00\x00\x40\x00\x00\x40\x00\x00'\
b'\x40\x00\x00\x40\x00\x00\x40\x00\x00\x40\x00\x00\x40\x00\x00\x40'\
b'\x00\x00\x40\x00\x00\x40\x00\x05\x00\x02\x00\x00\x04\x00\x00\x08'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\xc0\x18\x00\xe0\x3c\x00'\
b'\x20\x22\x00\x20\x22\x00\xe0\x3f\x00\xc0\x3f\x00\x00\x20\x00\x00'\
b'\x00\x00\x00\x00\x00\x0a\x00\x02\x00\x00\xfe\x1f\x00\xff\x3f\x00'\
b'\x40\x20\x00\x20\x20\x00\x20\x20\x00\x60\x10\x00\xc0\x1f\x00\x80'\
b'\x07\x00\x00\x00\x00\x09\x00\x00\x0f\x00\xc0\x1f\x00\x60\x30\x00'\
b'\x20\x20\x00\x20\x20\x00\x60\x20\x00\x40\x10\x00\x00\x00\x00\x00'\
b'\x00\x00\x0a\x00\x00\x0f\x00\xc0\x1f\x00\x60\x30\x00\x20\x20\x00'\
b'\x20\x20\x00\x42\x20\x00\xfe\x3f\x00\xff\x3f\x00\x00\x00\x00\x00'\
b'\x00\x00\x09\x00\x80\x0f\x00\xc0\x1f\x00\xc0\x38\x00\xa0\x30\x00'\
b'\xa0\x20\x00\xa0\x20\x00\xe0\x20\x00\xc0\x18\x00\x00\x00\x00\x08'\
b'\x00\x00\x20\x00\x20\x20\x00\xfc\x3f\x00\xfe\x3f\x00\x21\x20\x00'\
b'\x21\x00\x00\x03\x00\x00\x03\x00\x00\x0a\x00\x00\x80\x03\x80\xf3'\
b'\x07\xc0\x2b\x06\x20\x26\x04\x20\x24\x04\x60\x24\x04\xc0\x27\x04'\
b'\xc0\x23\x02\x40\xc0\x01\x40\x00\x00\x0a\x00\x02\x20\x00\xfe\x3f'\
b'\x00\xff\x3f\x00\x40\x20\x00\x20\x00\x00\x20\x00\x00\x20\x20\x00'\
b'\xe0\x3f\x00\xc0\x3f\x00\x00\x20\x00\x06\x00\x00\x20\x00\x40\x20'\
b'\x00\xc3\x3f\x00\xe3\x3f\x00\x00\x20\x00\x00\x00\x00\x07\x00\x00'\
b'\x00\x04\x00\x00\x04\x00\x00\x04\x40\x00\x04\xe3\xff\x03\xe3\xff'\
b'\x01\x00\x00\x00\x0a\x00\x02\x20\x00\xfe\x3f\x00\xff\x3f\x00\x00'\
b'\x23\x00\x00\x07\x00\xa0\x2c\x00\x60\x38\x00\x20\x30\x00\x20\x20'\
b'\x00\x00\x20\x00\x05\x00\x00\x20\x00\x02\x20\x00\xfe\x3f\x00\xff'\
b'\x3f\x00\x00\x20\x00\x10\x00\x20\x20\x00\xe0\x3f\x00\xe0\x3f\x00'\
b'\x40\x20\x00\x20\x00\x00\x20\x20\x00\xe0\x3f\x00\xc0\x3f\x00\x40'\
b'\x20\x00\x20\x00\x00\x20\x20\x00\xe0\x3f\x00\xc0\x3f\x00\x00\x20'\
b'\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x20\x20\x00\xe0\x3f\x00\xe0'\
b'\x3f\x00\x40\x20\x00\x20\x00\x00\x20\x00\x00\x20\x20\x00\xe0\x3f'\
b'\x00\xc0\x3f\x00\x00\x20\x00\x0a\x00\x80\x0f\x00\xc0\x1f\x00\x60'\
b'\x38\x00\x20\x20\x00\x20\x20\x00\x20\x20\x00\xe0\x30\x00\xc0\x1f'\
b'\x00\x80\x0f\x00\x00\x00\x00\x0a\x00\x20\x00\x04\xe0\xff\x07\xe0'\
b'\xff\x07\x40\x20\x04\x20\x20\x00\x20\x20\x00\x60\x30\x00\xc0\x1f'\
b'\x00\x80\x07\x00\x00\x00\x00\x0a\x00\x00\x0f\x00\xc0\x1f\x00\x60'\
b'\x30\x00\x20\x20\x00\x20\x20\x00\x20\x20\x04\xc0\xff\x07\xe0\xff'\
b'\x07\x00\x00\x04\x00\x00\x00\x07\x00\x00\x20\x00\xe0\x3f\x00\xe0'\
b'\x3f\x00\x40\x20\x00\x20\x00\x00\x20\x00\x00\x00\x00\x00\x07\x00'\
b'\xc0\x39\x00\x20\x13\x00\x20\x22\x00\x20\x26\x00\x40\x3e\x00\xe0'\
b'\x1c\x00\x00\x00\x00\x06\x00\x20\x00\x00\xf0\x1f\x00\xf8\x3f\x00'\
b'\x20\x20\x00\x00\x20\x00\x00\x00\x00\x0a\x00\x20\x00\x00\xe0\x1f'\
b'\x00\xe0\x3f\x00\x00\x20\x00\x00\x20\x00\x00\x20\x00\x20\x10\x00'\
b'\xe0\x3f\x00\xe0\x3f\x00\x00\x20\x00\x09\x00\x20\x00\x00\x60\x00'\
b'\x00\xe0\x01\x00\x20\x07\x00\x00\x3c\x00\x00\x18\x00\x20\x07\x00'\
b'\xe0\x00\x00\x20\x00\x00\x0e\x00\x20\x00\x00\xe0\x00\x00\xe0\x03'\
b'\x00\x20\x0e\x00\x00\x38\x00\x20\x0c\x00\xe0\x02\x00\xe0\x03\x00'\
b'\x20\x0e\x00\x00\x38\x00\x00\x0c\x00\xa0\x03\x00\x60\x00\x00\x20'\
b'\x00\x00\x0a\x00\x20\x20\x00\x20\x30\x00\xe0\x28\x00\xe0\x05\x00'\
b'\x00\x03\x00\xa0\x2e\x00\x60\x3c\x00\x20\x30\x00\x20\x20\x00\x00'\
b'\x00\x00\x09\x00\x20\x00\x00\xe0\x00\x06\xe0\x03\x04\x20\x0f\x06'\
b'\x00\xbc\x01\x00\x70\x00\x00\x0e\x00\xa0\x01\x00\x60\x00\x00\x08'\
b'\x00\x60\x30\x00\x20\x38\x00\x20\x2c\x00\x20\x27\x00\xa0\x21\x00'\
b'\xe0\x20\x00\x60\x30\x00\x00\x18\x00\x0a\x00\x00\x00\x00\x00\x03'\
b'\x00\xfe\xff\x01\xff\xfc\x03\x01\x00\x02\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\xff\x3f\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x01\x00\x02\xff\xfc\x03\xfe'\
b'\xff\x01\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x03\x00\x00'\
b'\x01\x00\x00\x01\x00\x00\x01\x00\x00\x02\x00\x00\x02\x00\x00\x02'\
b'\x00\x00\x03\x00\x00\x00\x00'
_index =\
b'\x00\x00\x11\x00\x28\x00\x42\x00\x62\x00\x82\x00\xb7\x00\xe9\x00'\
b'\xf7\x00\x0e\x01\x25\x01\x45\x01\x68\x01\x79\x01\x90\x01\xa1\x01'\
b'\xb5\x01\xd5\x01\xf5\x01\x15\x02\x35\x02\x55\x02\x75\x02\x95\x02'\
b'\xb5\x02\xd5\x02\xf5\x02\x06\x03\x17\x03\x3a\x03\x5d\x03\x80\x03'\
b'\x9d\x03\xd2\x03\xfe\x03\x27\x04\x50\x04\x7c\x04\xa2\x04\xc5\x04'\
b'\xf1\x04\x1d\x05\x34\x05\x4e\x05\x7a\x05\xa0\x05\xd8\x05\x07\x06'\
b'\x33\x06\x59\x06\x85\x06\xae\x06\xd1\x06\xf7\x06\x23\x07\x4f\x07'\
b'\x8a\x07\xb6\x07\xe2\x07\x08\x08\x1f\x08\x33\x08\x4a\x08\x67\x08'\
b'\x87\x08\x98\x08\xb5\x08\xd5\x08\xf2\x08\x12\x09\x2f\x09\x49\x09'\
b'\x69\x09\x89\x09\x9d\x09\xb4\x09\xd4\x09\xe5\x09\x17\x0a\x37\x0a'\
b'\x57\x0a\x77\x0a\x97\x0a\xae\x0a\xc5\x0a\xd9\x0a\xf9\x0a\x16\x0b'\
b'\x42\x0b\x62\x0b\x7f\x0b\x99\x0b\xb9\x0b\xc7\x0b\xe7\x0b\x07\x0c'\
def _chr_addr(ordch):
offset = 2 * (ordch - 32)
return int.from_bytes(_index[offset:offset + 2], 'little')
def get_ch(ch):
ordch = ord(ch)
ordch = ordch if ordch >= 32 and ordch <= 126 else ord('?')
offset = _chr_addr(ordch)
width = int.from_bytes(_font[offset:offset + 2], 'little')
next_offs = _chr_addr(ordch +1)
return memoryview(_font[offset + 2:next_offs]), 19, width

Wyświetl plik

@ -0,0 +1,156 @@
# Code generated by font-to-py.py.
# Font: Inconsolata.otf
version = '0.1'
def height():
return 14
def max_width():
return 8
def hmap():
return False
def reverse():
return False
def monospaced():
return True
_font =\
b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x08\x00\xff\x06\x3f\x06\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x08\x00\x0f\x00\x02\x00\x00\x00\x0f\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x08\x00\x90\x00\x90\x04\xfc\x07\x8e\x00'\
b'\x88\x07\xfe\x03\x8a\x00\x08\x00\x08\x00\x18\x03\x34\x06\x26\x04'\
b'\xff\x0f\x46\x06\xcc\x03\x00\x00\x00\x00\x08\x00\x0c\x00\x1e\x06'\
b'\x92\x03\xce\x00\x30\x03\x8c\x04\x86\x04\x00\x03\x08\x00\x00\x01'\
b'\xcc\x07\x7e\x04\x62\x04\xd2\x04\x8c\x03\xc0\x07\x80\x04\x08\x00'\
b'\x08\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x08\x00\xf0\x01\xbc\x07\x06\x0c\x02\x10\x01\x30\x00\x00\x00\x00'\
b'\x00\x00\x08\x00\x03\x30\x02\x10\x06\x0c\x38\x07\xf0\x01\x00\x00'\
b'\x00\x00\x00\x00\x08\x00\x00\x00\x30\x01\xa0\x01\x7c\x00\xfc\x00'\
b'\xa0\x01\x30\x01\x00\x00\x08\x00\x20\x00\x20\x00\xfc\x01\xfc\x01'\
b'\x20\x00\x20\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x16\x00\x0e'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x20\x00\x20\x00'\
b'\x20\x00\x20\x00\x20\x00\x20\x00\x00\x00\x00\x00\x08\x00\x00\x06'\
b'\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00'\
b'\x00\x04\x00\x07\xe0\x01\x38\x00\x0e\x00\x03\x00\x00\x00\x00\x00'\
b'\x08\x00\xf8\x01\x86\x07\xc2\x04\x32\x04\x1e\x06\xf8\x03\x00\x00'\
b'\x00\x00\x08\x00\x04\x00\x04\x00\x02\x00\xfe\x07\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x08\x00\x04\x06\x06\x07\x82\x05\xc2\x04\x66\x04'\
b'\x1c\x04\x00\x00\x00\x00\x08\x00\x00\x02\x02\x04\x22\x04\x22\x04'\
b'\x5e\x06\x8c\x03\x00\x00\x00\x00\x08\x00\xc0\x00\xb0\x00\x98\x00'\
b'\x86\x00\xfe\x07\x80\x00\x00\x00\x00\x00\x08\x00\x3c\x02\x3e\x06'\
b'\x32\x04\x32\x04\x22\x06\xe2\x03\x00\x00\x00\x00\x08\x00\xf8\x01'\
b'\x6c\x07\x32\x04\x32\x04\x22\x06\xc2\x03\x00\x00\x00\x00\x08\x00'\
b'\x02\x00\x02\x06\x82\x07\xf2\x00\x1e\x00\x06\x00\x00\x00\x00\x00'\
b'\x08\x00\x8c\x03\x5e\x06\x22\x04\x22\x04\x5e\x06\xcc\x03\x00\x00'\
b'\x00\x00\x08\x00\x3c\x00\x66\x04\x42\x04\x42\x04\x66\x03\xfc\x01'\
b'\x00\x00\x00\x00\x08\x00\x30\x06\x30\x06\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x30\x16\x30\x0e\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x20\x00\x60\x00\x70\x00'\
b'\x90\x00\x98\x01\x08\x01\x0c\x03\x00\x02\x08\x00\x90\x00\x90\x00'\
b'\x90\x00\x90\x00\x90\x00\x90\x00\x00\x00\x00\x00\x08\x00\x00\x02'\
b'\x0c\x03\x08\x01\x98\x01\x90\x00\x70\x00\x60\x00\x20\x00\x08\x00'\
b'\x06\x00\x03\x00\x81\x06\xe1\x06\x3f\x00\x1e\x00\x00\x00\x00\x00'\
b'\x08\x00\x70\x00\xfc\x03\x06\x06\xf2\x04\x92\x04\x92\x04\xfc\x06'\
b'\xf8\x00\x08\x00\x00\x04\x80\x07\xf0\x00\x9e\x00\xbc\x00\xe0\x00'\
b'\x80\x07\x00\x04\x08\x00\xfe\x07\x22\x04\x22\x04\x22\x04\x76\x06'\
b'\xdc\x03\x00\x00\x00\x00\x08\x00\xfc\x03\x06\x06\x02\x04\x02\x04'\
b'\x02\x04\x06\x02\x00\x00\x00\x00\x08\x00\xfe\x07\x02\x04\x02\x04'\
b'\x02\x04\x06\x02\xfc\x01\x00\x00\x00\x00\x08\x00\xfe\x07\x22\x04'\
b'\x22\x04\x22\x04\x22\x04\x02\x04\x00\x00\x00\x00\x08\x00\xfe\x07'\
b'\xfe\x07\x22\x00\x22\x00\x22\x00\x02\x00\x00\x00\x00\x00\x08\x00'\
b'\x60\x00\xfc\x03\x06\x06\x02\x04\x42\x04\x42\x04\xc6\x07\xc0\x03'\
b'\x08\x00\xfe\x07\x20\x00\x20\x00\x20\x00\x20\x00\xfe\x07\x00\x00'\
b'\x00\x00\x08\x00\x02\x04\x02\x04\xfe\x07\xfe\x07\x02\x04\x00\x04'\
b'\x00\x00\x00\x00\x08\x00\x00\x06\x00\x04\x02\x04\x02\x06\xfe\x03'\
b'\x02\x00\x00\x00\x00\x00\x08\x00\xfe\x07\x20\x00\x78\x00\xcc\x01'\
b'\x06\x03\x02\x06\x00\x00\x00\x00\x08\x00\xfe\x07\x00\x04\x00\x04'\
b'\x00\x04\x00\x04\x00\x04\x00\x00\x00\x00\x08\x00\xfe\x07\x18\x00'\
b'\x60\x00\x60\x00\x18\x00\xfe\x07\xfe\x07\x00\x00\x08\x00\xfe\x07'\
b'\x0c\x00\x30\x00\xe0\x00\x80\x03\xfe\x07\x00\x00\x00\x00\x08\x00'\
b'\xf0\x00\xfc\x03\x06\x06\x02\x04\x02\x04\x06\x06\xfc\x03\xf0\x00'\
b'\x08\x00\xfe\x07\x62\x00\x62\x00\x62\x00\x26\x00\x3c\x00\x00\x00'\
b'\x00\x00\x08\x00\xf0\x00\xfc\x03\x06\x06\x02\x0c\x02\x1c\x06\x16'\
b'\xfc\x13\xf0\x00\x08\x00\xfe\x07\x62\x00\x62\x00\xe2\x00\xa6\x03'\
b'\x3c\x06\x00\x00\x00\x00\x08\x00\x1c\x02\x36\x04\x22\x04\x62\x04'\
b'\x42\x06\xc4\x03\x00\x00\x00\x00\x08\x00\x02\x00\x02\x00\x02\x00'\
b'\xfe\x07\xfe\x07\x02\x00\x02\x00\x02\x00\x08\x00\xfe\x03\x00\x06'\
b'\x00\x04\x00\x04\x00\x06\xfe\x03\x00\x00\x00\x00\x08\x00\x02\x00'\
b'\x1e\x00\xf8\x00\xc0\x07\x80\x07\xf0\x00\x1e\x00\x02\x00\x08\x00'\
b'\x06\x00\xfe\x03\x80\x07\x78\x00\x7c\x00\xc0\x07\xf8\x03\x0e\x00'\
b'\x08\x00\x00\x00\x06\x06\x8c\x03\xf0\x00\xf0\x00\x8c\x03\x02\x06'\
b'\x00\x00\x08\x00\x02\x00\x06\x00\x1c\x00\xf0\x07\xe0\x07\x38\x00'\
b'\x06\x00\x00\x00\x08\x00\x02\x06\x82\x07\xe2\x04\x32\x04\x1e\x04'\
b'\x06\x04\x00\x04\x00\x00\x08\x00\xff\x0f\x01\x08\x01\x08\x01\x08'\
b'\x01\x08\x00\x00\x00\x00\x00\x00\x08\x00\x03\x00\x0e\x00\x38\x00'\
b'\xe0\x01\x00\x07\x00\x04\x00\x00\x00\x00\x08\x00\x01\x08\x01\x08'\
b'\x01\x08\x01\x08\xff\x0f\x00\x00\x00\x00\x00\x00\x08\x00\x20\x00'\
b'\x18\x00\x0e\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x08\x00'\
b'\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08'\
b'\x08\x00\x03\x00\x0e\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
b'\x00\x00\x08\x00\x90\x07\x90\x04\x98\x04\xd8\x04\xd0\x06\xf0\x07'\
b'\x00\x00\x00\x00\x08\x00\xff\x07\x10\x06\x18\x04\x18\x04\x10\x06'\
b'\xf0\x03\x00\x00\x00\x00\x08\x00\xe0\x03\x30\x06\x18\x04\x18\x04'\
b'\x18\x04\x30\x06\x00\x00\x00\x00\x08\x00\xf0\x03\x10\x06\x08\x04'\
b'\x18\x04\x30\x02\xff\x07\x00\x00\x00\x00\x08\x00\xe0\x03\xd0\x06'\
b'\xc8\x04\xc8\x04\xd0\x04\xf0\x02\x00\x00\x00\x00\x08\x00\x10\x00'\
b'\xfc\x07\xfe\x07\x11\x00\x11\x00\x03\x00\x02\x00\x00\x00\x08\x00'\
b'\x00\x00\xf0\x1f\x98\x37\x88\x27\x98\x26\xf0\x34\x08\x1c\x08\x00'\
b'\x08\x00\xff\x07\x30\x00\x10\x00\x18\x00\x18\x00\xf0\x07\x00\x00'\
b'\x00\x00\x08\x00\x00\x04\x18\x04\xfb\x07\xfb\x07\x00\x04\x00\x00'\
b'\x00\x00\x00\x00\x08\x00\x00\x18\x18\x30\x18\x20\x1a\x18\xfb\x1f'\
b'\x00\x00\x00\x00\x00\x00\x08\x00\xff\x07\x80\x00\xc0\x00\xa0\x01'\
b'\x10\x03\x08\x06\x00\x00\x00\x00\x08\x00\x01\x04\x01\x04\xff\x07'\
b'\xff\x07\x00\x04\x00\x04\x00\x00\x00\x00\x08\x00\xf8\x07\xf8\x07'\
b'\x08\x00\xf8\x07\xf0\x07\x08\x00\xf8\x07\xf0\x07\x08\x00\xf8\x07'\
b'\x30\x00\x10\x00\x18\x00\x18\x00\xf0\x07\x00\x00\x00\x00\x08\x00'\
b'\xe0\x03\x10\x06\x18\x04\x18\x04\x10\x06\xf0\x03\x00\x00\x00\x00'\
b'\x08\x00\xf8\x3f\x10\x06\x18\x04\x18\x04\x10\x06\xf0\x03\x80\x00'\
b'\x00\x00\x08\x00\xf0\x03\x10\x06\x08\x04\x18\x04\x10\x02\xf8\x3f'\
b'\x00\x00\x00\x00\x08\x00\xf8\x07\xf8\x07\x10\x00\x18\x00\x18\x00'\
b'\x10\x00\x00\x00\x00\x00\x08\x00\x20\x02\x70\x04\xc8\x04\xc8\x04'\
b'\x98\x04\x90\x03\x00\x00\x00\x00\x08\x00\x18\x00\x18\x00\xfe\x07'\
b'\x18\x04\x18\x04\x18\x06\x00\x00\x00\x00\x08\x00\xf8\x03\x00\x06'\
b'\x00\x04\x00\x04\x00\x02\xf8\x07\x00\x00\x00\x00\x08\x00\x08\x00'\
b'\x38\x00\xe0\x01\x80\x07\x00\x07\xc0\x01\x38\x00\x00\x00\x08\x00'\
b'\x38\x00\xf8\x03\x00\x06\xf0\x01\xf0\x00\x80\x07\xf8\x07\x38\x00'\
b'\x08\x00\x18\x04\x30\x03\xe0\x01\xe0\x01\x30\x03\x18\x04\x00\x00'\
b'\x00\x00\x08\x00\x00\x10\x38\x20\xe0\x30\x80\x1f\x00\x0f\xc0\x01'\
b'\x78\x00\x08\x00\x08\x00\x18\x06\x18\x07\x98\x05\x78\x04\x38\x04'\
b'\x18\x04\x00\x00\x00\x00\x08\x00\x40\x00\xf8\x0f\x3e\x1f\x02\x10'\
b'\x02\x30\x02\x30\x00\x00\x00\x00\x08\x00\xff\x1f\xff\x1f\x00\x00'\
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x02\x30\x02\x30'\
b'\x02\x10\x3e\x1f\xf8\x0f\x40\x00\x00\x00\x00\x00\x08\x00\x00\x00'\
b'\x30\x00\x18\x00\x18\x00\x30\x00\x20\x00\x10\x00\x10\x00'
_index =\
b'\x00\x00\x12\x00\x24\x00\x36\x00\x48\x00\x5a\x00\x6c\x00\x7e\x00'\
b'\x90\x00\xa2\x00\xb4\x00\xc6\x00\xd8\x00\xea\x00\xfc\x00\x0e\x01'\
b'\x20\x01\x32\x01\x44\x01\x56\x01\x68\x01\x7a\x01\x8c\x01\x9e\x01'\
b'\xb0\x01\xc2\x01\xd4\x01\xe6\x01\xf8\x01\x0a\x02\x1c\x02\x2e\x02'\
b'\x40\x02\x52\x02\x64\x02\x76\x02\x88\x02\x9a\x02\xac\x02\xbe\x02'\
b'\xd0\x02\xe2\x02\xf4\x02\x06\x03\x18\x03\x2a\x03\x3c\x03\x4e\x03'\
b'\x60\x03\x72\x03\x84\x03\x96\x03\xa8\x03\xba\x03\xcc\x03\xde\x03'\
b'\xf0\x03\x02\x04\x14\x04\x26\x04\x38\x04\x4a\x04\x5c\x04\x6e\x04'\
b'\x80\x04\x92\x04\xa4\x04\xb6\x04\xc8\x04\xda\x04\xec\x04\xfe\x04'\
b'\x10\x05\x22\x05\x34\x05\x46\x05\x58\x05\x6a\x05\x7c\x05\x8e\x05'\
b'\xa0\x05\xb2\x05\xc4\x05\xd6\x05\xe8\x05\xfa\x05\x0c\x06\x1e\x06'\
b'\x30\x06\x42\x06\x54\x06\x66\x06\x78\x06\x8a\x06\x9c\x06\xae\x06'\
def _chr_addr(ordch):
offset = 2 * (ordch - 32)
return int.from_bytes(_index[offset:offset + 2], 'little')
def get_ch(ch):
ordch = ord(ch)
ordch = ordch if ordch >= 32 and ordch <= 126 else ord('?')
offset = _chr_addr(ordch)
width = int.from_bytes(_font[offset:offset + 2], 'little')
next_offs = _chr_addr(ordch +1)
return memoryview(_font[offset + 2:next_offs]), 14, width

161
SSD1306/ssd1306.py 100644
Wyświetl plik

@ -0,0 +1,161 @@
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
from micropython import const
import time
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xa4)
SET_NORM_INV = const(0xa6)
SET_DISP = const(0xae)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xa0)
SET_MUX_RATIO = const(0xa8)
SET_COM_OUT_DIR = const(0xc0)
SET_DISP_OFFSET = const(0xd3)
SET_COM_PIN_CFG = const(0xda)
SET_DISP_CLK_DIV = const(0xd5)
SET_PRECHARGE = const(0xd9)
SET_VCOM_DESEL = const(0xdb)
SET_CHARGE_PUMP = const(0x8d)
class SSD1306:
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
self.buffer = bytearray(self.pages * self.width)
self.framebuf = framebuf.FrameBuffer1(self.buffer, self.width, self.height)
self.poweron()
self.init_display()
def init_display(self):
for cmd in (
SET_DISP | 0x00, # off
# address setting
SET_MEM_ADDR, 0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE | 0x00,
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO, self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET, 0x00,
SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV, 0x80,
SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
SET_VCOM_DESEL, 0x30, # 0.83*Vcc
# display
SET_CONTRAST, 0xff, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
# charge pump
SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP | 0x00)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width == 64:
# displays with width of 64 pixels are shifted by 32
x0 += 32
x1 += 32
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
def fill(self, col):
self.framebuf.fill(col)
def pixel(self, x, y, col):
self.framebuf.pixel(x, y, col)
def scroll(self, dx, dy):
self.framebuf.scroll(dx, dy)
def text(self, string, x, y, col=1):
self.framebuf.text(string, x, y, col)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.temp[0] = self.addr << 1
self.temp[1] = 0x40 # Co=0, D/C#=1
self.i2c.start()
self.i2c.write(self.temp)
self.i2c.write(buf)
self.i2c.stop()
def poweron(self):
pass
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.low()
self.cs.low()
self.spi.write(bytearray([cmd]))
self.cs.high()
def write_data(self, buf):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs.high()
self.dc.high()
self.cs.low()
self.spi.write(buf)
self.cs.high()
def poweron(self):
self.res.high()
time.sleep_ms(1)
self.res.low()
time.sleep_ms(10)
self.res.high()

Wyświetl plik

@ -0,0 +1,122 @@
# ssd1306_drv.py An implementation of a Display class for SSD1306 based displays
# V0.1 Peter Hinch Nov 2016
# https://learn.adafruit.com/monochrome-oled-breakouts/wiring-128x32-spi-oled-display
# https://www.proto-pic.co.uk/monochrome-128x32-oled-graphic-display.html
# Version supports vertical and "horizontal" modes.
# 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.
# SSD1306 classes to fix the official one whose scroll method is broken
# This also demonstrates a way to do scrolling for devices with true vertical
# mapping (the official driver sets the device into its "horizontal" mode).
# This is a hybrid mode where bytes are aligned vertically but arranged
# horizontally
import ssd1306
class SSD1306(object):
def __init__(self, device):
self.width = device.width # In pixels
self.height = device.height
self.bpc = (self.height + 7) >> 3
self.device = device
self.vmap = False # Currently the official driver uses "horizontal"
@property
def buffer(self): # property emulates underlying device
return self.device.buffer
def show(self):
self.device.show()
# Return map-independent offset into buffer
def _offset(self, x, y):
if self.vmap:
return y + x * self.bpc
else:
return y * self.width + x
def scroll(self, x, y):
dy = abs(y)
if dy:
self._scrolly(dy, y > 0)
dx = abs(x)
if dx:
self._scrollx(dx, x > 0)
def _scrolly(self, ystep, down):
buf = self.device.buffer
bpc = self.bpc
ystep_bytes = (ystep >> 3) + 1
ystep_bits = ystep & 7
if down:
for x in range(self.width):
for ydest in range(bpc - 1, -1, -1):
ysource = ydest - ystep_bytes
data = 0
if ysource + 1 >= 0:
data = buf[self._offset(x, ysource + 1)] << ystep_bits
if ysource >= 0:
data |= buf[self._offset(x, ysource)] >> 8 - ystep_bits
buf[self._offset(x, ydest)] = data
else:
for x in range(self.width):
for ydest in range(bpc):
ysource = ydest + ystep_bytes
data = 0
if ysource < bpc:
data = buf[self._offset(x, ysource)] << (8-ystep_bits)
if ysource - 1 < bpc:
data |= buf[self._offset(x, ysource - 1)] >> ystep_bits
buf[self._offset(x, ydest)] = data
def _scrollx(self, xstep, right): # scroll x
buf = self.device.buffer
bpc = self.bpc
for y in range(bpc):
if right: # Scroll right
for xdest in range(self.width - 1, -1, -1):
data = 0
xsource = xdest - xstep
if xsource >= 0:
data = buf[self._offset(xsource, y)]
buf[self._offset(xdest, y)] = data
else:
for xdest in range(0, self.width):
data = 0
xsource = xdest + xstep
if xsource < self.width:
data = buf[self._offset(xsource, y)]
buf[self._offset(xdest, y)] = data
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
device = ssd1306.SSD1306_I2C(width, height, i2c, addr, external_vcc)
super().__init__(device)
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
device = ssd1306.SSD1306_SPI(width, height, spi, dc, res, cs, external_vcc)
super().__init__(device)

Wyświetl plik

@ -0,0 +1,76 @@
# ssd1306_test.py Demo pogram for rendering arbitrary fonts to an SSD1306 OLED display
# 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.
# https://learn.adafruit.com/monochrome-oled-breakouts/wiring-128x32-spi-oled-display
# https://www.proto-pic.co.uk/monochrome-128x32-oled-graphic-display.html
import machine
from ssd1306_drv import SSD1306_SPI, SSD1306_I2C
from writer import Writer
# Fonts
import freesans20
#import freeserif19
#import inconsolata16
WIDTH = const(128)
SPI = False
if SPI:
# Pyb SSD
# 3v3 Vin
# Gnd Gnd
# X1 DC
# X2 CS
# X3 Rst
# X6 CLK
# X8 DATA
HEIGHT = 32
pdc = machine.Pin('X1', machine.Pin.OUT_PP)
pcs = machine.Pin('X2', machine.Pin.OUT_PP)
prst = machine.Pin('X3', machine.Pin.OUT_PP)
spi = machine.SPI(1)
ssd = SSD1306_SPI(WIDTH, HEIGHT, spi, pdc, prst, pcs)
else: # I2C
# Pyb SSD
# 3v3 Vin
# Gnd Gnd
# Y9 CLK
# Y10 DATA
HEIGHT = 64
pscl = machine.Pin('Y9', machine.Pin.OUT_PP)
psda = machine.Pin('Y10', machine.Pin.OUT_PP)
i2c = machine.I2C(scl=pscl, sda=psda)
ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c)
#wri = Writer(ssd, freeserif19)
wri2 = Writer(ssd, freesans20)
Writer.set_clip(True, True)
wri2.printstring('Tuesday\n')
wri2.printstring('8 Nov 2016\n')
wri2.printstring('10.30am')
ssd.show()

123
SSD1306/writer.py 100644
Wyświetl plik

@ -0,0 +1,123 @@
# writer.py Implements the Writer class.
# V0.1 Peter Hinch Nov 2016
# 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.
# A Writer supports rendering text to a Display instance in a given font.
# Currently supports vertical mapping and the SSD1306 "pseudo-horizontal" map
# only
# Multiple Writer instances may be created, each rendering a font to the
# same Display object.
VERT = 0
HORIZ = 1
WEIRD = 2
class Writer(object):
text_row = 0 # attributes common to all Writer instances
text_col = 0
row_clip = False # Clip or scroll when screen full
col_clip = False # Clip or new line when row is full
bmap = WEIRD # SSD1306 pseudo-horizontal
@classmethod
def set_textpos(cls, row, col):
cls.text_row = row
cls.text_col = col
@classmethod
def set_clip(cls, row_clip, col_clip):
cls.row_clip = row_clip
cls.col_clip = col_clip
@classmethod
def mapping(cls, bmap):
if bmap in (VERT, HORIZ):
cls.bmap = bmap
else:
raise ValueError('Unsupported mapping')
def __init__(self, device, font):
super().__init__()
self.device = device
self.font = font
if font.hmap():
raise OSError('Font must be vertically mapped')
self.screenwidth = device.width # In pixels
self.screenheight = device.height
div, mod = divmod(device.height, 8)
self.bytes_per_col = div + 1 if mod else div
def _newline(self):
height = self.font.height()
Writer.text_row += height
Writer.text_col = 0
margin = self.screenheight - (Writer.text_row + height)
if margin < 0:
if not Writer.row_clip:
self.device.scroll(0, margin)
Writer.text_row += margin
def printstring(self, string):
for char in string:
self._printchar(char)
def _printchar(self, char):
bmap = Writer.bmap # Buffer mapping
if char == '\n':
self._newline()
return
fbuff = self.device.buffer
glyph, char_height, char_width = self.font.get_ch(char)
if Writer.text_row+char_height > self.screenheight and Writer.row_clip:
return
if Writer.text_col + char_width > self.screenwidth:
if Writer.col_clip:
return
else:
self._newline()
div, mod = divmod(char_height, 8)
gbytes = div + 1 if mod else div # No. of bytes per column of glyph
start_row, align = divmod(Writer.text_row, 8)
for scol in range(0, char_width): # Source column
dcol = scol + Writer.text_col # Destination column
dest_row_byte = start_row
for gbyte in range(gbytes): # Each glyph byte in column
if bmap == VERT:
dest = dcol * self.bytes_per_col + dest_row_byte
elif bmap == WEIRD:
dest = dcol + dest_row_byte * self.screenwidth
source = scol * gbytes + gbyte
data = fbuff[dest] & (0xff >> (8 - align))
fbuff[dest] = data | glyph[source] << align
if align and (dest_row_byte + 1) < self.bytes_per_col:
if bmap == VERT:
dest += 1
elif bmap == WEIRD:
dest += self.screenwidth
data = fbuff[dest] & (0xff << align)
fbuff[dest] = data | glyph[source] >> (8 - align)
dest_row_byte += 1
if dest_row_byte >= self.bytes_per_col:
break
Writer.text_col += char_width