The first release of the SSD1306 support library py-gaugette used the 5x7 pixel fonts from the Adafruit GFX library. That’s a fine and compact font, but wouldn’t it be nice to have some pretty high-res fonts to take advantage of the memory and resolution we have to work with?
Generating Font Bitmaps
I started with The Dot Factory by Eran Duchan. Its a handy C# (Windows) tool for generating C and C++ bitmap files quickly, and source code is available. I modified it to generate Python code, and to add a kerning table to store the minimum number of pixels the cursor must move between any two characters to avoid collison.
The kerning isn’t completely right yet - I noticed that the underscore character can slip beheath other characters. I’ll need to look at that some more in due time - and I’d also like to replace the C# app for a command-line tool to generate the rasterized image files.
Each font is stored in a module like the following. The size suffix (16 in this case) indicates the character height in pixels. The descriptor table specifies the width of each character and the character’s offset in the bitmap.
Note the font is a module, not a class, because it allows a very concise syntax:
Supporting Horizontal Scrolling
In the process of testing these fonts, I realized I would like to be able to scroll horizontally, and the SSD1306 doesn’t have hardware support for that. Vertical scrolling is accomplished using the
SET_START_LINE command, but the horizontal scrolling commands do not support scrolling through an image that is wider than the display. We need to do it in software.
It turns out that blitting memory from the Pi to the SSD1306 over SPI is pretty fast; fast enough to get a reasonable horizontal scroll effect by blitting complete frames from the Pi’s memory to the SSD1306. There’s just one thing - the default memory mode of the SSD1306 is row-major, and for horizontal scrolling we really want to send a vertical slice of the memory buffer over SPI. To avoid buffer manipulation I switched the Pi-side memory buffer to use column-major order, and use
MEMORY_MODE_VERT on the SSD1306 when blitting.
To illustrate: the memory buffer is stored as a python list of bytes. Consider a virtual buffer that is 256 columns wide and 64 rows high. Using column-major layout we can address the 128 columns starting at column 100 using the python list addressing
Note that using column-major layout we cannot easily blit a horizontal slice of the virtual memory buffer into display ram, so we can’t use the same method for vertical scrolling. Stick with
SET_START_LINE for vertical scrolling. The combination of these methods gives us fast horizontal and vertical scrolling.