Make a digits-only font and save flash
A full ASCII bitmap font is convenient, but most embedded UIs only render a handful of characters — a clock, a temperature reading, a status code. Trimming the character set in /font shrinks the generated table proportionally. This guide walks through the numbers for one real font and size.
1. Pick a font
Open /font and select JetBrains Mono → Bold in Font Family.
2. Set the size to 24×22
In Dimensions, switch to Advanced mode and set Font Height to 24 px (Glyph Width derives to 22 px). With the default Full ASCII character set (95 glyphs), the CHARACTERS panel header shows:
Table: 6840 bytes (All ASCII Glyphs)
95 glyphs × 72 bytes/glyph (24 rows × 3 bytes/row) = 6840 bytes.
3. Switch to "Digits 0-9"
Open CHARACTERS and click the Digits 0-9 preset pill. The
set is now 0123456789 — 10 glyphs, and (because the digits are contiguous
codepoints) no separate index table is needed:
Table: 720 bytes (10 glyphs)
4. Add a space and a colon
For a clock display you'll likely also need a space (for leading-zero blanking) and a colon
(for HH:MM). Type a space followed by 0123456789: into
Custom characters — the chip row shows the space as โฃ,
for 12 glyphs total. Because space (0x20) and colon (0x3A) sit outside the contiguous digit
range, the set is now non-contiguous and the panel adds an index clause:
Table: 864 bytes (12 glyphs) + 12 bytes (index)
5. Download and inspect the header
Click the nav glyph preview to generate the header, then download it. The glyph table now has
12 entries (864 bytes) and a 12-byte {name}_codes[] index table listing the
included codepoints in ascending order:
#define FONT_JETBRAINS_MONO_BOLD_24X22_GLYPH_COUNT 12
#define FONT_JETBRAINS_MONO_BOLD_24X22_TABLE_SIZE 864
#define FONT_JETBRAINS_MONO_BOLD_24X22_HAS_CODE_TABLE 1
const uint8_t font_jetbrains_mono_bold_24x22[] = {
// @0 ' '
...
// @72 '0'
0x00, 0x00, 0x00, // Row 00: | |
0x00, 0x00, 0x00, // Row 01: | |
0x00, 0x00, 0x00, // Row 02: | |
0x00, 0xFC, 0x00, // Row 03: | ###### |
0x01, 0xFE, 0x00, // Row 04: | ######## |
0x03, 0xFF, 0x00, // Row 05: | ########## |
0x03, 0x87, 0x00, // Row 06: | ### ### |
0x07, 0x03, 0x80, // Row 07: | ### ### |
0x07, 0x03, 0x80, // Row 08: | ### ### |
0x07, 0x03, 0x80, // Row 09: | ### ### |
0x07, 0x13, 0x80, // Row 10: | ### # ### |
0x07, 0x33, 0x80, // Row 11: | ### ## ### |
0x07, 0x33, 0x80, // Row 12: | ### ## ### |
0x07, 0x03, 0x80, // Row 13: | ### ### |
0x07, 0x03, 0x80, // Row 14: | ### ### |
0x07, 0x03, 0x80, // Row 15: | ### ### |
0x07, 0x03, 0x80, // Row 16: | ### ### |
0x03, 0x87, 0x00, // Row 17: | ### ### |
0x03, 0xFF, 0x00, // Row 18: | ########## |
0x01, 0xFE, 0x00, // Row 19: | ######## |
0x00, 0x78, 0x00, // Row 20: | #### |
0x00, 0x00, 0x00, // Row 21: | |
0x00, 0x00, 0x00, // Row 22: | |
0x00, 0x00, 0x00, // Row 23: | |
...
// @792 ':'
0x00, 0x00, 0x00, // Row 00: | |
0x00, 0x00, 0x00, // Row 01: | |
0x00, 0x00, 0x00, // Row 02: | |
0x00, 0x00, 0x00, // Row 03: | |
0x00, 0x00, 0x00, // Row 04: | |
0x00, 0x00, 0x00, // Row 05: | |
0x00, 0x00, 0x00, // Row 06: | |
0x00, 0x30, 0x00, // Row 07: | ## |
0x00, 0x78, 0x00, // Row 08: | #### |
0x00, 0x78, 0x00, // Row 09: | #### |
0x00, 0x78, 0x00, // Row 10: | #### |
0x00, 0x00, 0x00, // Row 11: | |
0x00, 0x00, 0x00, // Row 12: | |
0x00, 0x00, 0x00, // Row 13: | |
0x00, 0x00, 0x00, // Row 14: | |
0x00, 0x00, 0x00, // Row 15: | |
0x00, 0x00, 0x00, // Row 16: | |
0x00, 0x78, 0x00, // Row 17: | #### |
0x00, 0x78, 0x00, // Row 18: | #### |
0x00, 0x78, 0x00, // Row 19: | #### |
0x00, 0x30, 0x00, // Row 20: | ## |
0x00, 0x00, 0x00, // Row 21: | |
0x00, 0x00, 0x00, // Row 22: | |
0x00, 0x00, 0x00, // Row 23: | |
};
// Sparse character set: this font does not cover a contiguous codepoint range.
// font_jetbrains_mono_bold_24x22_codes[] lists the included codepoints in ascending order; a
// character's glyph index is its position in that array (see the reference
// renderer below).
static const uint8_t font_jetbrains_mono_bold_24x22_codes[] = {
0x20, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A
};
Looking up '0' means a linear search over font_jetbrains_mono_bold_24x22_codes[]
— it's at index 1, so its glyph is font_jetbrains_mono_bold_24x22[1 * 72].
See the header format reference for how the sparse
reference renderer does this lookup.
6. The byte savings
| Character set | Glyphs | Table size |
|---|---|---|
| Full ASCII (95) | 95 | 6840 bytes |
| Digits only (10) | 10 | 720 bytes |
| Digits + space + : | 12 | 864 bytes (+ 12 bytes index) |
Trimming Full ASCII down to digits + space + colon cuts the glyph table from 6840 bytes to 864 bytes — about 87% smaller, plus a 12-byte index table.
7. C++ wrapper and out-of-set characters
If your firmware ever receives a character outside this 12-glyph set (a stray letter in a
debug string, for example), the plain C reference renderer silently skips it. If you enable
"Generate C++ class wrapper" in Header Options, the generated {name}_font::glyph(char)
instead returns a configurable fallback glyph — blank, a hollow box, or a copy of another
glyph in the set — for any character contains(char) reports as missing. See
the header format reference for the full wrapper output.