Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions core/string/locales.h
Original file line number Diff line number Diff line change
Expand Up @@ -1241,3 +1241,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 }
};
83 changes: 83 additions & 0 deletions core/string/translation_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,25 @@ 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');

const Vector<String> locales = String(nsd.locales).split(" ");
for (const String &l : locales) {
num_system_map[l] = idx;
}
idx++;
}
}

TranslationServer::Locale::operator String() const {
Expand Down Expand Up @@ -219,6 +238,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();
}
Expand Down Expand Up @@ -604,6 +683,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);
Expand Down
5 changes: 5 additions & 0 deletions core/string/translation_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -137,6 +138,10 @@ class TranslationServer : public Object {
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;
Expand Down
16 changes: 9 additions & 7 deletions doc/classes/TextServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1075,13 +1075,13 @@
Returns the dictionary of the supported OpenType variation coordinates.
</description>
</method>
<method name="format_number" qualifiers="const">
<method name="format_number" qualifiers="const" deprecated="Use [method TranslationServer.format_number] instead.">
<return type="String" />
<param index="0" name="number" type="String" />
<param index="1" name="language" type="String" default="&quot;&quot;" />
<description>
Converts a number from the Western Arabic (0..9) to the numeral systems used in [param language].
If [param language] is omitted, the active locale will be used.
Converts a number from Western Arabic (0..9) to the numeral system used in the given [param language].
If [param language] is an empty string, the active locale will be used.
</description>
</method>
<method name="free_rid">
Expand Down Expand Up @@ -1197,12 +1197,13 @@
Converts readable feature, variation, script, or language name to OpenType tag.
</description>
</method>
<method name="parse_number" qualifiers="const">
<method name="parse_number" qualifiers="const" deprecated="Use [method TranslationServer.parse_number] instead.">
<return type="String" />
<param index="0" name="number" type="String" />
<param index="1" name="language" type="String" default="&quot;&quot;" />
<description>
Converts [param number] from the numeral systems used in [param language] to Western Arabic (0..9).
Converts [param number] from the numeral system used in the given [param language] to Western Arabic (0..9).
If [param language] is an empty string, the active locale will be used.
</description>
</method>
<method name="parse_structured_text" qualifiers="const">
Expand All @@ -1214,11 +1215,12 @@
Default implementation of the BiDi algorithm override function.
</description>
</method>
<method name="percent_sign" qualifiers="const">
<method name="percent_sign" qualifiers="const" deprecated="Use [method TranslationServer.get_percent_sign] instead.">
<return type="String" />
<param index="0" name="language" type="String" default="&quot;&quot;" />
<description>
Returns percent sign used in the [param language].
Returns the percent sign used in the given [param language].
If [param language] is an empty string, the active locale will be used.
</description>
</method>
<method name="save_support_data" qualifiers="const">
Expand Down
14 changes: 8 additions & 6 deletions doc/classes/TextServerExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1054,12 +1054,13 @@
Returns the dictionary of the supported OpenType variation coordinates.
</description>
</method>
<method name="_format_number" qualifiers="virtual const">
<method name="_format_number" qualifiers="virtual const" deprecated="Use [method TranslationServer.format_number] instead.">
<return type="String" />
<param index="0" name="number" type="String" />
<param index="1" name="language" type="String" />
<description>
Converts a number from the Western Arabic (0..9) to the numeral systems used in [param language].
Converts a number from Western Arabic (0..9) to the numeral system used in the given [param language].
If [param language] is an empty string, the active locale will be used.
</description>
</method>
<method name="_free_rid" qualifiers="virtual required">
Expand Down Expand Up @@ -1163,12 +1164,13 @@
Converts readable feature, variation, script, or language name to OpenType tag.
</description>
</method>
<method name="_parse_number" qualifiers="virtual const">
<method name="_parse_number" qualifiers="virtual const" deprecated="Use [method TranslationServer.parse_number] instead.">
<return type="String" />
<param index="0" name="number" type="String" />
<param index="1" name="language" type="String" />
<description>
Converts [param number] from the numeral systems used in [param language] to Western Arabic (0..9).
Converts [param number] from the numeral system used in the given [param language] to Western Arabic (0..9).
If [param language] is an empty string, the active locale will be used.
</description>
</method>
<method name="_parse_structured_text" qualifiers="virtual const">
Expand All @@ -1180,11 +1182,11 @@
Default implementation of the BiDi algorithm override function.
</description>
</method>
<method name="_percent_sign" qualifiers="virtual const">
<method name="_percent_sign" qualifiers="virtual const" deprecated="Use [method TranslationServer.get_percent_sign] instead.">
<return type="String" />
<param index="0" name="language" type="String" />
<description>
Returns percent sign used in the [param language].
Returns percent sign used in the given [param language].
</description>
</method>
<method name="_reference_oversampling_level" qualifiers="virtual">
Expand Down
23 changes: 23 additions & 0 deletions doc/classes/TranslationServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@
Compares two locales and returns a similarity score between [code]0[/code] (no match) and [code]10[/code] (full match).
</description>
</method>
<method name="format_number" qualifiers="const">
<return type="String" />
<param index="0" name="number" type="String" />
<param index="1" name="locale" type="String" />
<description>
Converts a number from Western Arabic (0..9) to the numeral system used in the given [param locale].
</description>
</method>
<method name="get_all_countries" qualifiers="const">
<return type="PackedStringArray" />
<description>
Expand Down Expand Up @@ -92,6 +100,13 @@
Returns the translation domain with the specified name. An empty translation domain will be created and added if it does not exist.
</description>
</method>
<method name="get_percent_sign" qualifiers="const">
<return type="String" />
<param index="0" name="locale" type="String" />
<description>
Returns the percent sign used in the given [param locale].
</description>
</method>
<method name="get_plural_rules" qualifiers="const">
<return type="String" />
<param index="0" name="locale" type="String" />
Expand Down Expand Up @@ -127,6 +142,14 @@
Returns [code]true[/code] if a translation domain with the specified name exists.
</description>
</method>
<method name="parse_number" qualifiers="const">
<return type="String" />
<param index="0" name="number" type="String" />
<param index="1" name="locale" type="String" />
<description>
Converts [param number] from the numeral system used in the given [param locale] to Western Arabic (0..9).
</description>
</method>
<method name="pseudolocalize" qualifiers="const">
<return type="StringName" />
<param index="0" name="message" type="StringName" />
Expand Down
15 changes: 12 additions & 3 deletions editor/animation/animation_bezier_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "animation_bezier_editor.h"

#include "core/string/translation_server.h"
#include "editor/animation/animation_player_editor_plugin.h"
#include "editor/editor_node.h"
#include "editor/editor_string_names.h"
Expand Down Expand Up @@ -303,6 +304,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit"));
const int v_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit"));

const String &lang = _get_locale();

if (has_focus(true)) {
draw_rect(Rect2(Point2(), get_size()), focus_color, false, Math::round(EDSCALE));
}
Expand Down Expand Up @@ -577,7 +580,9 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
draw_line(Point2(limit, i), Point2(right_limit, i), lc, Math::round(EDSCALE));
Color c = color;
c.a *= 0.5;
draw_string(font, Point2(limit + 8, i - 2), TS->format_number(rtos(Math::snapped((iv + 1) * scale, step))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, c);

const String &formatted = TranslationServer::get_singleton()->format_number(rtos(Math::snapped((iv + 1) * scale, step)), lang);
draw_string(font, Point2(limit + 8, i - 2), formatted, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, c);
}

first = false;
Expand Down Expand Up @@ -716,8 +721,12 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
ep.point_rect.size = bezier_icon->get_size();
if (is_selected) {
draw_texture(selected_icon, ep.point_rect.position);
draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 8), TTR("Time:") + " " + TS->format_number(rtos(Math::snapped(offset, 0.0001))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + TS->format_number(rtos(Math::snapped(value, 0.001))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);

const String &formatted_offset = TranslationServer::get_singleton()->format_number(rtos(Math::snapped(offset, 0.0001)), lang);
draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 8), TTR("Time:") + " " + formatted_offset, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);

