Working on the tiny Arduino terminal emulator, I ran into issues with text density. The 128×128 console TFT display with default 6×8 pixel font only gives 21 columns by 16 rows of text. Subpixel rendering increased that 64 columns of text, but it was pretty illegible.
A Hackaday.io commenter named Radomir Dopieralski suggested that I use his 4×6 font instead. Normally, a 4×6 pixel font would still be pretty hard to read, but Radomir’s font is antialiased, and that makes a huge difference in legibility.
With each character being 4 pixels wide, the screen fits 32 of them per line. That is a lot better than before. And, unlike the subpixel solution, there is still room for full colour support.
I had to convert the source font PNG image representation into a packed C array. Each character ended up stored as six bytes: one per row of the 4×6 character box. Inside the byte, each pixel is stored as a 2-bit intensity value. For example, a
! is represented like this:
0x30, 0x30, 0x20, 0x00, 0x30, 0x00
A value of
00110000 in binary. That corresponds to one single center pixel set at full brightness. The
0x20 row is the same but with a lower intensity – that is the antialiased bottom edge of the upper part of the exclamation mark.
Colour Character Display
Character display code was already in an encapsulated routine because of earlier architecture decisions, so it was easy to modify. Making the variable-intensity font pixel values required adding simple linear interpolation to the rendering code: partial-intensity pixels in the letters have to be proportionally mixed with the background colour .
The individual red, green and blue component values of the foreground and background colours are bit-shifted and divided by 3. Then the foreground values are multiplied by the pixel intensity and added to the corresponding background intensity. The results are bit-shifted back into the 16 bit BGR packing that the screen controller uses.
Mistakes were made along the way, but ultimately it worked. I also filled in some missing box drawing characters (ASCII pipes, etc) to make console menus/dialogs show up correctly:
Thanks to Radomir’s font this now looks like a good middle ground between unreadable compressed text and chunky massive letters of the original default 6×8 font.