Skip to content

Commit ff55bd7

Browse files
timothyqiubruvzg
andcommitted
Move localized number formatting methods to TranslationServer
Co-Authored-By: Pāvels Nadtočajevs <[email protected]>
1 parent c0c1c68 commit ff55bd7

27 files changed

+347
-392
lines changed

core/string/locales.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,3 +1241,32 @@ static const char *plural_rules[][2] = {
12411241
{ "cy", "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 5);" },
12421242
{ nullptr, nullptr },
12431243
};
1244+
1245+
static const struct NumSystemData {
1246+
const char *locales;
1247+
const char32_t *digits;
1248+
const char32_t *percent_sign;
1249+
const char32_t *exp_l;
1250+
const char32_t *exp_u;
1251+
} num_system_data[] = {
1252+
// Eastern Arabic numerals.
1253+
{ "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"اس" },
1254+
// Persian and Urdu numerals.
1255+
{ "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"اس" },
1256+
// Bengali numerals.
1257+
{ "as as_IN bn bn_BD bn_IN mni mni_IN mni_Beng mni_Beng_IN", U"০১২৩৪৫৬৭৮৯.", U"%", U"e", U"E" },
1258+
// Devanagari numerals.
1259+
{ "mr mr_IN ne ne_IN ne_NP sa sa_IN", U"०१२३४५६७८९.", U"%", U"e", U"E" },
1260+
// Dzongkha numerals.
1261+
{ "dz dz_BT", U"༠༡༢༣༤༥༦༧༨༩.", U"%", U"e", U"E" },
1262+
// Santali numerals.
1263+
{ "sat sat_IN sat_Olck sat_Olck_IN", U"᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙.", U"%", U"e", U"E" },
1264+
// Burmese numerals.
1265+
{ "my my_MM", U"၀၁၂၃၄၅၆၇၈၉.", U"%", U"e", U"E" },
1266+
// Chakma numerals.
1267+
{ "ccp ccp_BD ccp_IN", U"𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿.", U"%", U"e", U"E" },
1268+
// Adlam numerals.
1269+
{ "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"𞤉" },
1270+
// End sentinel.
1271+
{ nullptr, nullptr, nullptr, nullptr, nullptr }
1272+
};

core/string/translation_server.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,25 @@ void TranslationServer::init_locale_info() {
117117
}
118118
idx++;
119119
}
120+
121+
// Init number systems.
122+
num_system_map.clear();
123+
idx = 0;
124+
while (num_system_data[idx].locales != nullptr) {
125+
const NumSystemData &nsd = num_system_data[idx];
126+
127+
// These fields must not be empty.
128+
DEV_ASSERT(nsd.percent_sign && nsd.percent_sign[0] != '\0');
129+
DEV_ASSERT(nsd.digits && nsd.digits[0] != '\0');
130+
DEV_ASSERT(nsd.exp_l && nsd.exp_l[0] != '\0');
131+
DEV_ASSERT(nsd.exp_u && nsd.exp_u[0] != '\0');
132+
133+
const Vector<String> locales = String(nsd.locales).split(" ");
134+
for (const String &l : locales) {
135+
num_system_map[l] = idx;
136+
}
137+
idx++;
138+
}
120139
}
121140

122141
TranslationServer::Locale::operator String() const {
@@ -219,6 +238,66 @@ TranslationServer::Locale::Locale(const TranslationServer &p_server, const Strin
219238
}
220239
}
221240

241+
String TranslationServer::format_number(const String &p_string, const String &p_locale) const {
242+
ERR_FAIL_COND_V(p_locale.is_empty(), p_string);
243+
if (!num_system_map.has(p_locale)) {
244+
return p_string;
245+
}
246+
247+
int index = num_system_map[p_locale];
248+
const NumSystemData &nsd = num_system_data[index];
249+
250+
String res = p_string;
251+
res = res.replace("e", nsd.exp_l);
252+
res = res.replace("E", nsd.exp_u);
253+
char32_t *data = res.ptrw();
254+
for (int j = 0; j < res.length(); j++) {
255+
if (data[j] >= 0x30 && data[j] <= 0x39) {
256+
data[j] = nsd.digits[data[j] - 0x30];
257+
} else if (data[j] == '.' || data[j] == ',') {
258+
data[j] = nsd.digits[10];
259+
}
260+
}
261+
return res;
262+
}
263+
264+
String TranslationServer::parse_number(const String &p_string, const String &p_locale) const {
265+
ERR_FAIL_COND_V(p_locale.is_empty(), p_string);
266+
if (!num_system_map.has(p_locale)) {
267+
return p_string;
268+
}
269+
270+
int index = num_system_map[p_locale];
271+
const NumSystemData &nsd = num_system_data[index];
272+
273+
String res = p_string;
274+
res = res.replace(nsd.exp_l, "e");
275+
res = res.replace(nsd.exp_u, "E");
276+
char32_t *data = res.ptrw();
277+
for (int j = 0; j < res.length(); j++) {
278+
if (data[j] == nsd.digits[10]) {
279+
data[j] = '.';
280+
} else {
281+
for (int k = 0; k < 10; k++) {
282+
if (data[j] == nsd.digits[k]) {
283+
data[j] = 0x30 + k;
284+
}
285+
}
286+
}
287+
}
288+
return res;
289+
}
290+
291+
String TranslationServer::get_percent_sign(const String &p_locale) const {
292+
ERR_FAIL_COND_V(p_locale.is_empty(), "%");
293+
if (!num_system_map.has(p_locale)) {
294+
return "%";
295+
}
296+
297+
int index = num_system_map[p_locale];
298+
return num_system_data[index].percent_sign;
299+
}
300+
222301
String TranslationServer::standardize_locale(const String &p_locale, bool p_add_defaults) const {
223302
return Locale(*this, p_locale, p_add_defaults).operator String();
224303
}
@@ -604,6 +683,10 @@ void TranslationServer::_bind_methods() {
604683

605684
ClassDB::bind_method(D_METHOD("get_loaded_locales"), &TranslationServer::get_loaded_locales);
606685

686+
ClassDB::bind_method(D_METHOD("format_number", "number", "locale"), &TranslationServer::format_number);
687+
ClassDB::bind_method(D_METHOD("get_percent_sign", "locale"), &TranslationServer::get_percent_sign);
688+
ClassDB::bind_method(D_METHOD("parse_number", "number", "locale"), &TranslationServer::parse_number);
689+
607690
ClassDB::bind_method(D_METHOD("is_pseudolocalization_enabled"), &TranslationServer::is_pseudolocalization_enabled);
608691
ClassDB::bind_method(D_METHOD("set_pseudolocalization_enabled", "enabled"), &TranslationServer::set_pseudolocalization_enabled);
609692
ClassDB::bind_method(D_METHOD("reload_pseudolocalization"), &TranslationServer::reload_pseudolocalization);

core/string/translation_server.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class TranslationServer : public Object {
9191
static inline HashMap<String, String> country_rename_map;
9292
static inline HashMap<String, String> variant_map;
9393
static inline HashMap<String, String> plural_rules_map;
94+
static inline HashMap<String, int> num_system_map;
9495

9596
void init_locale_info();
9697

@@ -137,6 +138,10 @@ class TranslationServer : public Object {
137138
void set_pseudolocalization_enabled(bool p_enabled);
138139
void reload_pseudolocalization();
139140

141+
String format_number(const String &p_string, const String &p_locale) const;
142+
String parse_number(const String &p_string, const String &p_locale) const;
143+
String get_percent_sign(const String &p_locale) const;
144+
140145
String standardize_locale(const String &p_locale, bool p_add_defaults = false) const;
141146

142147
int compare_locales(const String &p_locale_a, const String &p_locale_b) const;

doc/classes/TextServer.xml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,13 +1075,13 @@
10751075
Returns the dictionary of the supported OpenType variation coordinates.
10761076
</description>
10771077
</method>
1078-
<method name="format_number" qualifiers="const">
1078+
<method name="format_number" qualifiers="const" deprecated="Use [method TranslationServer.format_number] instead.">
10791079
<return type="String" />
10801080
<param index="0" name="number" type="String" />
10811081
<param index="1" name="language" type="String" default="&quot;&quot;" />
10821082
<description>
1083-
Converts a number from the Western Arabic (0..9) to the numeral systems used in [param language].
1084-
If [param language] is omitted, the active locale will be used.
1083+
Converts a number from Western Arabic (0..9) to the numeral system used in the given [param language].
1084+
If [param language] is an empty string, the active locale will be used.
10851085
</description>
10861086
</method>
10871087
<method name="free_rid">
@@ -1197,12 +1197,13 @@
11971197
Converts readable feature, variation, script, or language name to OpenType tag.
11981198
</description>
11991199
</method>
1200-
<method name="parse_number" qualifiers="const">
1200+
<method name="parse_number" qualifiers="const" deprecated="Use [method TranslationServer.parse_number] instead.">
12011201
<return type="String" />
12021202
<param index="0" name="number" type="String" />
12031203
<param index="1" name="language" type="String" default="&quot;&quot;" />
12041204
<description>
1205-
Converts [param number] from the numeral systems used in [param language] to Western Arabic (0..9).
1205+
Converts [param number] from the numeral system used in the given [param language] to Western Arabic (0..9).
1206+
If [param language] is an empty string, the active locale will be used.
12061207
</description>
12071208
</method>
12081209
<method name="parse_structured_text" qualifiers="const">
@@ -1214,11 +1215,12 @@
12141215
Default implementation of the BiDi algorithm override function.
12151216
</description>
12161217
</method>
1217-
<method name="percent_sign" qualifiers="const">
1218+
<method name="percent_sign" qualifiers="const" deprecated="Use [method TranslationServer.get_percent_sign] instead.">
12181219
<return type="String" />
12191220
<param index="0" name="language" type="String" default="&quot;&quot;" />
12201221
<description>
1221-
Returns percent sign used in the [param language].
1222+
Returns the percent sign used in the given [param language].
1223+
If [param language] is an empty string, the active locale will be used.
12221224
</description>
12231225
</method>
12241226
<method name="save_support_data" qualifiers="const">

doc/classes/TextServerExtension.xml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,12 +1054,13 @@
10541054
Returns the dictionary of the supported OpenType variation coordinates.
10551055
</description>
10561056
</method>
1057-
<method name="_format_number" qualifiers="virtual const">
1057+
<method name="_format_number" qualifiers="virtual const" deprecated="Use [method TranslationServer.format_number] instead.">
10581058
<return type="String" />
10591059
<param index="0" name="number" type="String" />
10601060
<param index="1" name="language" type="String" />
10611061
<description>
1062-
Converts a number from the Western Arabic (0..9) to the numeral systems used in [param language].
1062+
Converts a number from Western Arabic (0..9) to the numeral system used in the given [param language].
1063+
If [param language] is an empty string, the active locale will be used.
10631064
</description>
10641065
</method>
10651066
<method name="_free_rid" qualifiers="virtual required">
@@ -1163,12 +1164,13 @@
11631164
Converts readable feature, variation, script, or language name to OpenType tag.
11641165
</description>
11651166
</method>
1166-
<method name="_parse_number" qualifiers="virtual const">
1167+
<method name="_parse_number" qualifiers="virtual const" deprecated="Use [method TranslationServer.parse_number] instead.">
11671168
<return type="String" />
11681169
<param index="0" name="number" type="String" />
11691170
<param index="1" name="language" type="String" />
11701171
<description>
1171-
Converts [param number] from the numeral systems used in [param language] to Western Arabic (0..9).
1172+
Converts [param number] from the numeral system used in the given [param language] to Western Arabic (0..9).
1173+
If [param language] is an empty string, the active locale will be used.
11721174
</description>
11731175
</method>
11741176
<method name="_parse_structured_text" qualifiers="virtual const">
@@ -1180,11 +1182,11 @@
11801182
Default implementation of the BiDi algorithm override function.
11811183
</description>
11821184
</method>
1183-
<method name="_percent_sign" qualifiers="virtual const">
1185+
<method name="_percent_sign" qualifiers="virtual const" deprecated="Use [method TranslationServer.get_percent_sign] instead.">
11841186
<return type="String" />
11851187
<param index="0" name="language" type="String" />
11861188
<description>
1187-
Returns percent sign used in the [param language].
1189+
Returns percent sign used in the given [param language].
11881190
</description>
11891191
</method>
11901192
<method name="_reference_oversampling_level" qualifiers="virtual">

doc/classes/TranslationServer.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@
3333
Compares two locales and returns a similarity score between [code]0[/code] (no match) and [code]10[/code] (full match).
3434
</description>
3535
</method>
36+
<method name="format_number" qualifiers="const">
37+
<return type="String" />
38+
<param index="0" name="number" type="String" />
39+
<param index="1" name="locale" type="String" />
40+
<description>
41+
Converts a number from Western Arabic (0..9) to the numeral system used in the given [param locale].
42+
</description>
43+
</method>
3644
<method name="get_all_countries" qualifiers="const">
3745
<return type="PackedStringArray" />
3846
<description>
@@ -92,6 +100,13 @@
92100
Returns the translation domain with the specified name. An empty translation domain will be created and added if it does not exist.
93101
</description>
94102
</method>
103+
<method name="get_percent_sign" qualifiers="const">
104+
<return type="String" />
105+
<param index="0" name="locale" type="String" />
106+
<description>
107+
Returns the percent sign used in the given [param locale].
108+
</description>
109+
</method>
95110
<method name="get_plural_rules" qualifiers="const">
96111
<return type="String" />
97112
<param index="0" name="locale" type="String" />
@@ -127,6 +142,14 @@
127142
Returns [code]true[/code] if a translation domain with the specified name exists.
128143
</description>
129144
</method>
145+
<method name="parse_number" qualifiers="const">
146+
<return type="String" />
147+
<param index="0" name="number" type="String" />
148+
<param index="1" name="locale" type="String" />
149+
<description>
150+
Converts [param number] from the numeral system used in the given [param locale] to Western Arabic (0..9).
151+
</description>
152+
</method>
130153
<method name="pseudolocalize" qualifiers="const">
131154
<return type="StringName" />
132155
<param index="0" name="message" type="StringName" />

editor/animation/animation_bezier_editor.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "animation_bezier_editor.h"
3232

33+
#include "core/string/translation_server.h"
3334
#include "editor/animation/animation_player_editor_plugin.h"
3435
#include "editor/editor_node.h"
3536
#include "editor/editor_string_names.h"
@@ -303,6 +304,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
303304
const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit"));
304305
const int v_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit"));
305306

307+
const String &lang = _get_locale();
308+
306309
if (has_focus(true)) {
307310
draw_rect(Rect2(Point2(), get_size()), focus_color, false, Math::round(EDSCALE));
308311
}
@@ -577,7 +580,9 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
577580
draw_line(Point2(limit, i), Point2(right_limit, i), lc, Math::round(EDSCALE));
578581
Color c = color;
579582
c.a *= 0.5;
580-
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);
583+
584+
const String &formatted = TranslationServer::get_singleton()->format_number(rtos(Math::snapped((iv + 1) * scale, step)), lang);
585+
draw_string(font, Point2(limit + 8, i - 2), formatted, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, c);
581586
}
582587

583588
first = false;
@@ -716,8 +721,12 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
716721
ep.point_rect.size = bezier_icon->get_size();
717722
if (is_selected) {
718723
draw_texture(selected_icon, ep.point_rect.position);
719-
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);
720-
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);
724+
725+
const String &formatted_offset = TranslationServer::get_singleton()->format_number(rtos(Math::snapped(offset, 0.0001)), lang);
726+
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);
727+
728+
const String &formatted_value = TranslationServer::get_singleton()->format_number(rtos(Math::snapped(value, 0.001)), lang);
729+
draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + formatted_value, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
721730
} else {
722731
Color track_color = Color(1, 1, 1, 1);
723732
if (i != selected_track) {

editor/animation/animation_track_editor.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "core/config/project_settings.h"
3535
#include "core/error/error_macros.h"
3636
#include "core/input/input.h"
37+
#include "core/string/translation_server.h"
3738
#include "editor/animation/animation_bezier_editor.h"
3839
#include "editor/animation/animation_player_editor_plugin.h"
3940
#include "editor/docks/inspector_dock.h"
@@ -2876,7 +2877,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
28762877
}
28772878

28782879
if (key_idx != -1) {
2879-
String text = TTR("Time (s):") + " " + TS->format_number(rtos(Math::snapped(animation->track_get_key_time(track, key_idx), SECOND_DECIMAL))) + "\n";
2880+
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";
28802881
switch (animation->track_get_type(track)) {
28812882
case Animation::TYPE_POSITION_3D: {
28822883
Vector3 t = animation->track_get_key_value(track, key_idx);
@@ -9011,7 +9012,7 @@ String AnimationMarkerEdit::get_tooltip(const Point2 &p_pos) const {
90119012

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

0 commit comments

Comments
 (0)