lcdgfx renders text from font tables stored in PROGMEM. You can use the
fonts that ship with the library, or generate your own from any TTF (or a
GLCD-exported .c file) with the tools/fontgenerator.py script.
This page covers:
- Generating a font — the common commands
- Per-group exact width — fix thin space/colon spacing
- Command-line options
- Binary format reference — for tooling authors
fontgenerator.py needs freetype-py
(pip install freetype-py). The generated C array is written to stdout, so
redirect it into a header/source file.
# Variable-width font (recommended): each glyph keeps its natural width
./fontgenerator.py --ttf consola.ttf -s 8 -g 0 127 -f new > my_font.cpp
# Fixed-width font: every glyph padded to the width of the widest one
./fontgenerator.py --ttf consola.ttf -s 8 -fw -g 0 127 -f new > my_font.cpp
# Preview the result in the console while generating (-d = demo text)
./fontgenerator.py --ttf consola.ttf -s 8 -g 0 127 -f new -d -t "Hello 12:45"-g <first> <count> selects a block of characters. <first> is a symbol, a
decimal code, or a 0x.. hex code; <count> is (number of chars − 1).
Repeat -g to pack several blocks (e.g. digits + Latin + Cyrillic) into one
font while skipping the gaps in between:
./fontgenerator.py --ttf consola.ttf -s 10 \
-g 48 9 -g 65 25 -g 97 25 -f new > alnum_font.cppUse the font in your sketch:
display.setFixedFont(my_font); // fixed font (type 0/1)
display.setFreeFont(free_my_font8x13); // free / variable font (type 2)The generated array name encodes the size, e.g.
free_consola6x13. Look at theextern const uint8_t ...line at the top of the output for the exact symbol to pass tosetFreeFont().
(New format only — the recommended fix for uneven spacing.)
A variable-width font keeps every glyph at its natural width, which is usually
what you want — but some characters are drawn very narrow. A space or colon may
be only 1–2 px wide, so a string like Cookies 325 12 mins looks cramped even
with getFont().setSpacing(1). Forcing the whole font to fixed width (-fw)
over-corrects: now every glyph is as wide as W, wasting space.
The optional 3rd argument of -g solves this per block:
-g <first> <count> <width>
It forces every char in that group to an exact pixel width, keeping the
glyph centered — narrow chars are padded with blank columns on both sides,
wider chars are cropped equally from both sides. The width is stored per char
in the jump table, so it costs nothing at runtime and combines cleanly with
setSpacing().
# space -> 5 px, colon -> 3 px, underscore -> 5 px, everything else natural
./fontgenerator.py --ttf consolas.ttf -s 10 \
-g 32 0 5 \
-g 58 0 3 \
-g 95 0 5 \
-g 48 9 -g 65 25 -g 97 25 \
-f new > consolas_10.cppNotes:
- Padding is split as evenly as possible; an odd remainder puts the extra column on the right.
- Cropping to a width narrower than the glyph's ink prints a warning on
stderr (
char U+XXXX cropped ...) — the glyph may lose pixels. - Do not combine a per-group width with
-fw.-fwforces one global width onto every char and would override the per-group values.
| Option | Meaning |
|---|---|
--ttf <file> |
Use a TTF file as the source. |
--glcd <file> |
Use a GLCD-exported .c file as the source. |
-s <N> |
Font size (point size, not pixels). |
-SB <N> |
Limit glyph height to N pixels (bottom pixels are cut). |
-fh |
Fixed height (pad all glyphs to the tallest). |
-fw |
Fixed width (pad all glyphs to the widest). |
-g <S> <E> [W] |
Add a char block: first char S, count-minus-1 E, optional exact width W (new format only). |
-f old |
Old fixed format (1.7.6 and below). |
-f new |
New free/variable format (1.7.8 and above). |
-d |
Print demo text to the console. |
-t <text> |
Text to use for the -d demo. |
--demo-only |
Print demo text and exit (no font emitted). |
--output-file <file> |
Write the font to a file directly (instead of stdout). |
For people writing tools that emit or parse lcdgfx fonts. Every field is one byte unless noted.
TYPE | WIDTH | HEIGHT | FIRSTCHAR
FIRSTUNICODE(MSB) | FIRSTUNICODE(LSB) | COUNT // type 1 only
--- FONT DATA: COUNT * WIDTH * ceil(HEIGHT/8) bytes
- TYPE 0 — ASCII 0–127 plus extended 128–255. Generated by the standalone LCD font generator GUI only.
- TYPE 1 — fixed cell size, but supports Unicode blocks. Generate with:
./fontgenerator.py --ttf consola.ttf -s 8 -g 0 127 -f old -d > output.cpp - WIDTH / HEIGHT — fixed cell size of each glyph.
- FIRSTCHAR — meaningful only for TYPE 0 (first ASCII code in the table).
TYPE | WIDTH | HEIGHT | FIRSTCHAR
FIRSTUNICODE(MSB) | FIRSTUNICODE(LSB) | COUNT
--- JUMP TABLE (one entry per char):
OFFSET(MSB) | OFFSET(LSB) | WIDTH | HEIGHT
--- FONT DATA
- TYPE — always 2.
- WIDTH (header) — unused for type 2.
- HEIGHT (header) — max glyph height of the font.
- FIRSTCHAR (header) — unused for type 2.
- JUMP TABLE
WIDTH/HEIGHT— the per-char dimensions. This is where a per-group exact width ends up, which is why it is free at render time.
WIDTH | HEIGHT | FIRSTCHAR | COUNT
--- JUMP TABLE:
OFFSET(MSB) | OFFSET(LSB) | BYTES | WIDTH
--- FONT DATA