feat: enable Companion simulator to switch UI language at runtime (#6510)
This commit is contained in:
@@ -25,148 +25,146 @@
|
||||
#include "definitions.h"
|
||||
#include "translations/translations.h"
|
||||
|
||||
#define FR_LUT L'é', L'è', L'à', L'î', L'ç'
|
||||
#define FR_SUB_LUT L'Â', L'A', L'À', L'A', L'Ê', L'E', L'É', L'E', L'È', L'E'
|
||||
#define DA_LUT L'å', L'æ', L'ø', L'Å', L'Æ', L'Ø'
|
||||
#define DE_LUT L'Ä', L'ä', L'Ö', L'ö', L'Ü', L'ü', L'ß'
|
||||
#define CZ_LUT L'á', L'č', L'é', L'ě', L'í', L'ó', L'ř', L'š', L'ú', L'ů', L'ý', L'Á', L'Í', L'Ř', L'Ý', L'ž', L'É', L'ň'
|
||||
#define CZ_SUB_LUT L'Ě', L'ě', L'Š', L'š', L'Č', L'č', L'Ž', L'ž', L'Ú', L'ú', L'Ů', L'ů', L'Ó', L'ó', L'Ň', L'ň'
|
||||
#define ES_LUT L'Ñ', L'ñ', L'Á', L'á', L'É', L'é', L'Í', L'í', L'Ó', L'ó', L'ú'
|
||||
#define PT_LUT L'Á', L'á', L'Â', L'â', L'Ã', L'ã', L'À', L'à', L'Ç', L'ç', L'É', L'é', L'Ê', L'ê', L'Í', L'í', L'Ó', L'ó', L'Ô', L'ô', L'Õ', L'õ', L'Ú', L'ú'
|
||||
#define FI_LUT L'å', L'ä', L'ö', L'Å', L'Ä', L'Ö'
|
||||
#define IT_LUT L'à', L'ù'
|
||||
#define PL_LUT L'ą', L'ć', L'ę', L'ł', L'ń', L'ó', L'ś', L'ż', L'ź', L'Ą', L'Ć', L'Ę', L'Ł', L'Ń', L'Ó', L'Ś', L'Ż', L'Ź'
|
||||
#define RU_LUT L'А', L'Б', L'В', L'Г', L'Д', L'Е', L'Ж', L'З', L'И', L'Й', L'К', L'Л', L'М', L'Н', \
|
||||
L'О', L'П', L'Р', L'С', L'Т', L'У', L'Ф', L'Х', L'Ц', L'Ч', L'Ш', L'Щ', L'Ъ', L'Ы', \
|
||||
L'Ь', L'Э', L'Ю', L'Я', L'а', L'б', L'в', L'г', L'д', L'е', L'ж', L'з', L'и', L'й', \
|
||||
L'к', L'л', L'м', L'н', L'о', L'п', L'р', L'с', L'т', L'у', L'ф', L'х', L'ц', L'ч', \
|
||||
L'ш', L'щ', L'ъ', L'ы', L'ь', L'э', L'ю', L'я'
|
||||
#define UA_LUT L'Б', L'Г', L'Ґ', L'Д', L'Є', L'Ж', L'З', L'И', L'Ї', L'Й', L'Л', L'П', L'У', L'Ф', \
|
||||
L'Ц', L'Ч', L'Ш', L'Щ', L'Ь', L'Ю', L'Я', L'б', L'в', L'г', L'ґ', L'д', L'є', L'ж', \
|
||||
L'з', L'и', L'ї', L'й', L'к', L'л', L'м', L'н', L'п', L'т', L'ф', L'ц', L'ч', L'ш', \
|
||||
L'щ', L'ь', L'ю', L'я'
|
||||
#define UA_SUB_LUT L'А', L'A', L'а', L'a', L'В', L'B', L'С', L'C', L'с', L'c', L'Е', L'E', L'е', L'e', L'Н', L'H', \
|
||||
L'К', L'K', L'М', L'M', L'І', L'I', L'і', L'i', L'О', L'O', L'о', L'o', L'о', L'o', L'Р', L'P', \
|
||||
L'р', L'p', L'Т', L'T', L'Х', L'X', L'х', L'x', L'у', L'y'
|
||||
#define SE_LUT L'å', L'ä', L'ö', L'Å', L'Ä', L'Ö'
|
||||
|
||||
#if !defined(ALL_LANGS) || defined(BOOT)
|
||||
|
||||
#if defined(TRANSLATIONS_FR)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'é', L'è', L'à', L'î', L'ç',
|
||||
};
|
||||
|
||||
static const uint16_t _utf8_lut[] = { FR_LUT };
|
||||
#define UTF8_SUBS_LUT
|
||||
static uint16_t _utf8_substitution_lut[] = {
|
||||
L'Â', L'A',
|
||||
L'À', L'A',
|
||||
L'Ê', L'E',
|
||||
L'É', L'E',
|
||||
L'È', L'E',
|
||||
/* Existing but virtually unsused
|
||||
L'Ä', L'A',
|
||||
L'Ë', L'E',
|
||||
L'Ï', L'I',
|
||||
L'Ö', L'O',
|
||||
L'Ü', L'U',
|
||||
L'Û', L'U',
|
||||
L'Ù', L'U',
|
||||
*/
|
||||
};
|
||||
static const uint16_t _utf8_substitution_lut[] = { FR_SUB_LUT };
|
||||
#elif defined(TRANSLATIONS_DA)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'å', L'æ', L'ø', L'Å', L'Æ', L'Ø',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { DA_LUT };
|
||||
#elif defined(TRANSLATIONS_DE)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'Ä', L'ä', L'Ö', L'ö', L'Ü', L'ü', L'ß',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { DE_LUT };
|
||||
#elif defined(TRANSLATIONS_CZ)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'á', L'č', L'é', L'ě', L'í', L'ó', L'ř',
|
||||
L'š', L'ú', L'ů', L'ý', L'Á', L'Í', L'Ř',
|
||||
L'Ý', L'ž', L'É', L'ň',
|
||||
};
|
||||
|
||||
static const uint16_t _utf8_lut[] = { CZ_LUT };
|
||||
#define UTF8_SUBS_LUT
|
||||
static uint16_t _utf8_substitution_lut[] = {
|
||||
L'Ě', L'ě',
|
||||
L'Š', L'š',
|
||||
L'Č', L'č',
|
||||
L'Ž', L'ž',
|
||||
L'Ú', L'ú',
|
||||
L'Ů', L'ů',
|
||||
L'Ó', L'ó',
|
||||
L'Ň', L'ň',
|
||||
};
|
||||
static const uint16_t _utf8_substitution_lut[] = { CZ_SUB_LUT };
|
||||
#elif defined(TRANSLATIONS_ES) && !defined(BOOT)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'Ñ', L'ñ', L'Á', L'á', L'É', L'é', L'Í',
|
||||
L'í', L'Ó', L'ó', L'ú',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { ES_LUT };
|
||||
#elif defined(TRANSLATIONS_PT)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'Á', L'á', L'Â', L'â', L'Ã', L'ã', L'À',
|
||||
L'à', L'Ç', L'ç', L'É', L'é', L'Ê', L'ê',
|
||||
L'Í', L'í', L'Ó', L'ó', L'Ô', L'ô', L'Õ',
|
||||
L'õ', L'Ú', L'ú',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { PT_LUT };
|
||||
#elif defined(TRANSLATIONS_FI) && !defined(BOOT)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'å', L'ä', L'ö', L'Å', L'Ä', L'Ö',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { FI_LUT };
|
||||
#elif defined(TRANSLATIONS_IT)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'à', L'ù',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { IT_LUT };
|
||||
#elif defined(TRANSLATIONS_PL)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'ą', L'ć', L'ę', L'ł', L'ń', L'ó', L'ś',
|
||||
L'ż', L'ź', L'Ą', L'Ć', L'Ę', L'Ł', L'Ń',
|
||||
L'Ó', L'Ś', L'Ż', L'Ź',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { PL_LUT };
|
||||
#elif defined(TRANSLATIONS_RU) && !defined(BOOT)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'А', L'Б', L'В', L'Г', L'Д', L'Е', L'Ж',
|
||||
L'З', L'И', L'Й', L'К', L'Л', L'М', L'Н',
|
||||
L'О', L'П', L'Р', L'С', L'Т', L'У', L'Ф',
|
||||
L'Х', L'Ц', L'Ч', L'Ш', L'Щ', L'Ъ', L'Ы',
|
||||
L'Ь', L'Э', L'Ю', L'Я', L'а', L'б', L'в',
|
||||
L'г', L'д', L'е', L'ж', L'з', L'и', L'й',
|
||||
L'к', L'л', L'м', L'н', L'о', L'п', L'р',
|
||||
L'с', L'т', L'у', L'ф', L'х', L'ц', L'ч',
|
||||
L'ш', L'щ', L'ъ', L'ы', L'ь', L'э', L'ю',
|
||||
L'я',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { RU_LUT };
|
||||
#elif defined(TRANSLATIONS_UA) && !defined(BOOT)
|
||||
static const uint16_t _utf8_lut[] = { UA_LUT };
|
||||
#define UTF8_SUBS_LUT
|
||||
// Warning, albeit the following table looks useless
|
||||
// It does translate Cyrillic to Latin
|
||||
static uint16_t _utf8_substitution_lut[] = {
|
||||
L'А', L'A',
|
||||
L'а', L'a',
|
||||
L'В', L'B',
|
||||
L'С', L'C',
|
||||
L'с', L'c',
|
||||
L'Е', L'E',
|
||||
L'е', L'e',
|
||||
L'Н', L'H',
|
||||
L'К', L'K',
|
||||
L'М', L'M',
|
||||
L'І', L'I',
|
||||
L'і', L'i',
|
||||
L'О', L'O',
|
||||
L'о', L'o',
|
||||
L'о', L'o',
|
||||
L'Р', L'P',
|
||||
L'р', L'p',
|
||||
L'Т', L'T',
|
||||
L'Х', L'X',
|
||||
L'х', L'x',
|
||||
L'у', L'y'
|
||||
};
|
||||
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'Б', L'Г', L'Ґ', L'Д', L'Є', L'Ж', L'З',
|
||||
L'И', L'Ї', L'Й', L'Л', L'П', L'У', L'Ф',
|
||||
L'Ц', L'Ч', L'Ш', L'Щ', L'Ь', L'Ю', L'Я',
|
||||
L'б', L'в', L'г', L'ґ', L'д', L'є', L'ж',
|
||||
L'з', L'и', L'ї', L'й', L'к', L'л', L'м',
|
||||
L'н', L'п', L'т', L'ф', L'ц', L'ч', L'ш',
|
||||
L'щ', L'ь', L'ю', L'я'
|
||||
};
|
||||
static const uint16_t _utf8_substitution_lut[] = { UA_SUB_LUT };
|
||||
#elif defined(TRANSLATIONS_SE)
|
||||
static uint16_t _utf8_lut[] = {
|
||||
L'å', L'ä', L'ö', L'Å', L'Ä', L'Ö',
|
||||
};
|
||||
static const uint16_t _utf8_lut[] = { SE_LUT};
|
||||
#else
|
||||
#define NO_UTF8_LUT
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
static const uint16_t fr_utf8_lut[] = { FR_LUT, 0 };
|
||||
static const uint16_t fr_utf8_substitution_lut[] = { FR_SUB_LUT, 0 };
|
||||
static const uint16_t da_utf8_lut[] = { DA_LUT, 0 };
|
||||
static const uint16_t de_utf8_lut[] = { DE_LUT, 0 };
|
||||
static const uint16_t cz_utf8_lut[] = { CZ_LUT, 0 };
|
||||
static const uint16_t cz_utf8_substitution_lut[] = { CZ_SUB_LUT, 0 };
|
||||
static const uint16_t es_utf8_lut[] = { ES_LUT, 0 };
|
||||
static const uint16_t pt_utf8_lut[] = { PT_LUT, 0 };
|
||||
static const uint16_t fi_utf8_lut[] = { FI_LUT, 0 };
|
||||
static const uint16_t it_utf8_lut[] = { IT_LUT, 0 };
|
||||
static const uint16_t pl_utf8_lut[] = { PL_LUT, 0 };
|
||||
static const uint16_t ru_utf8_lut[] = { RU_LUT, 0 };
|
||||
static const uint16_t ua_utf8_lut[] = { UA_LUT, 0 };
|
||||
static const uint16_t ua_utf8_substitution_lut[] = { UA_SUB_LUT, 0 };
|
||||
static const uint16_t se_utf8_lut[] = { SE_LUT, 0 };
|
||||
|
||||
struct LangUtf {
|
||||
const uint16_t* lut;
|
||||
const uint16_t* substitution_lut;
|
||||
};
|
||||
|
||||
static const LangUtf langUtf[] = {
|
||||
{ nullptr, nullptr },
|
||||
{ cz_utf8_lut, cz_utf8_substitution_lut },
|
||||
{ da_utf8_lut, nullptr },
|
||||
{ de_utf8_lut, nullptr },
|
||||
{ nullptr, nullptr },
|
||||
{ es_utf8_lut, nullptr },
|
||||
{ fi_utf8_lut, nullptr },
|
||||
{ fr_utf8_lut, fr_utf8_substitution_lut },
|
||||
{ nullptr, nullptr },
|
||||
{ nullptr, nullptr },
|
||||
{ it_utf8_lut, nullptr },
|
||||
{ nullptr, nullptr },
|
||||
{ nullptr, nullptr },
|
||||
{ nullptr, nullptr },
|
||||
{ pl_utf8_lut, nullptr },
|
||||
{ pt_utf8_lut, nullptr },
|
||||
{ ru_utf8_lut, nullptr },
|
||||
{ se_utf8_lut, nullptr },
|
||||
{ nullptr, nullptr },
|
||||
{ nullptr, nullptr },
|
||||
{ ua_utf8_lut, ua_utf8_substitution_lut },
|
||||
};
|
||||
|
||||
static const uint16_t* _utf8_lut = nullptr;
|
||||
static const uint16_t* _utf8_substitution_lut = nullptr;
|
||||
|
||||
void setLanguageUTF(int n)
|
||||
{
|
||||
_utf8_lut = langUtf[n].lut;
|
||||
_utf8_substitution_lut = langUtf[n].substitution_lut;
|
||||
}
|
||||
#define UTF8_SUBS_LUT
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NO_UTF8_LUT)
|
||||
#if !defined(ALL_LANGS) || defined(BOOT)
|
||||
#define MAX_TRANSLATED_CHARS 107
|
||||
static_assert(sizeof(_utf8_lut) / sizeof(_utf8_lut[0]) <= MAX_TRANSLATED_CHARS, "Number of translated chars exceeds the limit");
|
||||
#endif
|
||||
|
||||
static unsigned char lookup_utf8_mapping(wchar_t w)
|
||||
{
|
||||
for (uint32_t i=0; i < DIM(_utf8_lut); i++) {
|
||||
#if !defined(ALL_LANGS) || defined(BOOT)
|
||||
for (int i=0; i < DIM(_utf8_lut); i++) {
|
||||
if (w == _utf8_lut[i])
|
||||
return FONT_LANG_START + (uint8_t)i;
|
||||
}
|
||||
#else
|
||||
if (_utf8_lut == nullptr) return w;
|
||||
for (int i=0; _utf8_lut[i]; i++) {
|
||||
if (w == _utf8_lut[i])
|
||||
return FONT_LANG_START + (uint8_t)i;
|
||||
}
|
||||
#endif
|
||||
return 0x20; // return 'space' for unknown chars
|
||||
}
|
||||
#endif
|
||||
@@ -174,10 +172,18 @@ static unsigned char lookup_utf8_mapping(wchar_t w)
|
||||
#if defined(UTF8_SUBS_LUT)
|
||||
static uint16_t lookup_utf8_substitution(wchar_t w)
|
||||
{
|
||||
for (uint32_t i=0; i < DIM(_utf8_substitution_lut); i+=2) {
|
||||
#if !defined(ALL_LANGS) || defined(BOOT)
|
||||
for (int i=0; i < DIM(_utf8_substitution_lut); i+=2) {
|
||||
if (w == _utf8_substitution_lut[i])
|
||||
return _utf8_substitution_lut[i+1];
|
||||
}
|
||||
#else
|
||||
if (!_utf8_substitution_lut) return w;
|
||||
for (int i=0; _utf8_substitution_lut[i]; i+=2) {
|
||||
if (w == _utf8_substitution_lut[i])
|
||||
return _utf8_substitution_lut[i+1];
|
||||
}
|
||||
#endif
|
||||
return w;
|
||||
}
|
||||
#endif
|
||||
@@ -205,9 +211,9 @@ unsigned char map_utf8_char(const char*& s, uint8_t& len)
|
||||
return (unsigned char)w;
|
||||
}
|
||||
if(w == L'≥')
|
||||
return STR_CHAR_BW_GREATEREQUAL;
|
||||
return CHAR_BW_GREATEREQUAL;
|
||||
if(w == L'°')
|
||||
return STR_CHAR_BW_DEGREE;
|
||||
return CHAR_BW_DEGREE;
|
||||
#if defined(UTF8_SUBS_LUT)
|
||||
auto w_map = lookup_utf8_substitution(w);
|
||||
if (w_map> FONT_LANG_START)
|
||||
|
||||
Reference in New Issue
Block a user