forked from fmueller/esp8266-led-marquee-sign-controller
before sending the text to the sign, translate any unicode characters to codepage 437 representation
This commit is contained in:
parent
c78fde5d9f
commit
610f86750b
81
src/util.h
81
src/util.h
@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
// TODO: reverse engineer builtin and custom bitmaps
|
// TODO: reverse engineer builtin and custom bitmaps
|
||||||
|
|
||||||
// seems like our sign listens to messages on this address
|
// seems like our sign listens to messages on this address
|
||||||
@ -246,6 +250,78 @@ enum class ExtendedChar {
|
|||||||
GreekSmallLetterPhi = 0xed,
|
GreekSmallLetterPhi = 0xed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::unordered_map<uint16_t, uint8_t> createUnicodeToCP437Map() {
|
||||||
|
std::unordered_map<uint16_t, uint8_t> cp437_map;
|
||||||
|
|
||||||
|
cp437_map[0x00E4] = 0x84; // ä in UTF-16
|
||||||
|
cp437_map[0xC3A4] = 0x84; // ä in UTF-8
|
||||||
|
cp437_map[0x00F6] = 0x94; // ö in UTF-16
|
||||||
|
cp437_map[0xC3B6] = 0x94; // ö in UTF-8
|
||||||
|
cp437_map[0x00FC] = 0x81; // ü in UTF-16
|
||||||
|
cp437_map[0xC3BC] = 0x81; // ü in UTF-8
|
||||||
|
cp437_map[0x00C4] = 0x8E; // Ä in UTF-16
|
||||||
|
cp437_map[0xC384] = 0x8E; // Ä in UTF-8
|
||||||
|
cp437_map[0x00D6] = 0x99; // Ö in UTF-16
|
||||||
|
cp437_map[0xC396] = 0x99; // Ö in UTF-8
|
||||||
|
cp437_map[0x00DC] = 0x9A; // Ü in UTF-16
|
||||||
|
cp437_map[0xC39C] = 0x9A; // Ü in UTF-8
|
||||||
|
cp437_map[0x00DF] = 0xE1; // ß in UTF-16
|
||||||
|
cp437_map[0xC39F] = 0xE1; // ß in UTF-8
|
||||||
|
cp437_map[0x20AC] = 0xB1; // € in UTF-16
|
||||||
|
cp437_map[0xE282AC] = 0xB1; // € in UTF-8 (3 Bytes)
|
||||||
|
cp437_map[0x00B5] = 0xE6; // µ in UTF-16
|
||||||
|
cp437_map[0xC2B5] = 0xE6; // µ in UTF-8
|
||||||
|
|
||||||
|
return cp437_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
String convertToCP437(const String& input) {
|
||||||
|
std::unordered_map<uint16_t, uint8_t> cp437_map = createUnicodeToCP437Map();
|
||||||
|
String output = "";
|
||||||
|
size_t len = input.length();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
char ch = input[i];
|
||||||
|
|
||||||
|
// UTF-8 detection: check for 3 byte UTF-8
|
||||||
|
if ((ch & 0xF0) == 0xE0) {
|
||||||
|
if (i + 2 < len) {
|
||||||
|
uint32_t utf8_char = ((uint8_t)input[i] << 16) | ((uint8_t)input[i + 1] << 8) | (uint8_t)input[i + 2];
|
||||||
|
i += 2; // skip 2 additional bytes
|
||||||
|
if (cp437_map.find(utf8_char) != cp437_map.end()) {
|
||||||
|
output += static_cast<char>(cp437_map[utf8_char]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// UTF-8 detection: check for 2 byte UTF-8
|
||||||
|
else if ((ch & 0xE0) == 0xC0) {
|
||||||
|
if (i + 1 < len) {
|
||||||
|
uint16_t utf8_char = ((uint8_t)input[i] << 8) | (uint8_t)input[i + 1];
|
||||||
|
i++; // skip second byte
|
||||||
|
if (cp437_map.find(utf8_char) != cp437_map.end()) {
|
||||||
|
output += static_cast<char>(cp437_map[utf8_char]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// single UTF-16 character (or plain ANSI character)
|
||||||
|
else if ((uint8_t)ch < 0x80) { // keep ASCII as is
|
||||||
|
output += ch;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint16_t utf16_char = (uint8_t)ch; // UTF-16 range
|
||||||
|
if (cp437_map.find(utf16_char) != cp437_map.end()) {
|
||||||
|
output += static_cast<char>(cp437_map[utf16_char]);
|
||||||
|
} else {
|
||||||
|
output += '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
String hexDump(String in) {
|
String hexDump(String in) {
|
||||||
String out;
|
String out;
|
||||||
for (size_t i = 0; i < in.length(); ++i) {
|
for (size_t i = 0; i < in.length(); ++i) {
|
||||||
@ -287,7 +363,6 @@ String hexDump(String in) {
|
|||||||
* - stay time: 4
|
* - stay time: 4
|
||||||
* - brightness: bright
|
* - brightness: bright
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void sendTextToSign(
|
void sendTextToSign(
|
||||||
const String &text,
|
const String &text,
|
||||||
const Method method = Method::Cyclic,
|
const Method method = Method::Cyclic,
|
||||||
@ -307,7 +382,9 @@ void sendTextToSign(
|
|||||||
|
|
||||||
Serial.println("Sending text: \"" + text + "\"");
|
Serial.println("Sending text: \"" + text + "\"");
|
||||||
|
|
||||||
String toSend = "~" + String(SIGN_ADDRESS, DEC) + "~f01" + (char) method + "\\" + (char) brightness + "\\Y" + String(speed, DEC) + "\\Z" + String(stayTime, DEC) + "\\" + (char) fontType + text + "\r\r\r";
|
String translatedText = convertToCP437(text);
|
||||||
|
|
||||||
|
String toSend = "~" + String(SIGN_ADDRESS, DEC) + "~f01" + (char) method + "\\" + (char) brightness + "\\Y" + String(speed, DEC) + "\\Z" + String(stayTime, DEC) + "\\" + (char) fontType + translatedText + "\r\r\r";
|
||||||
|
|
||||||
Serial1.print(toSend);
|
Serial1.print(toSend);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user