const String &formatted_value = TranslationServer::get_singleton()->format_number(rtos(Math::snapped(value, 0.001)), lang);
draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + formatted_value, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
} else {
Color track_color = Color(1, 1, 1, 1);
if (i != selected_track) {
Expand Down
5 changes: 3 additions & 2 deletions editor/animation/animation_track_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "core/config/project_settings.h"
#include "core/error/error_macros.h"
#include "core/input/input.h"
#include "core/string/translation_server.h"
#include "editor/animation/animation_bezier_editor.h"
#include "editor/animation/animation_player_editor_plugin.h"
#include "editor/docks/inspector_dock.h"
Expand Down Expand Up @@ -2876,7 +2877,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
}

if (key_idx != -1) {
String text = TTR("Time (s):") + " " + TS->format_number(rtos(Math::snapped(animation->track_get_key_time(track, key_idx), SECOND_DECIMAL))) + "\n";
String text = TTR("Time (s):") + " " + TranslationServer::get_singleton()->format_number(rtos(Math::snapped(animation->track_get_key_time(track, key_idx), SECOND_DECIMAL)), _get_locale()) + "\n";
switch (animation->track_get_type(track)) {
case Animation::TYPE_POSITION_3D: {
Vector3 t = animation->track_get_key_value(track, key_idx);
Expand Down Expand Up @@ -9011,7 +9012,7 @@ String AnimationMarkerEdit::get_tooltip(const Point2 &p_pos) const {

if (key_idx != -1) {
String name = names[key_idx];
String text = TTR("Time (s):") + " " + TS->format_number(rtos(Math::snapped(animation->get_marker_time(name), 0.0001))) + "\n";
String text = TTR("Time (s):") + " " + TranslationServer::get_singleton()->format_number(rtos(Math::snapped(animation->get_marker_time(name), 0.0001)), _get_locale()) + "\n";
text += TTR("Marker:") + " " + name + "\n";
return text;
}
Expand Down
Loading