Three copies of the same routine: DisplayDriver::decodeCodepoint (added
in the FullscreenMsgView wrap fix) plus per-driver duplicates in
SH1106Display and GxEPDDisplay. Consolidate on DisplayDriver and have
translateUTF8Static also route through it instead of its own inline
decoder. Net: 63 lines removed, single source of truth.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Lemon font (LemonFont.h, LemonIcons.h) to the standard build
alongside the Adafruit built-in font; ~101 KB added to flash
- SH1106Display: add _use_lemon flag + setLemonFont(bool) to switch
at runtime; print() and getTextWidth() use Lemon path when active;
translateUTF8ToBlocks() passes UTF-8 through unchanged (Lemon supports
full Unicode U+0020-U+04FF) vs transliterating for the default font
- DisplayDriver: add getCharWidth()/getLineHeight() virtuals (defaults 6/8);
SH1106Display returns 5/9 for Lemon, 6/8 for default; add setLemonFont()
no-op virtual; fix orphaned UTF-8 leading byte in drawTextEllipsized
- FullscreenMsgView: replace fixed-char-count word-wrap with pixel-accurate
wrap using display.getTextWidth(); use getLineHeight() for spacing so
Lemon (9 px) and default (8 px) both render correctly
- NodePrefs: add use_lemon_font field (0=default, 1=Lemon)
- SettingsScreen: add "Font" item in Display section (Default / Lemon),
calls UITask::applyFont() on change
- UITask: add applyFont() that calls display->setLemonFont(use_lemon_font);
called at startup (begin()) and when the setting changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MyMesh: notify() now always fires for channel/contact messages regardless
of serial connection; called after addChannelMsg so channel index is set
- ChannelHist: fix unread watermark direction (histEntry is newest-first,
index 0=newest); counter now decrements correctly as user reads messages
- ChannelHist: reset unread to 0 after sending (user is active in channel)
- SH1106Display: add pre-charge register (0xD9) to setBrightness for wider
dimming range; re-apply contrast+precharge in turnOn(); tune curve
- UITask: remove MsgPreviewScreen dead code (~180 lines, never shown)
- UITask: fix strcpy→snprintf in showAlert()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>