# Flash Size Optimization: Per-Family Font and Per-Language Hyphenation Flags **Date**: 2026-02-15 ## Task Description Investigated ESP32-C3 flash usage (97.3% full at 6.375 MB / 6.5 MB app partition) and implemented build flags to selectively exclude font families and hyphenation language tries. Fonts alone consumed 65.6% of flash (3.99 MB). ## Changes Made ### 1. `lib/EpdFont/builtinFonts/all.h` - Wrapped Bookerly includes (16 files) in `#ifndef OMIT_BOOKERLY` - Wrapped Noto Sans 12-18pt includes (16 files) in `#ifndef OMIT_NOTOSANS` (kept `notosans_8_regular.h` outside guard for UI small font) - Wrapped OpenDyslexic includes (16 files) in `#ifndef OMIT_OPENDYSLEXIC` ### 2. `src/main.cpp` - Wrapped Bookerly 14pt font objects (previously always included) in `#ifndef OMIT_BOOKERLY` - Added per-family `#ifndef OMIT_*` guards inside the existing `#ifndef OMIT_FONTS` block for other sizes - Added matching guards to font registration in `setupDisplayAndFonts()` ### 3. `src/SettingsList.h` - Added `FontFamilyMapping` struct and `kFontFamilyMappings[]` compile-time table with per-family `#ifndef` guards - Switched Font Family setting from `SettingInfo::Enum` to `SettingInfo::DynamicEnum` with getter/setter that maps between list indices and fixed enum values (BOOKERLY=0, NOTOSANS=1, OPENDYSLEXIC=2) - Added `static_assert` ensuring at least one font family is available ### 4. `src/activities/settings/SettingsActivity.cpp` - Added DynamicEnum toggle support in `toggleCurrentSetting()` (cycles through options via `valueGetter`/`valueSetter`) - Added DynamicEnum display support in `render()` display lambda ### 5. `src/CrossPointSettings.cpp` - Guarded `getReaderFontId()` switch cases with `#ifndef OMIT_*`, added `default:` fallback to first available font - Guarded `getReaderLineCompression()` switch cases with `#ifndef OMIT_*`, added `default:` fallback - Added `#error` directive if all font families are omitted ### 6. `lib/Epub/Epub/hyphenation/LanguageRegistry.cpp` - Added per-language `#ifndef OMIT_HYPH_xx` guards around includes, `LanguageHyphenator` objects, and entries - Switched from `std::array` to `std::vector` for variable entry count - Languages: DE (201 KB), EN (27 KB), ES (13 KB), FR (7 KB), IT (2 KB), RU (33 KB) ### 7. `platformio.ini` - Added to `[env:mod]`: `-DOMIT_OPENDYSLEXIC`, `-DOMIT_HYPH_DE`, `-DOMIT_HYPH_EN`, `-DOMIT_HYPH_ES`, `-DOMIT_HYPH_FR`, `-DOMIT_HYPH_IT`, `-DOMIT_HYPH_RU` ## Design Decisions - Enum values stay fixed (BOOKERLY=0, NOTOSANS=1, OPENDYSLEXIC=2) for settings file compatibility - Existing `OMIT_FONTS` flag left untouched; per-family flags nest inside it - DynamicEnum used for Font Family to handle index-to-value mapping when fonts are removed from the middle of the options list ## Estimated Savings (mod build) - OpenDyslexic fonts: ~1,052 KB - All hyphenation tries: ~282 KB - **Total: ~1,334 KB (~1.30 MB)** -- from 97.3% down to ~76.9% ## Follow-up Items - Build and verify the `mod` environment compiles cleanly and flash size reduction matches estimates - Other available flags for future use: `OMIT_BOOKERLY`, `OMIT_NOTOSANS` (individual language OMIT_HYPH_xx flags can also be used selectively)