Fonts
Fonts in Lopaka are platform-specific. Each target library has its own font format and its own set of built-in fonts — you cannot freely mix fonts across platforms. This page explains which font formats each platform uses, how to pick and import fonts in the editor, and what happens to your font choice when you generate code.
Font formats
Lopaka works with three font formats internally:
| Format | Description | Used by |
|---|---|---|
| BDF | Bitmap Distribution Format — a plain-text bitmap font standard | U8g2, CircuitPython |
| GFX | Adafruit GFX — a C header (.h) containing a bitmap array and glyph table | TFT_eSPI, AdafruitGFX, ArduinoGFX, GxEPD2 |
| TTF / OTF / WOFF | TrueType and OpenType vector fonts | LVGL, ESPHome |
Some platforms (Flipper Zero, MicroPython) do not use any of these formats — their fonts are fixed and compiled into the library itself. Those are covered in the platform sections below.
When you upload a custom font, Lopaka converts it to the format the active platform needs — you never have to deal with conversion manually (with a few exceptions described below).
Importing a custom font
To import a font, select a text layer, open the font dropdown in the Inspector, and click Import font…. Choose a file from your filesystem. What happens next depends on the file format and the active platform.
GFX header (.h)
Supported on: TFT_eSPI, AdafruitGFX, ArduinoGFX, GxEPD2
The file is used as-is with no conversion. Once uploaded, the font is available in the font list and its bitmap data is embedded in the generated code.
BDF font
Supported on: U8g2, TFT_eSPI, AdafruitGFX, ArduinoGFX, GxEPD2
- On U8g2 — the file is uploaded directly. The font name is used as-is in the generated code.
- On GFX-based platforms — the BDF file is automatically converted to GFX format before upload. The conversion covers the printable ASCII range (0x20–0x7E). The result is treated identically to a native GFX font.
TTF / OTF / WOFF
Supported on: TFT_eSPI, AdafruitGFX, ArduinoGFX, GxEPD2
Uploading a vector font opens the Font Wizard:
- Font Height — set the target pixel height. This controls how the glyphs are rasterized. Smaller values produce compact bitmaps; larger values produce sharper glyphs at the cost of more flash memory.
- Preview Zoom — scale the preview (1×–5×) to inspect the result. This does not affect the output.
- Click Import — the font is rasterized to GFX format and saved to the project.
The wizard only covers printable ASCII (space through tilde, 95 characters). Extended characters, accented letters, and CJK glyphs are not included in the output. If you need extended coverage, prepare a
.hfile with a tool that supports it and upload that instead.
Font size and scaling
| Platform | Size control | How it works |
|---|---|---|
| U8g2 | None — pick a different font | Each BDF font has one fixed size |
| TFT_eSPI / AdafruitGFX / ArduinoGFX / GxEPD2 | Integer scale (1×, 2×, …) | Pixel-doubles the bitmap |
| LVGL | None — fixed Montserrat | Early stage; no size or font controls |
| ESPHome | Free numeric (px) | Sets the size: field in YAML |
| Flipper Zero | None | Fixed system fonts |
| MicroPython / CircuitPython | None | Single built-in font |
What ends up in the generated code
GFX-based platforms
For every GFX font that is not the built-in 5×7 adafruit font, the generator inserts:
#include <Fonts/FontName.h>
const GFXfont *font_FontName = &FontName;If the same font is used by more than one layer, the declaration is deduplicated — it appears once.
U8g2
Only the font identifier appears inline:
u8g2.setFont(u8g2_font_helvB08_tr);No header and no variable.
Flipper Zero
The font constant is inlined directly:
canvas_set_font(canvas, FontPrimary);ESPHome
A font: block is added at the YAML document root. Multiple text layers that use different sizes of the same font produce separate entries.
LVGL
The built-in Montserrat font is referenced directly. No font variable or include is emitted.
Practical tips
- Minimum readable size on monochrome OLEDs. BDF fonts at 4–6 px are technically valid but become hard to read on real hardware. 8 px (e.g.
helvB08) is the practical minimum for most displays. - RAM budget for GFX fonts. Every GFX font you include occupies flash on the microcontroller. FreeMono12pt7b is about 1.7 KB; FreeMonoBold24pt7b is about 4.5 KB. Check your device's flash constraints before adding large fonts.
- Custom font character coverage. Lopaka's BDF→GFX and TTF→GFX converters only encode the printable ASCII range (space
0x20through tilde0x7E, 95 characters). If you need accented characters, symbols, or CJK glyphs you must use a pre-built.hfile that already contains them. - Custom fonts are tied to the project, not the platform. Uploaded fonts are stored as project assets and persist when you switch platforms. However, a font uploaded for one platform may not be compatible with another — a GFX
.hfont will not work on U8g2, and a BDF font will not work on TFT_eSPI.
Fonts by platform
U8g2
U8g2 ships with a large collection of BDF-derived fonts compiled directly into the library. Lopaka exposes this full collection in the font picker. Font names in the generated code follow the library's own naming scheme:
u8g2.setFont(u8g2_font_haxrcorp4089_tr);No font data is emitted into your sketch — the name alone is enough because the font is already inside the U8g2 library.
Font size is fixed. Each BDF font has a single baked-in pixel height. To display larger text you must choose a different font, not scale the current one.
Uploading custom fonts: U8g2 accepts .bdf files only. The file is added to the font list for the session with no format conversion.
TFT_eSPI, AdafruitGFX, ArduinoGFX, GxEPD2
These platforms all use the Adafruit GFX font format — a C header file that embeds the bitmap data directly. The built-in set includes the Adafruit 5×7 font and dozens of Free-family fonts at multiple sizes (FreeMono, FreeSans, FreeSerif in regular, bold, italic, bold-italic at 9, 12, 18, and 24 pt, and more).
The 5×7 font is the library's own default. It does not require a header declaration. For every other font the generator prepends an #include and a const GFXfont * variable to the output:
#include <Fonts/FreeMono12pt7b.h>
const GFXfont *font_FreeMono12pt7b = &FreeMono12pt7b;
// ...
tft.setFreeFont(font_FreeMono12pt7b);Font size is scalable. GFX fonts support an integer scale multiplier. A multiplier of 1 renders at native pixel size; 2 doubles both dimensions.
Y-position adjustment. GFX fonts use a descending baseline — the Y coordinate refers to the baseline, not the top of the glyph. Lopaka compensates automatically when you drag text on the canvas, and emits the corrected coordinate in generated code.
Uploading custom fonts. Accepts .h (pre-built GFX header), .bdf, .ttf, .otf, and .woff files.
.h— used as-is, no conversion..bdf— converted to GFX format automatically before upload..ttf/.otf/.woff— opens the font wizard (see above).
LVGL
LVGL support in Lopaka is in an early stage. Currently only one font is available — the built-in Montserrat — at a fixed size. Font selection and size controls are not exposed. This will be expanded in a future release.
ESPHome
ESPHome resolves fonts from Google Fonts at build time. The generated YAML contains a font: block that downloads the font by name when you flash the device:
font:
- file: gfonts://Roboto
id: font_roboto
size: 16Font size is configurable. The available fonts are the TTF fonts included in Lopaka's built-in set (Roboto, Montserrat, Ubuntu, and others). Custom font upload is not supported for ESPHome.
Flipper Zero and Flipper One
Flipper provides exactly four system fonts:
| Lopaka name | Flipper constant | Typical use |
|---|---|---|
| Primary | FontPrimary | Regular UI text |
| Secondary | FontSecondary | Small secondary labels |
| Keyboard | FontKeyboard | On-screen keyboard |
| Big Numbers | FontBigNumbers | Large digit display |
There are no size controls and no custom font upload.
MicroPython
MicroPython uses a single fixed built-in font (Petme 8×8). All text layers use it automatically.
CircuitPython
CircuitPython uses the Terminus BDF font. Custom font upload is not supported.