fix: draw substitution block for unsupported characters in SH1106 Lemon renderer

- drawLemonChar: for codepoints outside the font range (> U+04FF) that
  are printable (>= U+0020), render a 4×6 filled rectangle instead of
  silently advancing the cursor with no visible output
- decodeUtf8: properly decode 4-byte UTF-8 sequences (U+10000+) to their
  actual codepoints so they reach the block fallback; return U+FFFD for
  genuinely invalid bytes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-18 09:30:25 +02:00
co-authored by Claude Sonnet 4.6
parent acc062718f
commit de8861f574
+11 -3
View File
@@ -84,9 +84,16 @@ uint32_t SH1106Display::decodeUtf8(const uint8_t*& p) {
if (*p) cp = (cp << 6) | (*p++ & 0x3F); if (*p) cp = (cp << 6) | (*p++ & 0x3F);
return cp; return cp;
} }
// 4-byte and invalid — skip continuation bytes if ((c & 0xF8) == 0xF0) { // 4-byte: U+10000U+10FFFF
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;
}
// invalid byte — skip continuation bytes
while (*p && (*p & 0xC0) == 0x80) p++; while (*p && (*p & 0xC0) == 0x80) p++;
return '?'; return 0xFFFD;
} }
// Draw one Lemon glyph at (x, y), return new cursor x. // Draw one Lemon glyph at (x, y), return new cursor x.
@@ -113,7 +120,8 @@ int16_t SH1106Display::drawLemonChar(int16_t x, int16_t y, uint32_t cp) {
} }
if (cp < Lemon.first || cp > Lemon.last) { if (cp < Lemon.first || cp > Lemon.last) {
// outside font range — use default advance if (cp >= 0x20) // not a control character — draw substitution block
display.fillRect(x + 1, y - 1, 4, 6, _color);
return x + 6; return x + 6;
} }
const GFXglyph* glyph = &lemonGlyphs[cp - Lemon.first]; const GFXglyph* glyph = &lemonGlyphs[cp - Lemon.first];