Font System

Complete guide to character support and custom font creation for Central European languages.

Character Support

SpojBoard implements full support for Central European diacritical characters using custom 8-bit ISO-8859-2 fonts with automatic UTF-8 conversion.

The Problem

Standard Adafruit GFX fonts use 7-bit encoding (ASCII), which doesn't include:

  • Czech: ž, š, č, ř, ň, ť, ď, ú, ů, á, é, í, ó, ý
  • German: ß, ä, ö, ü, Ä, Ö, Ü
  • Polish/Hungarian: ł, ń, ś, ź, ő, ű

The Solution

SpojBoard uses a three-step conversion pipeline:

  1. Custom 8-bit fonts — Generated with fontconvert8, range 0x20-0xDF (192 characters)
  2. UTF-8 decoder — Converts multi-byte UTF-8 to Unicode code points
  3. ISO-8859-2 mapper — Maps Unicode to ISO-8859-2 with GFX encoding shift

Available Fonts

SpojBoard includes three custom fonts optimized for LED matrix display:

DepartureMono Regular 4pt

Small font for compact text, line numbers, status messages

  • Character width: ~3-4 pixels
  • Line height: 6 pixels

DepartureMono Regular 5pt

Medium font for destinations, ETAs, larger text

  • Character width: ~4-5 pixels
  • Line height: 8 pixels

DepartureMono Condensed 5pt

Auto-used for destinations >16 characters

  • Character width: ~3-4 pixels (narrower)
  • Capacity: up to 23 characters on 128px

Automatic Font Selection

The display automatically chooses the font based on destination length:*

  • ≤14-15 characters: Regular 5pt font (adjusted for AC indicator and ETA width)
  • >15 characters: Condensed 5pt font (up to 23 chars)
  • >23 characters: Horizontal scrolling enabled
*Single ETA mode thresholds. Available character space decreases when more information is displayed:
  • Platform enabled: ~2 fewer characters
  • Dual ETA enabled: ~4 fewer characters
  • Both enabled: ~6 fewer characters

The display compensates automatically by switching to condensed font earlier or enabling scrolling for long destinations.

Character Set Coverage

All fonts include the full ISO-8859-2 character set:

Czech Diacritics

Á áČ čĎ ďÉ é Ě ěÍ íŇ ňÓ ó Ř řŠ šŤ ťÚ ú Ů ůÝ ýŽ ž

Additional Languages

  • German: Ä Ö Ü ß (ä ö ü)
  • Polish: Ą Ć Ę Ł Ń Ó Ś Ź Ż
  • Hungarian: Ő Ű (ő ű)
  • Slovak: Ľ Ĺ Ŕ (ľ ĺ ŕ)

Creating Custom Fonts

To create your own ISO-8859-2 fonts:

1. Install fontconvert8

git clone https://github.com/petrbrouzda/fontconvert8-iso8859-2.git
cd fontconvert8-iso8859-2/fontconvert8
make

2. Convert Your Font

# Convert TrueType font to Adafruit GFX format
./fontconvert YourFont.ttf 5 > YourFont5pt8b.h

# Naming convention: FontName[size]pt8b.h
# 8b = 8-bit encoding

3. Fine-Tune (Optional)

Use the Adafruit GFX Font Customiser to:

  • Visualize the font in browser
  • Edit individual glyphs pixel by pixel
  • Adjust spacing and kerning
  • Export modified .h file

4. Integrate into Firmware

  1. Copy the .h file to src/fonts/
  2. Include in DisplayManager.cpp
  3. Rebuild and flash
Mac M-series: You may need to install FreeType2 via Homebrew and update the Makefile paths for ARM64.

Usage in Code

#include "../fonts/DepartureMono5pt8b.h"
#include "../utils/gfxlatin2.h"

// Get UTF-8 string from API
char destination[32];
strlcpy(destination, "Nádraží Hostivař", sizeof(destination));

// Convert to ISO-8859-2 (in-place, call ONCE)
utf8tocp(destination);

// Display with proper Czech characters
display->setFont(&DepartureMono_Regular5pt8b);
display->print(destination);

Troubleshooting

Missing Characters (boxes or gaps)

Font doesn't include the character. Regenerate with fontconvert8.

Garbled Text

Forgot to call utf8tocp() before display. Always convert UTF-8 strings first.

Overlapping Characters

Use GFX Font Customiser to adjust character spacing.

Performance

  • Memory: ~2-4 KB per font in PROGMEM (flash, not RAM)
  • Rendering: ~0.1ms per character, ~1-2ms for typical destination
  • UTF-8 conversion: <0.1ms (one-time)