diff --git a/src/helpers/ui/DisplayDriver.h b/src/helpers/ui/DisplayDriver.h index 3f1089ec..a00fbbeb 100644 --- a/src/helpers/ui/DisplayDriver.h +++ b/src/helpers/ui/DisplayDriver.h @@ -134,23 +134,12 @@ public: size_t j = 0; const uint8_t* p = (const uint8_t*)src; while (*p && j < dest_size - 1) { - uint8_t c = *p++; - if (c < 0x80) { + if (*p < 0x80) { + uint8_t c = *p++; if (c >= 32) dest[j++] = c; } else { - uint32_t cp = c; - if ((c & 0xE0) == 0xC0) { - cp = c & 0x1F; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - } else if ((c & 0xF0) == 0xE0) { - cp = c & 0x0F; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - } else { - while (*p && (*p & 0xC0) == 0x80) p++; - dest[j++] = '\xDB'; - continue; - } + uint32_t cp = decodeCodepoint(p); + // transliterateCodepoint already returns '\xDB' for unmapped values (incl. 0xFFFD). dest[j++] = transliterateCodepoint(cp); } } diff --git a/src/helpers/ui/GxEPDDisplay.cpp b/src/helpers/ui/GxEPDDisplay.cpp index 267f7d82..c61ba3f2 100644 --- a/src/helpers/ui/GxEPDDisplay.cpp +++ b/src/helpers/ui/GxEPDDisplay.cpp @@ -23,31 +23,6 @@ static int fontAscender(int sz, bool use_lemon, int scale) { return 0; // GFX built-in font: cursor is top-left of cell } -uint32_t GxEPDDisplay::decodeUtf8(const uint8_t*& p) { - uint8_t c = *p++; - if (c < 0x80) return c; - if ((c & 0xE0) == 0xC0) { - uint32_t cp = c & 0x1F; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - return cp; - } - if ((c & 0xF0) == 0xE0) { - uint32_t cp = c & 0x0F; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - return cp; - } - if ((c & 0xF8) == 0xF0) { - uint32_t cp = c & 0x07; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - return cp; - } - while (*p && (*p & 0xC0) == 0x80) p++; - return 0xFFFD; -} - // y is the GFX baseline (display.getCursorY()), which equals original_y + 8*sc. // Pixels are placed at y + yo*sc + row*sc — identical to how GFX would render // a scaled GFX font, but bypassing GFX so multi-byte UTF-8 is decoded correctly. @@ -209,7 +184,7 @@ void GxEPDDisplay::print(const char* str) { const int sc = scale(); const uint8_t* p = (const uint8_t*)str; while (*p) { - uint32_t cp = decodeUtf8(p); + uint32_t cp = decodeCodepoint(p); if (cp == '\n') { cy += Lemon.yAdvance * sc; cx = 0; } else { cx = drawLemonChar(cx, cy, cp, sc); } } @@ -271,7 +246,7 @@ uint16_t GxEPDDisplay::getTextWidth(const char* str) { uint16_t total = 0; const int sc = scale(); const uint8_t* p = (const uint8_t*)str; - while (*p) total += lemonXAdvance(decodeUtf8(p), sc); + while (*p) total += lemonXAdvance(decodeCodepoint(p), sc); return total; } display.setTextWrap(false); diff --git a/src/helpers/ui/GxEPDDisplay.h b/src/helpers/ui/GxEPDDisplay.h index 18e185ca..ea43e153 100644 --- a/src/helpers/ui/GxEPDDisplay.h +++ b/src/helpers/ui/GxEPDDisplay.h @@ -57,7 +57,6 @@ class GxEPDDisplay : public DisplayDriver { uint8_t _full_refresh_interval = 0; uint8_t _partial_count = 0; - static uint32_t decodeUtf8(const uint8_t*& p); int16_t drawLemonChar(int16_t x, int16_t y, uint32_t cp, int sc); uint8_t lemonXAdvance(uint32_t cp, int sc); int scale() const { return (width() >= height()) ? 2 : 1; } diff --git a/src/helpers/ui/SH1106Display.cpp b/src/helpers/ui/SH1106Display.cpp index 67384954..2adfa044 100644 --- a/src/helpers/ui/SH1106Display.cpp +++ b/src/helpers/ui/SH1106Display.cpp @@ -65,31 +65,6 @@ void SH1106Display::setCursor(int x, int y) display.setCursor(x, y); } -uint32_t SH1106Display::decodeUtf8(const uint8_t*& p) { - uint8_t c = *p++; - if (c < 0x80) return c; - if ((c & 0xE0) == 0xC0) { - uint32_t cp = c & 0x1F; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - return cp; - } - if ((c & 0xF0) == 0xE0) { - uint32_t cp = c & 0x0F; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - return cp; - } - if ((c & 0xF8) == 0xF0) { - uint32_t cp = c & 0x07; - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - if (*p) cp = (cp << 6) | (*p++ & 0x3F); - return cp; - } - while (*p && (*p & 0xC0) == 0x80) p++; - return 0xFFFD; -} - int16_t SH1106Display::drawLemonChar(int16_t x, int16_t y, uint32_t cp) { int sz = _text_sz; for (uint8_t i = 0; i < lemonIconCount; i++) { @@ -161,7 +136,7 @@ void SH1106Display::print(const char *str) int16_t cy = display.getCursorY(); const uint8_t* p = (const uint8_t*)str; while (*p) { - uint32_t cp = decodeUtf8(p); + uint32_t cp = decodeCodepoint(p); if (cp == '\n') { cy += Lemon.yAdvance; cx = 0; } else { cx = drawLemonChar(cx, cy, cp); } } @@ -188,7 +163,7 @@ uint16_t SH1106Display::getTextWidth(const char *str) if (_use_lemon) { uint16_t width = 0; const uint8_t* p = (const uint8_t*)str; - while (*p) width += lemonXAdvance(decodeUtf8(p)); + while (*p) width += lemonXAdvance(decodeCodepoint(p)); return width; } int16_t x1, y1; diff --git a/src/helpers/ui/SH1106Display.h b/src/helpers/ui/SH1106Display.h index d7016a72..37d83a27 100644 --- a/src/helpers/ui/SH1106Display.h +++ b/src/helpers/ui/SH1106Display.h @@ -25,7 +25,6 @@ class SH1106Display : public DisplayDriver int _text_sz; bool i2c_probe(TwoWire &wire, uint8_t addr); - static uint32_t decodeUtf8(const uint8_t*& p); int16_t drawLemonChar(int16_t x, int16_t y, uint32_t cp); uint8_t lemonXAdvance(uint32_t cp);