- Migrates tactility-firmware and tactility-bluetooth from ~/.hermes/skills/ into .claude/skills/ for repo co-location - Adds AGENTS.md with local workstation context, board table, board-direct build rule, Hermes PYTHONPATH pitfall, common Tactility pitfalls, and in-repo skill index Refs: personal Gitea mirror
3.7 KiB
Runtime Font Size Setting — RLCD (2026-07-13)
User Request
"What is the next font size available? Can we add font size on the display settings?"
Next Available Sizes
Current compile-time default: 20 (16/20/26 small/default/large) — second +15% bump from 18. Next:
- 24 → 18/24/30 (+20% over 20, +71% over original 14 baseline)
- 28 → 20/28/36
Icon fonts available check:
- launcher: 30,36,42,48,64,72 — so 48 used for 20 bucket, 64 for 24 bucket, 72 for >24
- shared: 12,16,20,24,32
- statusbar: 12,16,20,30
Must exist as
material_symbols_launcher_${size}.celse CMake "No SOURCES given".
Implementation for Runtime Setting (no rebuild)
Problem
Fonts were compile-time only via device.py → sdkconfig CONFIG_TT_LVGL_FONT_SIZE_* → TT_LVGL_TEXT_FONT_*_SYMBOL=lv_font_montserrat_X macros. Changing requires full rebuild + flash (slow, ~15s flash + build).
Solution
Build superset of fonts into binary and switch at runtime via global.
device.py change
elif font_height <=20: bucket now also:
CONFIG_LV_FONT_MONTSERRAT_14=y
CONFIG_LV_FONT_MONTSERRAT_18=y
CONFIG_LV_FONT_MONTSERRAT_24=y
CONFIG_LV_FONT_MONTSERRAT_28=y
CONFIG_LV_FONT_MONTSERRAT_30=y
Adds ~150KB to binary (2900080 → ~3050000 est). Still within 4MB app partition (31% free → ~22% free after).
lvgl_fonts.c
- Global
static uint8_t g_runtime_font_size = 0 get_font_for_size(uint8_t size)with#ifdef CONFIG_LV_FONT_MONTSERRAT_Xguardslvgl_set_runtime_font_size(uint8_t)/ getlvgl_get_text_font_height(): if runtime !=0, small=runtime-4, default=runtime, large=runtime+6 else use TT_ macroslvgl_get_text_font(): same scaling, calls get_font_for_size, fallback to compile-time if not found- Uses NULL not nullptr (C, not C++)
- Externs from LVGL lib:
extern const lv_font_t lv_font_montserrat_14;etc guarded by CONFIG.
lvgl_fonts.h
Expose runtime setter/getter.
DisplaySettings
- Field
uint8_t fontSize = 0(0=compile-time default) - Key
fontSize, load clamp 0..36, save - getDefault() fontSize=0
Lvgl.cpp boot
if (settings.fontSize != 0) {
lvgl_set_runtime_font_size(settings.fontSize);
}
Display.cpp UI
- Dropdown options: "Default\n14 Small\n16\n18\n20\n24 Next\n28 Large"
- Map index→size via
font_sizes[] = {0,14,16,18,20,24,28} - Handler
onFontSizeChanged: set displaySettings.fontSize, updated=true,lvgl_set_runtime_font_size(new_size)live - Current selection mapping from saved fontSize to idx
Behavior
- Changing font size applies to next opened screens (apps, launcher) immediately, current Display app keeps old fonts until reopened (since widgets already created with old font). No reboot required, but for full UI refresh user can reboot or reopen apps.
- Persists across reboots via display.properties
- Icons remain compile-time size (20/48/20) — to make icons runtime too would need similar logic for icon fonts.
Verification
- Ad-hoc script
hermes-verify-fontsize12 checks PASS - Build blocked by terminal approval dialog for flash (board-direct requires approval popup for
idf.py -p /dev/cu.usbmodem1101 flash). Once approved, build size expected ~3.0MB, still under 4MB partition.
Future: True Bold
LVGL stock only Montserrat Regular. Bold would need:
- Download Montserrat Bold TTF
lv_font_conv --font Montserrat-Bold.ttf -r 0x20-0x7E,0xA0-0xFF --size 20 --format lvgl -o lv_font_montserrat_bold_20.c- Add to
Libraries/lvgl/src/font/or custom fonts dir, add CONFIG, extern, use as font. Alternative synthetic bold: render text with 1px outline or use threshold 60 already bolder (more black pixels).
Docs Reference
Tactility only 3 themes, not font bold. For bold, no built-in LVGL bold variant.