mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 23:08:11 +00:00
perf(ui): replace transliterateCodepoint switch with sorted-table binary search
Old 80+ case switch generated a jump table around ~600-1200 B of flash; new layout is two parallel static-const arrays (uint16 codepoint + char ascii, 144 entries each = 432 B) and a 5-line bsearch loop. Same input range, same output, faster lookup (~log2(144) ≈ 7 compares vs jump-table indirection + bounds check). Adds a static_assert that the two arrays stay in sync. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -70,87 +70,63 @@ public:
|
||||
print(tmp);
|
||||
}
|
||||
|
||||
// Sorted-codepoint → ASCII transliteration table.
|
||||
// Binary search beats a ~110-case switch on flash (parallel arrays = 3 bytes/entry,
|
||||
// no padding) and gives O(log n) lookup. Covers Latin Extended A/B + common
|
||||
// Latin-1 accented diacritics needed by EU languages and Turkish.
|
||||
static char transliterateCodepoint(uint32_t cp) {
|
||||
switch (cp) {
|
||||
// Polish
|
||||
case 0x0105: return 'a'; case 0x0104: return 'A'; // ą Ą
|
||||
case 0x0107: return 'c'; case 0x0106: return 'C'; // ć Ć
|
||||
case 0x0119: return 'e'; case 0x0118: return 'E'; // ę Ę
|
||||
case 0x0142: return 'l'; case 0x0141: return 'L'; // ł Ł
|
||||
case 0x0144: return 'n'; case 0x0143: return 'N'; // ń Ń
|
||||
case 0x00F3: return 'o'; case 0x00D3: return 'O'; // ó Ó
|
||||
case 0x015B: return 's'; case 0x015A: return 'S'; // ś Ś
|
||||
case 0x017A: return 'z'; case 0x0179: return 'Z'; // ź Ź
|
||||
case 0x017C: return 'z'; case 0x017B: return 'Z'; // ż Ż
|
||||
// Czech/Slovak
|
||||
case 0x010D: return 'c'; case 0x010C: return 'C'; // č Č
|
||||
case 0x0161: return 's'; case 0x0160: return 'S'; // š Š
|
||||
case 0x017E: return 'z'; case 0x017D: return 'Z'; // ž Ž
|
||||
case 0x0159: return 'r'; case 0x0158: return 'R'; // ř Ř
|
||||
case 0x011B: return 'e'; case 0x011A: return 'E'; // ě Ě
|
||||
case 0x016F: return 'u'; case 0x016E: return 'U'; // ů Ů
|
||||
case 0x010F: return 'd'; case 0x010E: return 'D'; // ď Ď
|
||||
case 0x0165: return 't'; case 0x0164: return 'T'; // ť Ť
|
||||
case 0x0148: return 'n'; case 0x0147: return 'N'; // ň Ň
|
||||
case 0x013E: return 'l'; case 0x013D: return 'L'; // ľ Ľ
|
||||
case 0x013A: return 'l'; case 0x0139: return 'L'; // ĺ Ĺ
|
||||
case 0x0155: return 'r'; case 0x0154: return 'R'; // ŕ Ŕ
|
||||
// German
|
||||
case 0x00E4: return 'a'; case 0x00C4: return 'A'; // ä Ä
|
||||
case 0x00F6: return 'o'; case 0x00D6: return 'O'; // ö Ö
|
||||
case 0x00FC: return 'u'; case 0x00DC: return 'U'; // ü Ü
|
||||
case 0x00DF: return 's'; // ß
|
||||
// Scandinavian
|
||||
case 0x00E5: return 'a'; case 0x00C5: return 'A'; // å Å
|
||||
case 0x00F8: return 'o'; case 0x00D8: return 'O'; // ø Ø
|
||||
case 0x00E6: return 'a'; case 0x00C6: return 'A'; // æ Æ
|
||||
// Hungarian
|
||||
case 0x0151: return 'o'; case 0x0150: return 'O'; // ő Ő
|
||||
case 0x0171: return 'u'; case 0x0170: return 'U'; // ű Ű
|
||||
// Romanian
|
||||
case 0x0103: return 'a'; case 0x0102: return 'A'; // ă Ă
|
||||
case 0x0219: return 's'; case 0x0218: return 'S'; // ș Ș
|
||||
case 0x021B: return 't'; case 0x021A: return 'T'; // ț Ț
|
||||
// Croatian
|
||||
case 0x0111: return 'd'; case 0x0110: return 'D'; // đ Đ
|
||||
// Icelandic
|
||||
case 0x00F0: return 'd'; case 0x00D0: return 'D'; // ð Ð (eth)
|
||||
case 0x00FE: return 't'; case 0x00DE: return 'T'; // þ Þ (thorn)
|
||||
// Romanian cedilla variants (legacy encoding)
|
||||
case 0x0163: return 't'; case 0x0162: return 'T'; // ţ Ţ
|
||||
// Turkish
|
||||
case 0x011F: return 'g'; case 0x011E: return 'G'; // ğ Ğ
|
||||
case 0x015F: return 's'; case 0x015E: return 'S'; // ş Ş
|
||||
case 0x0131: return 'i'; // ı
|
||||
// Baltic (Lithuanian/Latvian)
|
||||
case 0x0101: return 'a'; case 0x0100: return 'A'; // ā Ā
|
||||
case 0x0113: return 'e'; case 0x0112: return 'E'; // ē Ē
|
||||
case 0x012B: return 'i'; case 0x012A: return 'I'; // ī Ī
|
||||
case 0x016B: return 'u'; case 0x016A: return 'U'; // ū Ū
|
||||
case 0x0123: return 'g'; case 0x0122: return 'G'; // ģ Ģ
|
||||
case 0x0137: return 'k'; case 0x0136: return 'K'; // ķ Ķ
|
||||
case 0x013C: return 'l'; case 0x013B: return 'L'; // ļ Ļ
|
||||
case 0x0146: return 'n'; case 0x0145: return 'N'; // ņ Ņ
|
||||
case 0x0157: return 'r'; case 0x0156: return 'R'; // ŗ Ŗ
|
||||
case 0x0173: return 'u'; case 0x0172: return 'U'; // ų Ų
|
||||
case 0x0117: return 'e'; case 0x0116: return 'E'; // ė Ė
|
||||
case 0x012F: return 'i'; case 0x012E: return 'I'; // į Į
|
||||
// French/Spanish/Portuguese common accents
|
||||
case 0x00E0: case 0x00E1: case 0x00E2: case 0x00E3: return 'a';
|
||||
case 0x00C0: case 0x00C1: case 0x00C2: case 0x00C3: return 'A';
|
||||
case 0x00E8: case 0x00E9: case 0x00EA: case 0x00EB: return 'e';
|
||||
case 0x00C8: case 0x00C9: case 0x00CA: case 0x00CB: return 'E';
|
||||
case 0x00EC: case 0x00ED: case 0x00EE: case 0x00EF: return 'i';
|
||||
case 0x00CC: case 0x00CD: case 0x00CE: case 0x00CF: return 'I';
|
||||
case 0x00F2: case 0x00F4: case 0x00F5: return 'o';
|
||||
case 0x00D2: case 0x00D4: case 0x00D5: return 'O';
|
||||
case 0x00F9: case 0x00FA: case 0x00FB: return 'u';
|
||||
case 0x00D9: case 0x00DA: case 0x00DB: return 'U';
|
||||
case 0x00E7: return 'c'; case 0x00C7: return 'C'; // ç Ç
|
||||
case 0x00F1: return 'n'; case 0x00D1: return 'N'; // ñ Ñ
|
||||
case 0x00FD: return 'y'; case 0x00DD: return 'Y'; // ý Ý
|
||||
default: return '\xDB';
|
||||
// Codepoints must stay sorted ascending — binary search assumes it.
|
||||
static const uint16_t CPS[] = {
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D8,
|
||||
0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F8,
|
||||
0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE,
|
||||
0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
|
||||
0x010C, 0x010D, 0x010E, 0x010F, 0x0110, 0x0111, 0x0112, 0x0113,
|
||||
0x0116, 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011E, 0x011F,
|
||||
0x0122, 0x0123, 0x012A, 0x012B, 0x012E, 0x012F, 0x0131,
|
||||
0x0136, 0x0137, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E,
|
||||
0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, 0x0148,
|
||||
0x0150, 0x0151, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159,
|
||||
0x015A, 0x015B, 0x015E, 0x015F, 0x0160, 0x0161, 0x0162, 0x0163,
|
||||
0x0164, 0x0165, 0x016A, 0x016B, 0x016E, 0x016F, 0x0170, 0x0171,
|
||||
0x0172, 0x0173, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E,
|
||||
0x0218, 0x0219, 0x021A, 0x021B
|
||||
};
|
||||
static const char ASCII[] = {
|
||||
'A','A','A','A','A','A','A','C',
|
||||
'E','E','E','E','I','I','I','I',
|
||||
'D','N','O','O','O','O','O','O',
|
||||
'U','U','U','U','Y','T','s',
|
||||
'a','a','a','a','a','a','a','c',
|
||||
'e','e','e','e','i','i','i','i',
|
||||
'd','n','o','o','o','o','o','o',
|
||||
'u','u','u','u','y','t',
|
||||
'A','a','A','a','A','a','C','c',
|
||||
'C','c','D','d','D','d','E','e',
|
||||
'E','e','E','e','E','e','G','g',
|
||||
'G','g','I','i','I','i','i',
|
||||
'K','k','L','l','L','l','L','l',
|
||||
'L','l','N','n','N','n','N','n',
|
||||
'O','o','R','r','R','r','R','r',
|
||||
'S','s','S','s','S','s','T','t',
|
||||
'T','t','U','u','U','u','U','u',
|
||||
'U','u','Z','z','Z','z','Z','z',
|
||||
'S','s','T','t'
|
||||
};
|
||||
static_assert(sizeof(CPS) / sizeof(CPS[0]) == sizeof(ASCII), "transliteration tables out of sync");
|
||||
int lo = 0, hi = (int)(sizeof(ASCII)) - 1;
|
||||
while (lo <= hi) {
|
||||
int mid = (lo + hi) >> 1;
|
||||
uint16_t v = CPS[mid];
|
||||
if (v == cp) return ASCII[mid];
|
||||
if (v < cp) lo = mid + 1; else hi = mid - 1;
|
||||
}
|
||||
return '\xDB';
|
||||
}
|
||||
|
||||
// convert UTF-8 to ASCII, transliterating accented/diacritic characters (callable without a display instance)
|
||||
|
||||
Reference in New Issue
Block a user