mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
Merge pull request #112092 from timothyqiu/ts-nums
Move localized number formatting methods to `TranslationServer`
This commit is contained in:
commit
8327dfa215
27 changed files with 348 additions and 394 deletions
|
|
@ -1232,3 +1232,32 @@ static const char *plural_rules[][2] = {
|
|||
{ "cy", "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 5);" },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
static const struct NumSystemData {
|
||||
const char *locales;
|
||||
const char32_t *digits;
|
||||
const char32_t *percent_sign;
|
||||
const char32_t *exp_l;
|
||||
const char32_t *exp_u;
|
||||
} num_system_data[] = {
|
||||
// Eastern Arabic numerals.
|
||||
{ "ar ar_AE ar_BH ar_DJ ar_EG ar_ER ar_IL ar_IQ ar_JO ar_KM ar_KW ar_LB ar_MR ar_OM ar_PS ar_QA ar_SA ar_SD ar_SO ar_SS ar_SY ar_TD ar_YE ckb ckb_IQ ckb_IR sd sd_PK sd_Arab sd_Arab_PK", U"٠١٢٣٤٥٦٧٨٩٫", U"٪", U"اس", U"اس" },
|
||||
// Persian and Urdu numerals.
|
||||
{ "fa fa_AF fa_IR ks ks_IN ks_Arab ks_Arab_IN lrc lrc_IQ lrc_IR mzn mzn_IR pa_PK pa_Arab pa_Arab_PK ps ps_AF ps_PK ur_IN uz_AF uz_Arab uz_Arab_AF", U"۰۱۲۳۴۵۶۷۸۹٫", U"٪", U"اس", U"اس" },
|
||||
// Bengali numerals.
|
||||
{ "as as_IN bn bn_BD bn_IN mni mni_IN mni_Beng mni_Beng_IN", U"০১২৩৪৫৬৭৮৯.", U"%", U"e", U"E" },
|
||||
// Devanagari numerals.
|
||||
{ "mr mr_IN ne ne_IN ne_NP sa sa_IN", U"०१२३४५६७८९.", U"%", U"e", U"E" },
|
||||
// Dzongkha numerals.
|
||||
{ "dz dz_BT", U"༠༡༢༣༤༥༦༧༨༩.", U"%", U"e", U"E" },
|
||||
// Santali numerals.
|
||||
{ "sat sat_IN sat_Olck sat_Olck_IN", U"᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙.", U"%", U"e", U"E" },
|
||||
// Burmese numerals.
|
||||
{ "my my_MM", U"၀၁၂၃၄၅၆၇၈၉.", U"%", U"e", U"E" },
|
||||
// Chakma numerals.
|
||||
{ "ccp ccp_BD ccp_IN", U"𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿.", U"%", U"e", U"E" },
|
||||
// Adlam numerals.
|
||||
{ "ff ff_Adlm_BF ff_Adlm_CM ff_Adlm_GH ff_Adlm_GM ff_Adlm_GN ff_Adlm_GW ff_Adlm_LR ff_Adlm_MR ff_Adlm_NE ff_Adlm_NG ff_Adlm_SL ff_Adlm_SN", U"𞥐𞥑𞥒𞥓𞥔𞥕𞥖𞥗𞥘𞥙.", U"%", U"𞤉", U"𞤉" },
|
||||
// End sentinel.
|
||||
{ nullptr, nullptr, nullptr, nullptr, nullptr }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -117,6 +117,26 @@ void TranslationServer::init_locale_info() {
|
|||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
// Init number systems.
|
||||
num_system_map.clear();
|
||||
idx = 0;
|
||||
while (num_system_data[idx].locales != nullptr) {
|
||||
const NumSystemData &nsd = num_system_data[idx];
|
||||
|
||||
// These fields must not be empty.
|
||||
DEV_ASSERT(nsd.percent_sign && nsd.percent_sign[0] != '\0');
|
||||
DEV_ASSERT(nsd.digits && nsd.digits[0] != '\0');
|
||||
DEV_ASSERT(nsd.exp_l && nsd.exp_l[0] != '\0');
|
||||
DEV_ASSERT(nsd.exp_u && nsd.exp_u[0] != '\0');
|
||||
DEV_ASSERT(strlen(nsd.digits) == 11);
|
||||
|
||||
const Vector<String> locales = String(nsd.locales).split(" ");
|
||||
for (const String &l : locales) {
|
||||
num_system_map[l] = idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
TranslationServer::Locale::operator String() const {
|
||||
|
|
@ -219,6 +239,66 @@ TranslationServer::Locale::Locale(const TranslationServer &p_server, const Strin
|
|||
}
|
||||
}
|
||||
|
||||
String TranslationServer::format_number(const String &p_string, const String &p_locale) const {
|
||||
ERR_FAIL_COND_V(p_locale.is_empty(), p_string);
|
||||
if (!num_system_map.has(p_locale)) {
|
||||
return p_string;
|
||||
}
|
||||
|
||||
int index = num_system_map[p_locale];
|
||||
const NumSystemData &nsd = num_system_data[index];
|
||||
|
||||
String res = p_string;
|
||||
res = res.replace("e", nsd.exp_l);
|
||||
res = res.replace("E", nsd.exp_u);
|
||||
char32_t *data = res.ptrw();
|
||||
for (int j = 0; j < res.length(); j++) {
|
||||
if (data[j] >= 0x30 && data[j] <= 0x39) {
|
||||
data[j] = nsd.digits[data[j] - 0x30];
|
||||
} else if (data[j] == '.' || data[j] == ',') {
|
||||
data[j] = nsd.digits[10];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
String TranslationServer::parse_number(const String &p_string, const String &p_locale) const {
|
||||
ERR_FAIL_COND_V(p_locale.is_empty(), p_string);
|
||||
if (!num_system_map.has(p_locale)) {
|
||||
return p_string;
|
||||
}
|
||||
|
||||
int index = num_system_map[p_locale];
|
||||
const NumSystemData &nsd = num_system_data[index];
|
||||
|
||||
String res = p_string;
|
||||
res = res.replace(nsd.exp_l, "e");
|
||||
res = res.replace(nsd.exp_u, "E");
|
||||
char32_t *data = res.ptrw();
|
||||
for (int j = 0; j < res.length(); j++) {
|
||||
if (data[j] == nsd.digits[10]) {
|
||||
data[j] = '.';
|
||||
} else {
|
||||
for (int k = 0; k < 10; k++) {
|
||||
if (data[j] == nsd.digits[k]) {
|
||||
data[j] = 0x30 + k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
String TranslationServer::get_percent_sign(const String &p_locale) const {
|
||||
ERR_FAIL_COND_V(p_locale.is_empty(), "%");
|
||||
if (!num_system_map.has(p_locale)) {
|
||||
return "%";
|
||||
}
|
||||
|
||||
int index = num_system_map[p_locale];
|
||||
return num_system_data[index].percent_sign;
|
||||
}
|
||||
|
||||
String TranslationServer::standardize_locale(const String &p_locale, bool p_add_defaults) const {
|
||||
return Locale(*this, p_locale, p_add_defaults).operator String();
|
||||
}
|
||||
|
|
@ -604,6 +684,10 @@ void TranslationServer::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("get_loaded_locales"), &TranslationServer::get_loaded_locales);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("format_number", "number", "locale"), &TranslationServer::format_number);
|
||||
ClassDB::bind_method(D_METHOD("get_percent_sign", "locale"), &TranslationServer::get_percent_sign);
|
||||
ClassDB::bind_method(D_METHOD("parse_number", "number", "locale"), &TranslationServer::parse_number);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_pseudolocalization_enabled"), &TranslationServer::is_pseudolocalization_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_pseudolocalization_enabled", "enabled"), &TranslationServer::set_pseudolocalization_enabled);
|
||||
ClassDB::bind_method(D_METHOD("reload_pseudolocalization"), &TranslationServer::reload_pseudolocalization);
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ class TranslationServer : public Object {
|
|||
static inline HashMap<String, String> country_rename_map;
|
||||
static inline HashMap<String, String> variant_map;
|
||||
static inline HashMap<String, String> plural_rules_map;
|
||||
static inline HashMap<String, int> num_system_map;
|
||||
|
||||
void init_locale_info();
|
||||
|
||||
|
|
@ -137,6 +138,10 @@ public:
|
|||
void set_pseudolocalization_enabled(bool p_enabled);
|
||||
void reload_pseudolocalization();
|
||||
|
||||
String format_number(const String &p_string, const String &p_locale) const;
|
||||
String parse_number(const String &p_string, const String &p_locale) const;
|
||||
String get_percent_sign(const String &p_locale) const;
|
||||
|
||||
String standardize_locale(const String &p_locale, bool p_add_defaults = false) const;
|
||||
|
||||
int compare_locales(const String &p_locale_a, const String &p_locale_b) const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue