This is a small project, primarily written for my pico-based embedded projects, such as my WAV-Player or my E-Reader. Both of these run on a 296x128 E-Paper display so visual clarity and space are at a premium. Because of this, I decided to use the GNU UniFont, as it covered the most characters, but this was not available in a binary format that would reasonably fit onto my pico's flash, and wouldn't incur horrendous runtime costs to decode...
Alas, I decided to write a custom format, which is byte packed and allows O(1) lookups at runtime. It does this with the following structure:
| Bytes | Contents |
|---|---|
| 0x0000 - 0x2FFFF | Lookup Table |
| 0x30000 - EOF | Glyph Data |
| Bytes | Contents |
|---|---|
| 0 - 2 | Internal Pointer from file beginning to Glyph Data |
Each Entry is indexed with the numerical value of it's codepoint
| Byte | Contents |
|---|---|
| 0 | 4 bit unsigned Width, 4 bit unsigned Height * |
| 1 | 4 bit signed OffsetX, 4 bit signed OffsetY |
| 2 | signed byte underline offset |
| 3 | unsigned byte advance offset |
| 4 - (w*h) / 8 | 1bpp Bitmap |
* The Width and Height in the first byte are encoded as such: Take the literal numeric value of the 4 bit and add 1. This allows the range to be 1 - 16, instead of 0 - 15. We Drop the 0, as characters that are 0 pixels wide or high are invisible, as such they shouldn't be in this font
Here the underline offset takes up a whole byte, which is way too much for it's value range, but part of it could be repurposed for other uses
The advance-offset describes the number of pixels the cursor should be incremented to the next character when rendering
The Bitmap is 1bpp, meaning it only supports black and white. It wouldn't be too hard to adapt it to grayscale or similar, but I cannot be bothered, as I only need to render with two colors
Do Note: I make no guarantees for this actually working and my implementation being correct, but in my testing it has worked so far...