feat(eink): Text size and Icon size settings for big panels

On an 800x480 panel the doubled 6x9 font and the status bar's icons are
tiny. Two opt-in build flags, each also a setting under Settings > Display:

- EINK_FONT_SCALE=<n>: the landscape font's pixel multiplier (stock 2).
  Settings > Display > Text size (1x-5x) overrides it at run time
  (DisplayDriver::setUiScale -> EinkGfxDisplay re-lays out).
- STATUS_ICON_SCALE=<n>: Home's status icons, battery and page-icon row
  drawn at n x their pixel grid, the bar growing to fit. 0 = Auto, 1.5x
  the text's pixel scale. Settings > Display > Icon size (Auto, 1x-8x).

Both live in their own /ui_scale file, so NodePrefs is untouched. Icon size
appears only where STATUS_ICON_SCALE is set; Text size appears on every
e-ink build with the full-refresh setting, and builds that set neither
flag draw as before until it is changed. The GDEQ0426T82 env defaults to
4x text with Auto icons.

Tested in the native sim at 800x480.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KxAZVAbhhYr18Dd4guTQM1
This commit is contained in:
pmow
2026-10-09 11:57:29 -10:00
co-authored by Claude Opus 5.5
parent da5ff56cff
commit 2c1e1fa930
8 changed files with 186 additions and 18 deletions
+1
View File
@@ -536,6 +536,7 @@ public:
virtual void setBrightness(uint8_t level) { } // level 0-4 (min to max), no-op default
virtual void setDisplayRotation(uint8_t rot) { } // 0-3, no-op for fixed-orientation displays
virtual void setFullRefreshInterval(uint8_t n) { } // e-ink: do full refresh every n partial refreshes (0=never)
virtual void setUiScale(uint8_t font_scale) { } // e-ink: text pixel multiplier, 0 = build default
// Sideways slide between two frames, for screens that page left/right.
// slideBegin() keeps rows y0.. of the frame on screen now; call it before the
// next frame is drawn. slideCompose(dx), at the end of drawing that frame,
+4
View File
@@ -30,6 +30,7 @@ class EinkGfxDisplay : public DisplayDriver {
const GFXfont* _font;
int _cell_w = 6, _cell_h = 9; // the font's cell, before _px and the text size
int _px = 1; // pixel doubling (landscape without EINK_LARGE_FONT)
uint8_t _px_override = 0; // Settings > Display > Text size (0 = build default)
int _text_sz = 1;
int _cx = 0, _cy = 0; // cursor, top of the text row
uint32_t _hash = 0, _shown_hash = 0;
@@ -74,6 +75,9 @@ public:
dest[dest_size - 1] = '\0';
}
bool isEink() override { return true; }
// Runtime text scale (Settings > Display > Text size): re-lays out and forces
// a full redraw. 0 = the build default (EINK_FONT_SCALE).
void setUiScale(uint8_t font_scale) override { _px_override = font_scale; updateLayout(); }
void startFrame(Color bkg = DARK) override;
void setTextSize(int sz) override;
+9 -2
View File
@@ -3,6 +3,12 @@
// the font tables below are static arrays.
#include "EinkGfxDisplay.h"
// EINK_FONT_SCALE=<n>: pixel multiplier for the 6x9 font on a landscape panel
// without EINK_LARGE_FONT (default 2). 4 on an 800x480 panel = 24x36 cells,
// ~33 characters x 13 lines. Settings > Display > Text size overrides it at run time.
#ifndef EINK_FONT_SCALE
#define EINK_FONT_SCALE 2
#endif
#include "MiscFixedRenderer.h"
#if EINK_LARGE_FONT == 2
#include "MiscFixed9x15Font.h"
@@ -20,7 +26,8 @@ EinkGfxDisplay::EinkGfxDisplay(int w, int h, Adafruit_GFX& gfx, uint16_t ink, ui
void EinkGfxDisplay::updateLayout() {
const bool landscape = width() >= height();
_font = (EINK_LARGE_FONT && landscape) ? &EINK_LARGE_GFXFONT : &MiscFixed;
_px = (!EINK_LARGE_FONT && landscape) ? 2 : 1;
_px = (!EINK_LARGE_FONT && landscape) ? EINK_FONT_SCALE : 1;
if (_px_override) _px = _px_override;
_cell_w = miscFixedCellW(*_font);
_cell_h = _font->yAdvance;
_vw_dirty = true;
@@ -87,7 +94,7 @@ void EinkGfxDisplay::fillRect(int x, int y, int w, int h) {
void EinkGfxDisplay::drawRect(int x, int y, int w, int h) {
mix<int>(x); mix<int>(y); mix<int>(w); mix<int>(h);
_gfx.drawRect(x, y, w, h, _curr);
if (_px == 2 && w > 2 && h > 2) _gfx.drawRect(x + 1, y + 1, w - 2, h - 2, _curr);
if (_px >= 2 && w > 2 && h > 2) _gfx.drawRect(x + 1, y + 1, w - 2, h - 2, _curr);
}
void EinkGfxDisplay::drawXbm(int x, int y, const uint8_t* bits, int w, int h) {