From 9de60a11360f17b9caefd380bf30d922e8c5344f Mon Sep 17 00:00:00 2001 From: Arcao <arcao@arcao.com> Date: Tue, 2 Aug 2016 12:00:06 +0200 Subject: [PATCH] Support for custom font table look-up function --- OLEDDisplay.cpp | 34 +++++++++++----------------------- OLEDDisplay.h | 28 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/OLEDDisplay.cpp b/OLEDDisplay.cpp index 2161d3e..75cb6ff 100644 --- a/OLEDDisplay.cpp +++ b/OLEDDisplay.cpp @@ -569,12 +569,17 @@ size_t OLEDDisplay::write(uint8_t c) { // Don't waste space on \r\n line endings, dropping \r if (c == 13) return 1; + // convert UTF-8 character to font table index + c = (this->fontTableLookupFunction)(c); + // drop unknown character + if (c == 0) return 1; + bool maxLineNotReached = this->logBufferLine < this->logBufferMaxLines; bool bufferNotFull = this->logBufferFilled < this->logBufferSize; // Can we write to the buffer? if (bufferNotFull && maxLineNotReached) { - this->logBuffer[logBufferFilled] = utf8ascii(c); + this->logBuffer[logBufferFilled] = c; this->logBufferFilled++; // Keep track of lines written if (c == 10) this->logBufferLine++; @@ -717,27 +722,6 @@ void inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t widt } } -// Code form http://playground.arduino.cc/Main/Utf8ascii -uint8_t OLEDDisplay::utf8ascii(byte ascii) { - static uint8_t LASTCHAR; - - if ( ascii < 128 ) { // Standard ASCII-set 0..0x7F handling - LASTCHAR = 0; - return ascii; - } - - uint8_t last = LASTCHAR; // get last char - LASTCHAR = ascii; - - switch (last) { // conversion depnding on first UTF8-character - case 0xC2: return (ascii); break; - case 0xC3: return (ascii | 0xC0); break; - case 0x82: if (ascii == 0xAC) return (0x80); // special case Euro-symbol - } - - return 0; // otherwise: return zero, if character has to be ignored -} - // You need to free the char! char* OLEDDisplay::utf8ascii(String str) { uint16_t k = 0; @@ -754,7 +738,7 @@ char* OLEDDisplay::utf8ascii(String str) { length--; for (uint16_t i=0; i < length; i++) { - char c = utf8ascii(s[i]); + char c = (this->fontTableLookupFunction)(s[i]); if (c!=0) { s[k++]=c; } @@ -765,3 +749,7 @@ char* OLEDDisplay::utf8ascii(String str) { // This will leak 's' be sure to free it in the calling function. return s; } + +void OLEDDisplay::setFontTableLookupFunction(FontTableLookupFunction function) { + this->fontTableLookupFunction = function; +} \ No newline at end of file diff --git a/OLEDDisplay.h b/OLEDDisplay.h index 7c1dcf2..f6a27d7 100644 --- a/OLEDDisplay.h +++ b/OLEDDisplay.h @@ -107,6 +107,7 @@ enum OLEDDISPLAY_TEXT_ALIGNMENT { TEXT_ALIGN_CENTER_BOTH = 3 }; +typedef byte (*FontTableLookupFunction)(const byte ch); class OLEDDisplay : public Print { public: @@ -183,6 +184,9 @@ class OLEDDisplay : public Print { // ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24 void setFont(const char *fontData); + // Set the function that will convert utf-8 to font table index + void setFontTableLookupFunction(FontTableLookupFunction function); + /* Display functions */ // Turn the display on @@ -253,13 +257,33 @@ class OLEDDisplay : public Print { void sendInitCommands(); // converts utf8 characters to extended ascii - static char* utf8ascii(String s); - static byte utf8ascii(byte ascii); + char* utf8ascii(String s); void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline)); void drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth); + // UTF-8 to font table index converter + // Code form http://playground.arduino.cc/Main/Utf8ascii + FontTableLookupFunction fontTableLookupFunction = [](const byte ch) { + 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; break; + case 0xC3: return (uint8_t) (ch | 0xC0); break; + case 0x82: if (ch == 0xAC) return (uint8_t) 0x80; // special case Euro-symbol + } + + return (uint8_t) 0; // otherwise: return zero, if character has to be ignored + }; }; #endif -- GitLab