#ifdef MESHTASTIC_INCLUDE_INKHUD #include "./AppletFont.h" #include using namespace NicheGraphics; InkHUD::AppletFont::AppletFont() { // Default constructor uses the in-built AdafruitGFX font (not recommended) } InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont, Encoding encoding, int8_t paddingTop, int8_t paddingBottom) : gfxFont(&adafruitGFXFont), encoding(encoding) { // AdafruitGFX fonts are drawn relative to a "cursor line"; // they print as if the glyphs are resting on the line of piece of ruled paper. // The glyphs also each have a different height. // To simplify drawing, we will scan the entire font now, and determine an appropriate height for a line of text // We also need to know where that "cursor line" sits inside this "line height"; // we need this additional info in order to align text by top-left, bottom-right, etc // AdafruitGFX fonts do declare a line-height, but this seems to include a certain amount of padding, // which we'd rather not deal with. If we want padding, we'll add it manually. this->ascenderHeight = 0; this->descenderHeight = 0; this->height = 0; // Scan each glyph in the AdafruitGFX font for (uint16_t i = 0; i <= (gfxFont->last - gfxFont->first); i++) { uint8_t glyphHeight = gfxFont->glyph[i].height; // Height of glyph this->height = max(this->height, glyphHeight); // Store if it's a new max // Calculate how far the glyph rises the cursor line // Store if new max value // Caution: signed and unsigned types int8_t glyphAscender = 0 - gfxFont->glyph[i].yOffset; if (glyphAscender > 0) this->ascenderHeight = max(this->ascenderHeight, (uint8_t)glyphAscender); int8_t glyphDescender = gfxFont->glyph[i].height + gfxFont->glyph[i].yOffset; if (glyphDescender > 0) this->descenderHeight = max(this->descenderHeight, (uint8_t)glyphDescender); } // Apply any manual padding to grow or shrink the line size // Helpful if a font has one or two exceptionally large characters, which would make the lines ridiculously tall ascenderHeight += paddingTop; descenderHeight += paddingBottom; // Find how far the cursor advances when we "print" a space character spaceCharWidth = gfxFont->glyph[(uint8_t)' ' - gfxFont->first].xAdvance; } /* ▲ ##### # ▲ │ # # │ lineHeight │ ### # │ │ # # # # │ heightAboveCursor │ # # # # │ │ # # #### │ │ -----------------#---- │ # │ heightBelowCursor ▼ ### ▼ */ uint8_t InkHUD::AppletFont::lineHeight() { return this->height; } // AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper). // This value is the height of the font, above that imaginary line. // Used to calculate the true height of the font uint8_t InkHUD::AppletFont::heightAboveCursor() { return this->ascenderHeight; } // AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper). // This value is the height of the font, below that imaginary line. // Used to calculate the true height of the font uint8_t InkHUD::AppletFont::heightBelowCursor() { return this->descenderHeight; } // Width of the space character // Used with Applet::printWrapped uint8_t InkHUD::AppletFont::widthBetweenWords() { return this->spaceCharWidth; } // Convert a unicode char from set of UTF-8 bytes to UTF-32 // Used by AppletFont::applyEncoding, which remaps unicode chars for extended ASCII fonts, based on their UTF-32 value uint32_t InkHUD::AppletFont::toUtf32(std::string utf8) { uint32_t utf32 = 0; switch (utf8.length()) { case 2: // 5 bits + 6 bits utf32 |= (utf8.at(0) & 0b00011111) << 6; utf32 |= (utf8.at(1) & 0b00111111); break; case 3: // 4 bits + 6 bits + 6 bits utf32 |= (utf8.at(0) & 0b00001111) << (6 + 6); utf32 |= (utf8.at(1) & 0b00111111) << 6; utf32 |= (utf8.at(2) & 0b00111111); break; case 4: // 3 bits + 6 bits + 6 bits + 6 bits utf32 |= (utf8.at(0) & 0b00000111) << (6 + 6 + 6); utf32 |= (utf8.at(1) & 0b00111111) << (6 + 6); utf32 |= (utf8.at(2) & 0b00111111) << 6; utf32 |= (utf8.at(3) & 0b00111111); break; default: assert(false); } return utf32; } // Process a string, collating UTF-8 bytes, and sending them off for re-encoding to extended ASCII // Not all InkHUD text is passed through here, only text which could potentially contain non-ASCII chars std::string InkHUD::AppletFont::decodeUTF8(std::string encoded) { // Final processed output std::string decoded; // Holds bytes for one UTF-8 char during parsing std::string utf8Char; uint8_t utf8CharSize = 0; for (char &c : encoded) { // If first byte if (utf8Char.empty()) { // If MSB is unset, byte is an ASCII char // If MSB is set, byte is part of a UTF-8 char. Counting number of higher-order bits tells how many bytes in char if ((c & 0x80)) { char c1 = c; while (c1 & 0x80) { c1 <<= 1; utf8CharSize++; } } } // Append the byte to the UTF-8 char we're building utf8Char += c; // More bytes left to collect. Iterate. if (utf8Char.length() < utf8CharSize) continue; // Now collected all bytes for this char // Remap the value to match the encoding of our 8-bit AppletFont decoded += applyEncoding(utf8Char); // Reset, ready to build next UTF-8 char from the encoded bytes utf8Char.clear(); utf8CharSize = 0; } // For each char // All chars processed, return result return decoded; } // Re-encode a single UTF-8 character to extended ASCII // Target encoding depends on the font char InkHUD::AppletFont::applyEncoding(std::string utf8) { // ##################################################### Syntactic Sugar ##################################################### #define REMAP(in, out) \ case in: \ return out; // ########################################################################################################################### // Latin - Central Europe // https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT if (encoding == WINDOWS_1250) { // 1-Byte chars: no remapping if (utf8.length() == 1) return utf8.at(0); // Multi-byte chars: switch (toUtf32(utf8)) { REMAP(0x20AC, 0x80); // EURO SIGN REMAP(0x201A, 0x82); // SINGLE LOW-9 QUOTATION MARK REMAP(0x201E, 0x84); // DOUBLE LOW-9 QUOTATION MARK REMAP(0x2026, 0x85); // HORIZONTAL ELLIPSIS REMAP(0x2020, 0x86); // DAGGER REMAP(0x2021, 0x87); // DOUBLE DAGGER REMAP(0x2030, 0x89); // PER MILLE SIGN REMAP(0x0160, 0x8A); // LATIN CAPITAL LETTER S WITH CARON REMAP(0x2039, 0x8B); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK REMAP(0x015A, 0x8C); // LATIN CAPITAL LETTER S WITH ACUTE REMAP(0x0164, 0x8D); // LATIN CAPITAL LETTER T WITH CARON REMAP(0x017D, 0x8E); // LATIN CAPITAL LETTER Z WITH CARON REMAP(0x0179, 0x8F); // LATIN CAPITAL LETTER Z WITH ACUTE REMAP(0x2018, 0x91); // LEFT SINGLE QUOTATION MARK REMAP(0x2019, 0x92); // RIGHT SINGLE QUOTATION MARK REMAP(0x201C, 0x93); // LEFT DOUBLE QUOTATION MARK REMAP(0x201D, 0x94); // RIGHT DOUBLE QUOTATION MARK REMAP(0x2022, 0x95); // BULLET REMAP(0x2013, 0x96); // EN DASH REMAP(0x2014, 0x97); // EM DASH REMAP(0x2122, 0x99); // TRADE MARK SIGN REMAP(0x0161, 0x9A); // LATIN SMALL LETTER S WITH CARON REMAP(0x203A, 0x9B); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK REMAP(0x015B, 0x9C); // LATIN SMALL LETTER S WITH ACUTE REMAP(0x0165, 0x9D); // LATIN SMALL LETTER T WITH CARON REMAP(0x017E, 0x9E); // LATIN SMALL LETTER Z WITH CARON REMAP(0x017A, 0x9F); // LATIN SMALL LETTER Z WITH ACUTE REMAP(0x00A0, 0xA0); // NO-BREAK SPACE REMAP(0x02C7, 0xA1); // CARON REMAP(0x02D8, 0xA2); // BREVE REMAP(0x0141, 0xA3); // LATIN CAPITAL LETTER L WITH STROKE REMAP(0x00A4, 0xA4); // CURRENCY SIGN REMAP(0x0104, 0xA5); // LATIN CAPITAL LETTER A WITH OGONEK REMAP(0x00A6, 0xA6); // BROKEN BAR REMAP(0x00A7, 0xA7); // SECTION SIGN REMAP(0x00A8, 0xA8); // DIAERESIS REMAP(0x00A9, 0xA9); // COPYRIGHT SIGN REMAP(0x015E, 0xAA); // LATIN CAPITAL LETTER S WITH CEDILLA REMAP(0x00AB, 0xAB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK REMAP(0x00AC, 0xAC); // NOT SIGN REMAP(0x00AD, 0xAD); // SOFT HYPHEN REMAP(0x00AE, 0xAE); // REGISTERED SIGN REMAP(0x017B, 0xAF); // LATIN CAPITAL LETTER Z WITH DOT ABOVE REMAP(0x00B0, 0xB0); // DEGREE SIGN REMAP(0x00B1, 0xB1); // PLUS-MINUS SIGN REMAP(0x02DB, 0xB2); // OGONEK REMAP(0x0142, 0xB3); // LATIN SMALL LETTER L WITH STROKE REMAP(0x00B4, 0xB4); // ACUTE ACCENT REMAP(0x00B5, 0xB5); // MICRO SIGN REMAP(0x00B6, 0xB6); // PILCROW SIGN REMAP(0x00B7, 0xB7); // MIDDLE DOT REMAP(0x00B8, 0xB8); // CEDILLA REMAP(0x0105, 0xB9); // LATIN SMALL LETTER A WITH OGONEK REMAP(0x015F, 0xBA); // LATIN SMALL LETTER S WITH CEDILLA REMAP(0x00BB, 0xBB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK REMAP(0x013D, 0xBC); // LATIN CAPITAL LETTER L WITH CARON REMAP(0x02DD, 0xBD); // DOUBLE ACUTE ACCENT REMAP(0x013E, 0xBE); // LATIN SMALL LETTER L WITH CARON REMAP(0x017C, 0xBF); // LATIN SMALL LETTER Z WITH DOT ABOVE REMAP(0x0154, 0xC0); // LATIN CAPITAL LETTER R WITH ACUTE REMAP(0x00C1, 0xC1); // LATIN CAPITAL LETTER A WITH ACUTE REMAP(0x00C2, 0xC2); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX REMAP(0x0102, 0xC3); // LATIN CAPITAL LETTER A WITH BREVE REMAP(0x00C4, 0xC4); // LATIN CAPITAL LETTER A WITH DIAERESIS REMAP(0x0139, 0xC5); // LATIN CAPITAL LETTER L WITH ACUTE REMAP(0x0106, 0xC6); // LATIN CAPITAL LETTER C WITH ACUTE REMAP(0x00C7, 0xC7); // LATIN CAPITAL LETTER C WITH CEDILLA REMAP(0x010C, 0xC8); // LATIN CAPITAL LETTER C WITH CARON REMAP(0x00C9, 0xC9); // LATIN CAPITAL LETTER E WITH ACUTE REMAP(0x0118, 0xCA); // LATIN CAPITAL LETTER E WITH OGONEK REMAP(0x00CB, 0xCB); // LATIN CAPITAL LETTER E WITH DIAERESIS REMAP(0x011A, 0xCC); // LATIN CAPITAL LETTER E WITH CARON REMAP(0x00CD, 0xCD); // LATIN CAPITAL LETTER I WITH ACUTE REMAP(0x00CE, 0xCE); // LATIN CAPITAL LETTER I WITH CIRCUMFLEX REMAP(0x010E, 0xCF); // LATIN CAPITAL LETTER D WITH CARON REMAP(0x0110, 0xD0); // LATIN CAPITAL LETTER D WITH STROKE REMAP(0x0143, 0xD1); // LATIN CAPITAL LETTER N WITH ACUTE REMAP(0x0147, 0xD2); // LATIN CAPITAL LETTER N WITH CARON REMAP(0x00D3, 0xD3); // LATIN CAPITAL LETTER O WITH ACUTE REMAP(0x00D4, 0xD4); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX REMAP(0x0150, 0xD5); // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE REMAP(0x00D6, 0xD6); // LATIN CAPITAL LETTER O WITH DIAERESIS REMAP(0x00D7, 0xD7); // MULTIPLICATION SIGN REMAP(0x0158, 0xD8); // LATIN CAPITAL LETTER R WITH CARON REMAP(0x016E, 0xD9); // LATIN CAPITAL LETTER U WITH RING ABOVE REMAP(0x00DA, 0xDA); // LATIN CAPITAL LETTER U WITH ACUTE REMAP(0x0170, 0xDB); // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE REMAP(0x00DC, 0xDC); // LATIN CAPITAL LETTER U WITH DIAERESIS REMAP(0x00DD, 0xDD); // LATIN CAPITAL LETTER Y WITH ACUTE REMAP(0x0162, 0xDE); // LATIN CAPITAL LETTER T WITH CEDILLA REMAP(0x00DF, 0xDF); // LATIN SMALL LETTER SHARP S REMAP(0x0155, 0xE0); // LATIN SMALL LETTER R WITH ACUTE REMAP(0x00E1, 0xE1); // LATIN SMALL LETTER A WITH ACUTE REMAP(0x00E2, 0xE2); // LATIN SMALL LETTER A WITH CIRCUMFLEX REMAP(0x0103, 0xE3); // LATIN SMALL LETTER A WITH BREVE REMAP(0x00E4, 0xE4); // LATIN SMALL LETTER A WITH DIAERESIS REMAP(0x013A, 0xE5); // LATIN SMALL LETTER L WITH ACUTE REMAP(0x0107, 0xE6); // LATIN SMALL LETTER C WITH ACUTE REMAP(0x00E7, 0xE7); // LATIN SMALL LETTER C WITH CEDILLA REMAP(0x010D, 0xE8); // LATIN SMALL LETTER C WITH CARON REMAP(0x00E9, 0xE9); // LATIN SMALL LETTER E WITH ACUTE REMAP(0x0119, 0xEA); // LATIN SMALL LETTER E WITH OGONEK REMAP(0x00EB, 0xEB); // LATIN SMALL LETTER E WITH DIAERESIS REMAP(0x011B, 0xEC); // LATIN SMALL LETTER E WITH CARON REMAP(0x00ED, 0xED); // LATIN SMALL LETTER I WITH ACUTE REMAP(0x00EE, 0xEE); // LATIN SMALL LETTER I WITH CIRCUMFLEX REMAP(0x010F, 0xEF); // LATIN SMALL LETTER D WITH CARON REMAP(0x0111, 0xF0); // LATIN SMALL LETTER D WITH STROKE REMAP(0x0144, 0xF1); // LATIN SMALL LETTER N WITH ACUTE REMAP(0x0148, 0xF2); // LATIN SMALL LETTER N WITH CARON REMAP(0x00F3, 0xF3); // LATIN SMALL LETTER O WITH ACUTE REMAP(0x00F4, 0xF4); // LATIN SMALL LETTER O WITH CIRCUMFLEX REMAP(0x0151, 0xF5); // LATIN SMALL LETTER O WITH DOUBLE ACUTE REMAP(0x00F6, 0xF6); // LATIN SMALL LETTER O WITH DIAERESIS REMAP(0x00F7, 0xF7); // DIVISION SIGN REMAP(0x0159, 0xF8); // LATIN SMALL LETTER R WITH CARON REMAP(0x016F, 0xF9); // LATIN SMALL LETTER U WITH RING ABOVE REMAP(0x00FA, 0xFA); // LATIN SMALL LETTER U WITH ACUTE REMAP(0x0171, 0xFB); // LATIN SMALL LETTER U WITH DOUBLE ACUTE REMAP(0x00FC, 0xFC); // LATIN SMALL LETTER U WITH DIAERESIS REMAP(0x00FD, 0xFD); // LATIN SMALL LETTER Y WITH ACUTE REMAP(0x0163, 0xFE); // LATIN SMALL LETTER T WITH CEDILLA REMAP(0x02D9, 0xFF); // DOT ABOVE } } // Latin - Cyrillic // https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT else if (encoding == WINDOWS_1251) { // 1-Byte chars: no remapping if (utf8.length() == 1) return utf8.at(0); // Multi-byte chars: switch (toUtf32(utf8)) { REMAP(0x0402, 0x80); // CYRILLIC CAPITAL LETTER DJE REMAP(0x0403, 0x81); // CYRILLIC CAPITAL LETTER GJE REMAP(0x201A, 0x82); // SINGLE LOW-9 QUOTATION MARK REMAP(0x0453, 0x83); // CYRILLIC SMALL LETTER GJE REMAP(0x201E, 0x84); // DOUBLE LOW-9 QUOTATION MARK REMAP(0x2026, 0x85); // HORIZONTAL ELLIPSIS REMAP(0x2020, 0x86); // DAGGER REMAP(0x2021, 0x87); // DOUBLE DAGGER REMAP(0x20AC, 0x88); // EURO SIGN REMAP(0x2030, 0x89); // PER MILLE SIGN REMAP(0x0409, 0x8A); // CYRILLIC CAPITAL LETTER LJE REMAP(0x2039, 0x8B); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK REMAP(0x040A, 0x8C); // CYRILLIC CAPITAL LETTER NJE REMAP(0x040C, 0x8D); // CYRILLIC CAPITAL LETTER KJE REMAP(0x040B, 0x8E); // CYRILLIC CAPITAL LETTER TSHE REMAP(0x040F, 0x8F); // CYRILLIC CAPITAL LETTER DZHE REMAP(0x0452, 0x90); // CYRILLIC SMALL LETTER DJE REMAP(0x2018, 0x91); // LEFT SINGLE QUOTATION MARK REMAP(0x2019, 0x92); // RIGHT SINGLE QUOTATION MARK REMAP(0x201C, 0x93); // LEFT DOUBLE QUOTATION MARK REMAP(0x201D, 0x94); // RIGHT DOUBLE QUOTATION MARK REMAP(0x2022, 0x95); // BULLET REMAP(0x2013, 0x96); // EN DASH REMAP(0x2014, 0x97); // EM DASH REMAP(0x2122, 0x99); // TRADE MARK SIGN REMAP(0x0459, 0x9A); // CYRILLIC SMALL LETTER LJE REMAP(0x203A, 0x9B); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK REMAP(0x045A, 0x9C); // CYRILLIC SMALL LETTER NJE REMAP(0x045C, 0x9D); // CYRILLIC SMALL LETTER KJE REMAP(0x045B, 0x9E); // CYRILLIC SMALL LETTER TSHE REMAP(0x045F, 0x9F); // CYRILLIC SMALL LETTER DZHE REMAP(0x00A0, 0xA0); // NO-BREAK SPACE REMAP(0x040E, 0xA1); // CYRILLIC CAPITAL LETTER SHORT U REMAP(0x045E, 0xA2); // CYRILLIC SMALL LETTER SHORT U REMAP(0x0408, 0xA3); // CYRILLIC CAPITAL LETTER JE REMAP(0x00A4, 0xA4); // CURRENCY SIGN REMAP(0x0490, 0xA5); // CYRILLIC CAPITAL LETTER GHE WITH UPTURN REMAP(0x00A6, 0xA6); // BROKEN BAR REMAP(0x00A7, 0xA7); // SECTION SIGN REMAP(0x0401, 0xA8); // CYRILLIC CAPITAL LETTER IO REMAP(0x00A9, 0xA9); // COPYRIGHT SIGN REMAP(0x0404, 0xAA); // CYRILLIC CAPITAL LETTER UKRAINIAN IE REMAP(0x00AB, 0xAB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK REMAP(0x00AC, 0xAC); // NOT SIGN REMAP(0x00AD, 0xAD); // SOFT HYPHEN REMAP(0x00AE, 0xAE); // REGISTERED SIGN REMAP(0x0407, 0xAF); // CYRILLIC CAPITAL LETTER YI REMAP(0x00B0, 0xB0); // DEGREE SIGN REMAP(0x00B1, 0xB1); // PLUS-MINUS SIGN REMAP(0x0406, 0xB2); // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I REMAP(0x0456, 0xB3); // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I REMAP(0x0491, 0xB4); // CYRILLIC SMALL LETTER GHE WITH UPTURN REMAP(0x00B5, 0xB5); // MICRO SIGN REMAP(0x00B6, 0xB6); // PILCROW SIGN REMAP(0x00B7, 0xB7); // MIDDLE DOT REMAP(0x0451, 0xB8); // CYRILLIC SMALL LETTER IO REMAP(0x2116, 0xB9); // NUMERO SIGN REMAP(0x0454, 0xBA); // CYRILLIC SMALL LETTER UKRAINIAN IE REMAP(0x00BB, 0xBB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK REMAP(0x0458, 0xBC); // CYRILLIC SMALL LETTER JE REMAP(0x0405, 0xBD); // CYRILLIC CAPITAL LETTER DZE REMAP(0x0455, 0xBE); // CYRILLIC SMALL LETTER DZE REMAP(0x0457, 0xBF); // CYRILLIC SMALL LETTER YI REMAP(0x0410, 0xC0); // CYRILLIC CAPITAL LETTER A REMAP(0x0411, 0xC1); // CYRILLIC CAPITAL LETTER BE REMAP(0x0412, 0xC2); // CYRILLIC CAPITAL LETTER VE REMAP(0x0413, 0xC3); // CYRILLIC CAPITAL LETTER GHE REMAP(0x0414, 0xC4); // CYRILLIC CAPITAL LETTER DE REMAP(0x0415, 0xC5); // CYRILLIC CAPITAL LETTER IE REMAP(0x0416, 0xC6); // CYRILLIC CAPITAL LETTER ZHE REMAP(0x0417, 0xC7); // CYRILLIC CAPITAL LETTER ZE REMAP(0x0418, 0xC8); // CYRILLIC CAPITAL LETTER I REMAP(0x0419, 0xC9); // CYRILLIC CAPITAL LETTER SHORT I REMAP(0x041A, 0xCA); // CYRILLIC CAPITAL LETTER KA REMAP(0x041B, 0xCB); // CYRILLIC CAPITAL LETTER EL REMAP(0x041C, 0xCC); // CYRILLIC CAPITAL LETTER EM REMAP(0x041D, 0xCD); // CYRILLIC CAPITAL LETTER EN REMAP(0x041E, 0xCE); // CYRILLIC CAPITAL LETTER O REMAP(0x041F, 0xCF); // CYRILLIC CAPITAL LETTER PE REMAP(0x0420, 0xD0); // CYRILLIC CAPITAL LETTER ER REMAP(0x0421, 0xD1); // CYRILLIC CAPITAL LETTER ES REMAP(0x0422, 0xD2); // CYRILLIC CAPITAL LETTER TE REMAP(0x0423, 0xD3); // CYRILLIC CAPITAL LETTER U REMAP(0x0424, 0xD4); // CYRILLIC CAPITAL LETTER EF REMAP(0x0425, 0xD5); // CYRILLIC CAPITAL LETTER HA REMAP(0x0426, 0xD6); // CYRILLIC CAPITAL LETTER TSE REMAP(0x0427, 0xD7); // CYRILLIC CAPITAL LETTER CHE REMAP(0x0428, 0xD8); // CYRILLIC CAPITAL LETTER SHA REMAP(0x0429, 0xD9); // CYRILLIC CAPITAL LETTER SHCHA REMAP(0x042A, 0xDA); // CYRILLIC CAPITAL LETTER HARD SIGN REMAP(0x042B, 0xDB); // CYRILLIC CAPITAL LETTER YERU REMAP(0x042C, 0xDC); // CYRILLIC CAPITAL LETTER SOFT SIGN REMAP(0x042D, 0xDD); // CYRILLIC CAPITAL LETTER E REMAP(0x042E, 0xDE); // CYRILLIC CAPITAL LETTER YU REMAP(0x042F, 0xDF); // CYRILLIC CAPITAL LETTER YA REMAP(0x0430, 0xE0); // CYRILLIC SMALL LETTER A REMAP(0x0431, 0xE1); // CYRILLIC SMALL LETTER BE REMAP(0x0432, 0xE2); // CYRILLIC SMALL LETTER VE REMAP(0x0433, 0xE3); // CYRILLIC SMALL LETTER GHE REMAP(0x0434, 0xE4); // CYRILLIC SMALL LETTER DE REMAP(0x0435, 0xE5); // CYRILLIC SMALL LETTER IE REMAP(0x0436, 0xE6); // CYRILLIC SMALL LETTER ZHE REMAP(0x0437, 0xE7); // CYRILLIC SMALL LETTER ZE REMAP(0x0438, 0xE8); // CYRILLIC SMALL LETTER I REMAP(0x0439, 0xE9); // CYRILLIC SMALL LETTER SHORT I REMAP(0x043A, 0xEA); // CYRILLIC SMALL LETTER KA REMAP(0x043B, 0xEB); // CYRILLIC SMALL LETTER EL REMAP(0x043C, 0xEC); // CYRILLIC SMALL LETTER EM REMAP(0x043D, 0xED); // CYRILLIC SMALL LETTER EN REMAP(0x043E, 0xEE); // CYRILLIC SMALL LETTER O REMAP(0x043F, 0xEF); // CYRILLIC SMALL LETTER PE REMAP(0x0440, 0xF0); // CYRILLIC SMALL LETTER ER REMAP(0x0441, 0xF1); // CYRILLIC SMALL LETTER ES REMAP(0x0442, 0xF2); // CYRILLIC SMALL LETTER TE REMAP(0x0443, 0xF3); // CYRILLIC SMALL LETTER U REMAP(0x0444, 0xF4); // CYRILLIC SMALL LETTER EF REMAP(0x0445, 0xF5); // CYRILLIC SMALL LETTER HA REMAP(0x0446, 0xF6); // CYRILLIC SMALL LETTER TSE REMAP(0x0447, 0xF7); // CYRILLIC SMALL LETTER CHE REMAP(0x0448, 0xF8); // CYRILLIC SMALL LETTER SHA REMAP(0x0449, 0xF9); // CYRILLIC SMALL LETTER SHCHA REMAP(0x044A, 0xFA); // CYRILLIC SMALL LETTER HARD SIGN REMAP(0x044B, 0xFB); // CYRILLIC SMALL LETTER YERU REMAP(0x044C, 0xFC); // CYRILLIC SMALL LETTER SOFT SIGN REMAP(0x044D, 0xFD); // CYRILLIC SMALL LETTER E REMAP(0x044E, 0xFE); // CYRILLIC SMALL LETTER YU REMAP(0x044F, 0xFF); // CYRILLIC SMALL LETTER YA } } // Latin - Western Europe // https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT else if (encoding == WINDOWS_1252) { // 1-Byte chars: no remapping if (utf8.length() == 1) return utf8.at(0); // Multi-byte chars: switch (toUtf32(utf8)) { REMAP(0x20AC, 0x80) // EURO SIGN REMAP(0x201A, 0x82) // SINGLE LOW-9 QUOTATION MARK REMAP(0x0192, 0x83) // LATIN SMALL LETTER F WITH HOOK REMAP(0x201E, 0x84) // DOUBLE LOW-9 QUOTATION MARK REMAP(0x2026, 0x85) // HORIZONTAL ELLIPSIS REMAP(0x2020, 0x86) // DAGGER REMAP(0x2021, 0x87) // DOUBLE DAGGER REMAP(0x02C6, 0x88) // MODIFIER LETTER CIRCUMFLEX ACCENT REMAP(0x2030, 0x89) // PER MILLE SIGN REMAP(0x0160, 0x8A) // LATIN CAPITAL LETTER S WITH CARON REMAP(0x2039, 0x8B) // SINGLE LEFT-POINTING ANGLE QUOTATION MARK REMAP(0x0152, 0x8C) // LATIN CAPITAL LIGATURE OE REMAP(0x017D, 0x8E) // LATIN CAPITAL LETTER Z WITH CARON REMAP(0x2018, 0x91) // LEFT SINGLE QUOTATION MARK REMAP(0x2019, 0x92) // RIGHT SINGLE QUOTATION MARK REMAP(0x201C, 0x93) // LEFT DOUBLE QUOTATION MARK REMAP(0x201D, 0x94) // RIGHT DOUBLE QUOTATION MARK REMAP(0x2022, 0x95) // BULLET REMAP(0x2013, 0x96) // EN DASH REMAP(0x2014, 0x97) // EM DASH REMAP(0x02DC, 0x98) // SMALL TILDE REMAP(0x2122, 0x99) // TRADE MARK SIGN REMAP(0x0161, 0x9A) // LATIN SMALL LETTER S WITH CARON REMAP(0x203A, 0x9B) // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK REMAP(0x0153, 0x9C) // LATIN SMALL LIGATURE OE REMAP(0x017E, 0x9E) // LATIN SMALL LETTER Z WITH CARON REMAP(0x0178, 0x9F) // LATIN CAPITAL LETTER Y WITH DIAERESIS REMAP(0x00A0, 0xA0) // NO-BREAK SPACE REMAP(0x00A1, 0xA1) // INVERTED EXCLAMATION MARK REMAP(0x00A2, 0xA2) // CENT SIGN REMAP(0x00A3, 0xA3) // POUND SIGN REMAP(0x00A4, 0xA4) // CURRENCY SIGN REMAP(0x00A5, 0xA5) // YEN SIGN REMAP(0x00A6, 0xA6) // BROKEN BAR REMAP(0x00A7, 0xA7) // SECTION SIGN REMAP(0x00A8, 0xA8) // DIAERESIS REMAP(0x00A9, 0xA9) // COPYRIGHT SIGN REMAP(0x00AA, 0xAA) // FEMININE ORDINAL INDICATOR REMAP(0x00AB, 0xAB) // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK REMAP(0x00AC, 0xAC) // NOT SIGN REMAP(0x00AD, 0xAD) // SOFT HYPHEN REMAP(0x00AE, 0xAE) // REGISTERED SIGN REMAP(0x00AF, 0xAF) // MACRON REMAP(0x00B0, 0xB0) // DEGREE SIGN REMAP(0x00B1, 0xB1) // PLUS-MINUS SIGN REMAP(0x00B2, 0xB2) // SUPERSCRIPT TWO REMAP(0x00B3, 0xB3) // SUPERSCRIPT THREE REMAP(0x00B4, 0xB4) // ACUTE ACCENT REMAP(0x00B5, 0xB5) // MICRO SIGN REMAP(0x00B6, 0xB6) // PILCROW SIGN REMAP(0x00B7, 0xB7) // MIDDLE DOT REMAP(0x00B8, 0xB8) // CEDILLA REMAP(0x00B9, 0xB9) // SUPERSCRIPT ONE REMAP(0x00BA, 0xBA) // MASCULINE ORDINAL INDICATOR REMAP(0x00BB, 0xBB) // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK REMAP(0x00BC, 0xBC) // VULGAR FRACTION ONE QUARTER REMAP(0x00BD, 0xBD) // VULGAR FRACTION ONE HALF REMAP(0x00BE, 0xBE) // VULGAR FRACTION THREE QUARTERS REMAP(0x00BF, 0xBF) // INVERTED QUESTION MARK REMAP(0x00C0, 0xC0) // LATIN CAPITAL LETTER A WITH GRAVE REMAP(0x00C1, 0xC1) // LATIN CAPITAL LETTER A WITH ACUTE REMAP(0x00C2, 0xC2) // LATIN CAPITAL LETTER A WITH CIRCUMFLEX REMAP(0x00C3, 0xC3) // LATIN CAPITAL LETTER A WITH TILDE REMAP(0x00C4, 0xC4) // LATIN CAPITAL LETTER A WITH DIAERESIS REMAP(0x00C5, 0xC5) // LATIN CAPITAL LETTER A WITH RING ABOVE REMAP(0x00C6, 0xC6) // LATIN CAPITAL LETTER AE REMAP(0x00C7, 0xC7) // LATIN CAPITAL LETTER C WITH CEDILLA REMAP(0x00C8, 0xC8) // LATIN CAPITAL LETTER E WITH GRAVE REMAP(0x00C9, 0xC9) // LATIN CAPITAL LETTER E WITH ACUTE REMAP(0x00CA, 0xCA) // LATIN CAPITAL LETTER E WITH CIRCUMFLEX REMAP(0x00CB, 0xCB) // LATIN CAPITAL LETTER E WITH DIAERESIS REMAP(0x00CC, 0xCC) // LATIN CAPITAL LETTER I WITH GRAVE REMAP(0x00CD, 0xCD) // LATIN CAPITAL LETTER I WITH ACUTE REMAP(0x00CE, 0xCE) // LATIN CAPITAL LETTER I WITH CIRCUMFLEX REMAP(0x00CF, 0xCF) // LATIN CAPITAL LETTER I WITH DIAERESIS REMAP(0x00D0, 0xD0) // LATIN CAPITAL LETTER ETH REMAP(0x00D1, 0xD1) // LATIN CAPITAL LETTER N WITH TILDE REMAP(0x00D2, 0xD2) // LATIN CAPITAL LETTER O WITH GRAVE REMAP(0x00D3, 0xD3) // LATIN CAPITAL LETTER O WITH ACUTE REMAP(0x00D4, 0xD4) // LATIN CAPITAL LETTER O WITH CIRCUMFLEX REMAP(0x00D5, 0xD5) // LATIN CAPITAL LETTER O WITH TILDE REMAP(0x00D6, 0xD6) // LATIN CAPITAL LETTER O WITH DIAERESIS REMAP(0x00D7, 0xD7) // MULTIPLICATION SIGN REMAP(0x00D8, 0xD8) // LATIN CAPITAL LETTER O WITH STROKE REMAP(0x00D9, 0xD9) // LATIN CAPITAL LETTER U WITH GRAVE REMAP(0x00DA, 0xDA) // LATIN CAPITAL LETTER U WITH ACUTE REMAP(0x00DB, 0xDB) // LATIN CAPITAL LETTER U WITH CIRCUMFLEX REMAP(0x00DC, 0xDC) // LATIN CAPITAL LETTER U WITH DIAERESIS REMAP(0x00DD, 0xDD) // LATIN CAPITAL LETTER Y WITH ACUTE REMAP(0x00DE, 0xDE) // LATIN CAPITAL LETTER THORN REMAP(0x00DF, 0xDF) // LATIN SMALL LETTER SHARP S REMAP(0x00E0, 0xE0) // LATIN SMALL LETTER A WITH GRAVE REMAP(0x00E1, 0xE1) // LATIN SMALL LETTER A WITH ACUTE REMAP(0x00E2, 0xE2) // LATIN SMALL LETTER A WITH CIRCUMFLEX REMAP(0x00E3, 0xE3) // LATIN SMALL LETTER A WITH TILDE REMAP(0x00E4, 0xE4) // LATIN SMALL LETTER A WITH DIAERESIS REMAP(0x00E5, 0xE5) // LATIN SMALL LETTER A WITH RING ABOVE REMAP(0x00E6, 0xE6) // LATIN SMALL LETTER AE REMAP(0x00E7, 0xE7) // LATIN SMALL LETTER C WITH CEDILLA REMAP(0x00E8, 0xE8) // LATIN SMALL LETTER E WITH GRAVE REMAP(0x00E9, 0xE9) // LATIN SMALL LETTER E WITH ACUTE REMAP(0x00EA, 0xEA) // LATIN SMALL LETTER E WITH CIRCUMFLEX REMAP(0x00EB, 0xEB) // LATIN SMALL LETTER E WITH DIAERESIS REMAP(0x00EC, 0xEC) // LATIN SMALL LETTER I WITH GRAVE REMAP(0x00ED, 0xED) // LATIN SMALL LETTER I WITH ACUTE REMAP(0x00EE, 0xEE) // LATIN SMALL LETTER I WITH CIRCUMFLEX REMAP(0x00EF, 0xEF) // LATIN SMALL LETTER I WITH DIAERESIS REMAP(0x00F0, 0xF0) // LATIN SMALL LETTER ETH REMAP(0x00F1, 0xF1) // LATIN SMALL LETTER N WITH TILDE REMAP(0x00F2, 0xF2) // LATIN SMALL LETTER O WITH GRAVE REMAP(0x00F3, 0xF3) // LATIN SMALL LETTER O WITH ACUTE REMAP(0x00F4, 0xF4) // LATIN SMALL LETTER O WITH CIRCUMFLEX REMAP(0x00F5, 0xF5) // LATIN SMALL LETTER O WITH TILDE REMAP(0x00F6, 0xF6) // LATIN SMALL LETTER O WITH DIAERESIS REMAP(0x00F7, 0xF7) // DIVISION SIGN REMAP(0x00F8, 0xF8) // LATIN SMALL LETTER O WITH STROKE REMAP(0x00F9, 0xF9) // LATIN SMALL LETTER U WITH GRAVE REMAP(0x00FA, 0xFA) // LATIN SMALL LETTER U WITH ACUTE REMAP(0x00FB, 0xFB) // LATIN SMALL LETTER U WITH CIRCUMFLEX REMAP(0x00FC, 0xFC) // LATIN SMALL LETTER U WITH DIAERESIS REMAP(0x00FD, 0xFD) // LATIN SMALL LETTER Y WITH ACUTE REMAP(0x00FE, 0xFE) // LATIN SMALL LETTER THORN REMAP(0x00FF, 0xFF) // LATIN SMALL LETTER Y WITH DIAERESIS } } // If not handled, return DEL // Todo: swap this to SUB, and modify the fonts return '\x7F'; // Sweep up the syntactic sugar // Don't want ants in the house #undef REMAP } #endif