diff --git a/src/helpers/ui/GxEPDDisplay.cpp b/src/helpers/ui/GxEPDDisplay.cpp index 664607f0..01a50eb3 100644 --- a/src/helpers/ui/GxEPDDisplay.cpp +++ b/src/helpers/ui/GxEPDDisplay.cpp @@ -16,10 +16,10 @@ // GFX fonts use the baseline as the cursor origin. UI code assumes top-of-cell // coordinates (same convention as the OLED driver). Add the font ascender so // the two conventions match. -static int fontAscender(int sz, bool use_lemon) { - if (sz == 3) return 26; // FreeSans18pt7b: proportional font, baseline origin - if (use_lemon) return 8; // Lemon GFX font: baseline origin, typical ascender 8px - return 0; // GFX built-in font: cursor is top-left of cell +static int fontAscender(int sz, bool use_lemon, int scale) { + if (sz == 3) return 26; // FreeSans18pt7b: proportional, baseline origin + if (use_lemon) return 8 * scale; // Lemon GFX font: baseline origin, ascender 8px×scale + return 0; // GFX built-in font: cursor is top-left of cell } bool GxEPDDisplay::begin() { @@ -72,14 +72,19 @@ void GxEPDDisplay::startFrame(Color bkg) { display.fillScreen(GxEPD_WHITE); display.setTextColor(_curr_color = GxEPD_BLACK); _text_sz = 1; + int sc = (width() >= height()) ? 2 : 1; display.setFont(_use_lemon ? &Lemon : NULL); - display.setTextSize(1); + display.setTextSize(sc); display_crc.reset(); } void GxEPDDisplay::setTextSize(int sz) { _text_sz = sz; display_crc.update(sz); + // Size 1 scales with orientation: 1× in portrait (≈OLED width), 2× in landscape. + // Size 2 always uses 2× built-in (12×16) — fixed because layout Y-positions are hardcoded. + // Size 3 always uses FreeSans18pt for large headings. + int sc = (width() >= height()) ? 2 : 1; switch (sz) { case 3: display.setFont(&FreeSans18pt7b); @@ -91,7 +96,7 @@ void GxEPDDisplay::setTextSize(int sz) { break; default: display.setFont(_use_lemon ? &Lemon : NULL); - display.setTextSize(1); + display.setTextSize(sc); break; } } @@ -111,7 +116,8 @@ void GxEPDDisplay::setCursor(int x, int y) { display_crc.update(y); // Offset y by the font ascender: callers pass top-of-cell y, GFX fonts // expect baseline y. Without this, text would be clipped at the top. - display.setCursor(x, y + fontAscender(_text_sz, _use_lemon)); + int sc = (width() >= height()) ? 2 : 1; + display.setCursor(x, y + fontAscender(_text_sz, _use_lemon, sc)); } void GxEPDDisplay::print(const char* str) { diff --git a/src/helpers/ui/GxEPDDisplay.h b/src/helpers/ui/GxEPDDisplay.h index 278df610..c5fa53fc 100644 --- a/src/helpers/ui/GxEPDDisplay.h +++ b/src/helpers/ui/GxEPDDisplay.h @@ -68,11 +68,20 @@ public: // 1 = FreeSans9pt (lineH=16, charW≈9) // 2 = FreeSansBold12pt (lineH=20, charW≈12) // 3 = FreeSans18pt (lineH=28, charW≈17) - // Size 1: GFX built-in 6×8 (default) or Lemon 5×10 bitmap font — matches OLED metrics. - // Size 2: GFX built-in scaled 12×16 bitmap font. - // Size 3: FreeSans18pt proportional font for large headings. - int getCharWidth() const override { return _text_sz == 3 ? 17 : _text_sz == 2 ? 12 : (_use_lemon ? 5 : 6); } - int getLineHeight() const override { return _text_sz == 3 ? 28 : _text_sz == 2 ? 16 : (_use_lemon ? 10 : 8); } + // Size 1 scales with orientation (portrait 1×, landscape 2×); size 2 is always 12×16; + // size 3 is FreeSans18pt (~17×28). Landscape = width >= height. + int getCharWidth() const override { + int sc = (width() >= height()) ? 2 : 1; + if (_text_sz == 3) return 17; + if (_text_sz == 2) return 12; + return (_use_lemon ? 5 : 6) * sc; + } + int getLineHeight() const override { + int sc = (width() >= height()) ? 2 : 1; + if (_text_sz == 3) return 28; + if (_text_sz == 2) return 16; + return (_use_lemon ? 10 : 8) * sc; + } void setLemonFont(bool enabled) override { _use_lemon = enabled; } bool begin();