From d48e803b7b2b3e0c326561b0e2c18c9d2b5745d9 Mon Sep 17 00:00:00 2001 From: Professr Date: Mon, 22 Jun 2020 12:03:26 -0700 Subject: [PATCH 1/3] Custom utf8 conversion replaces unconvertable chars with ? instead of blanks, #154 --- src/screen.cpp | 3 +++ src/screen.h | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/screen.cpp b/src/screen.cpp index 9085dc0e..5d7d5579 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -499,6 +499,9 @@ void Screen::setup() // Store a pointer to Screen so we can get to it from static functions. ui.getUiState()->userData = this; + // Set the utf8 conversion function + dispdev.setFontTableLookupFunction(customFontTableLookup); + // Add frames. static FrameCallback bootFrames[] = {drawBootScreen}; static const int bootFrameCount = sizeof(bootFrames) / sizeof(bootFrames[0]); diff --git a/src/screen.h b/src/screen.h index 302c8e33..f5f4b3c9 100644 --- a/src/screen.h +++ b/src/screen.h @@ -149,6 +149,29 @@ class Screen : public PeriodicTask } } + /// Overrides the default utf8 character conversion, to replace empty space with question marks + static char customFontTableLookup(const uint8_t ch) { + // UTF-8 to font table index converter + // Code form http://playground.arduino.cc/Main/Utf8ascii + static uint8_t LASTCHAR; + + if (ch < 128) { // Standard ASCII-set 0..0x7F handling + LASTCHAR = 0; + return ch; + } + + uint8_t last = LASTCHAR; // get last char + LASTCHAR = ch; + + switch (last) { // conversion depnding on first UTF8-character + case 0xC2: return (uint8_t) ch; + case 0xC3: return (uint8_t) (ch | 0xC0); + case 0x82: if (ch == 0xAC) return (uint8_t) 0x80; // special case Euro-symbol + } + + return (uint8_t) '?'; // otherwise: return ?, if character can't be converted + } + /// Returns a handle to the DebugInfo screen. // // Use this handle to set things like battery status, user count, GPS status, etc. From 2530dc44c782ceab537acc1a333108d04999052d Mon Sep 17 00:00:00 2001 From: Professr Date: Tue, 23 Jun 2020 16:46:41 -0700 Subject: [PATCH 2/3] =?UTF-8?q?Changed=20unconvertable-character=20symbol?= =?UTF-8?q?=20to=20=C2=BF=20and=20made=20it=20return=20only=20one=20per=20?= =?UTF-8?q?unconvertable=20sequence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/screen.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/screen.h b/src/screen.h index f5f4b3c9..47860275 100644 --- a/src/screen.h +++ b/src/screen.h @@ -154,9 +154,11 @@ class Screen : public PeriodicTask // UTF-8 to font table index converter // Code form http://playground.arduino.cc/Main/Utf8ascii static uint8_t LASTCHAR; + static bool SKIPREST; // Only display a single unconvertable-character symbol per sequence of unconvertable characters if (ch < 128) { // Standard ASCII-set 0..0x7F handling LASTCHAR = 0; + SKIPREST = false; return ch; } @@ -164,12 +166,15 @@ class Screen : public PeriodicTask LASTCHAR = ch; switch (last) { // conversion depnding on first UTF8-character - case 0xC2: return (uint8_t) ch; - case 0xC3: return (uint8_t) (ch | 0xC0); - case 0x82: if (ch == 0xAC) return (uint8_t) 0x80; // special case Euro-symbol + case 0xC2: { SKIPREST = false; return (uint8_t) ch; } + case 0xC3: { SKIPREST = false; return (uint8_t) (ch | 0xC0); } + case 0x82: { SKIPREST = false; if (ch == 0xAC) return (uint8_t) 0x80; } // special case Euro-symbol } + // If we already returned an unconvertable-character symbol for this unconvertable-character sequence, return NULs for the rest of it + if (SKIPREST) return (uint8_t) 0; + SKIPREST = true; - return (uint8_t) '?'; // otherwise: return ?, if character can't be converted + return (uint8_t) 0xA8; // otherwise: return ¿ if character can't be converted } /// Returns a handle to the DebugInfo screen. From e3bcb87cf0f54c0785a41ac6591ac7dea81bf204 Mon Sep 17 00:00:00 2001 From: Professr Date: Tue, 23 Jun 2020 18:02:41 -0700 Subject: [PATCH 3/3] Removed prefix chars, fixed issues related to custom font mappings --- src/screen.cpp | 2 +- src/screen.h | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/screen.cpp b/src/screen.cpp index 18e5cb1d..1200e5a4 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -717,7 +717,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 } const char *fields[] = {channelStr, nullptr}; - uint32_t yo = drawRows(display, x, y + 12, fields); + uint32_t yo = drawRows(display, x, y + FONT_HEIGHT, fields); display->drawLogBuffer(x, yo); } diff --git a/src/screen.h b/src/screen.h index 47860275..95ca0a60 100644 --- a/src/screen.h +++ b/src/screen.h @@ -168,13 +168,16 @@ class Screen : public PeriodicTask switch (last) { // conversion depnding on first UTF8-character case 0xC2: { SKIPREST = false; return (uint8_t) ch; } case 0xC3: { SKIPREST = false; return (uint8_t) (ch | 0xC0); } - case 0x82: { SKIPREST = false; if (ch == 0xAC) return (uint8_t) 0x80; } // special case Euro-symbol } + + // We want to strip out prefix chars for two-byte char formats + if (ch == 0xC2 || ch == 0xC3 || ch == 0x82) return (uint8_t) 0; + // If we already returned an unconvertable-character symbol for this unconvertable-character sequence, return NULs for the rest of it if (SKIPREST) return (uint8_t) 0; SKIPREST = true; - return (uint8_t) 0xA8; // otherwise: return ¿ if character can't be converted + return (uint8_t) 191; // otherwise: return ¿ if character can't be converted (note that the font map we're using doesn't stick to standard EASCII codes) } /// Returns a handle to the DebugInfo screen.