A tiny new font for the SSD1306 128x64 OLED screen

The default font for the Adafruit graphics library is a 5x7 font, it looks a little something like this:

It's readable, but I thought it'd be interesting to use a more compact font like "Tom Thumb" by Robey Pointer:

The font currently bundled with the library is in a file called glcdfont.c and is defined as a big byte array:

Each line of that array is 5 bytes and represents a simple monochrome bitmap of a single ascii character, with each byte representing a column. For example example the letter "a" is represented by the following line:

0x20, 0x54, 0x54, 0x78, 0x40,

In binary each of these is:

You can almost see the shape if you twist your head 90 degrees to the right, but to make things a little clearer here's what this actually represents:

If we were to use the Tom Thumb font we could save ourselves two bytes per character, since it is a little slimmer, meaning that "a" could be represented by the following three bytes:

0x68, 0x58, 0x70

Or, in binary:

Which looks like this:

Since there's a bit of wasted space at the top (the top two bits won't get used at all) we could technically save ourselves a little more space, but for simplicity's sake I'm going to sacrifice those two bits. Currently the font can be easily retrieved and manipulated as each column fits neatly into a single byte, however we'd introduce a good deal more complexity by squeezing those additional bits - which would mean substantial changes to the driver itself to compute the correct address to read the bitmap from, and shift/mask the necessary bits.

However even with this tradeoff we can still save 2 bytes per character, which is a pretty impressive 512 bytes over the whole ascii space which is pretty substantial.

The main challenge is creating a separate .c file we can swap glcdfont.c out for. I had trouble dealing with the BDF file Robey shared, but since there's a little bitmap representation of the whole ascii space it wasn't too tough recreating the font by hand ... just extremely tedious! I hacked together a simple little app (source is here) using Processing that let me paint each character by clicking boxes and which spat out the hex values when I hit a key. I'd then copy and paste this into the glcdfont.c. As I said, extremely tedious.

Once I'd produce my file it was time to test it - the beauty of having the 3x6 font means that the entire ascii space could be displayed on a 128x64 screen:

It's actually pretty surprising how much text you can fit on screen.

And just a little reminder of how small this screen is, with a €2 coin for scale

You can see the amount of memory saved in the .text section (where program code lives) by examining binaries GCC has produced - exactly 512 bytes.

My fork of the Adafruit gfx library with the Tom Thumb font is at https://github.com/smcl/Adafruit-GFX-Library and is a drop-in replacement for the existing library (replace the entire library, though, since I made some changes in Adafruit_GFX.cpp. You can switch between the fonts by toggling the #if ... #else condition in glcdfont.h below: