# 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}.c` else 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_X` guards - `lvgl_set_runtime_font_size(uint8_t)` / get - `lvgl_get_text_font_height()`: if runtime !=0, small=runtime-4, default=runtime, large=runtime+6 else use TT_ macros - `lvgl_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-fontsize` 12 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: 1. Download Montserrat Bold TTF 2. `lv_font_conv --font Montserrat-Bold.ttf -r 0x20-0x7E,0xA0-0xFF --size 20 --format lvgl -o lv_font_montserrat_bold_20.c` 3. 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.