Skip to content

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:

FormatDescriptionUsed by
BDFBitmap Distribution Format — a plain-text bitmap font standardU8g2, CircuitPython
GFXAdafruit GFX — a C header (.h) containing a bitmap array and glyph tableTFT_eSPI, AdafruitGFX, ArduinoGFX, GxEPD2
TTF / OTF / WOFFTrueType and OpenType vector fontsLVGL, 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:

  1. 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.
  2. Preview Zoom — scale the preview (1×–5×) to inspect the result. This does not affect the output.
  3. 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 .h file with a tool that supports it and upload that instead.

Font size and scaling

PlatformSize controlHow it works
U8g2None — pick a different fontEach BDF font has one fixed size
TFT_eSPI / AdafruitGFX / ArduinoGFX / GxEPD2Integer scale (1×, 2×, …)Pixel-doubles the bitmap
LVGLNone — fixed MontserratEarly stage; no size or font controls
ESPHomeFree numeric (px)Sets the size: field in YAML
Flipper ZeroNoneFixed system fonts
MicroPython / CircuitPythonNoneSingle 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:

cpp
#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:

c
u8g2.setFont(u8g2_font_helvB08_tr);

No header and no variable.

Flipper Zero

The font constant is inlined directly:

c
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 0x20 through tilde 0x7E, 95 characters). If you need accented characters, symbols, or CJK glyphs you must use a pre-built .h file 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 .h font 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:

c
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:

cpp
#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:

yaml
font:
    - file: gfonts://Roboto
      id: font_roboto
      size: 16

Font 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 nameFlipper constantTypical use
PrimaryFontPrimaryRegular UI text
SecondaryFontSecondarySmall secondary labels
KeyboardFontKeyboardOn-screen keyboard
Big NumbersFontBigNumbersLarge 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.