Skip to content

Commit

Permalink
Fix #11054: Prevent translation of currency codes.
Browse files Browse the repository at this point in the history
Most languages stick with the 3-letter latin currency codes in the name
string, however some translations are... clever... and use the currency
symbol instead. Whilst this may look nice, it can cause issues with fonts
as some scripts have a specific limited set of fonts which do not include
these symbols.

Instead, hard code the currency code list and add it when drawing the
currency name.
  • Loading branch information
PeterN committed Jun 23, 2023
1 parent d42a78f commit 9dd9b8e
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 115 deletions.
112 changes: 46 additions & 66 deletions src/currency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,54 @@

#include "safeguards.h"

/* exchange rate prefix symbol_pos
* | separator | postfix |
* | | Euro year | | | name
* | | | | | | | */
/* exchange rate prefix code
* | separator | postfix | symbol_pos
* | | Euro year | | | | name
* | | | | | | | | */
/** The original currency specifications. */
static const CurrencySpec origin_currency_specs[CURRENCY_END] = {
{ 1, "", CF_NOEURO, u8"\u00a3", "", 0, STR_GAME_OPTIONS_CURRENCY_GBP }, ///< british pound
{ 2, "", CF_NOEURO, "$", "", 0, STR_GAME_OPTIONS_CURRENCY_USD }, ///< american dollar
{ 2, "", CF_ISEURO, u8"\u20ac", "", 0, STR_GAME_OPTIONS_CURRENCY_EUR }, ///< euro
{ 220, "", CF_NOEURO, u8"\u00a5", "", 0, STR_GAME_OPTIONS_CURRENCY_JPY }, ///< japanese yen
{ 27, "", 2002, "", NBSP "S.", 1, STR_GAME_OPTIONS_CURRENCY_ATS }, ///< austrian schilling
{ 81, "", 2002, "BEF" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_BEF }, ///< belgian franc
{ 2, "", CF_NOEURO, "CHF" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_CHF }, ///< swiss franc
{ 41, "", CF_NOEURO, "", NBSP u8"K\u010d", 1, STR_GAME_OPTIONS_CURRENCY_CZK }, ///< czech koruna
{ 4, "", 2002, "DM" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_DEM }, ///< deutsche mark
{ 11, "", CF_NOEURO, "", NBSP "kr", 1, STR_GAME_OPTIONS_CURRENCY_DKK }, ///< danish krone
{ 333, "", 2002, "Pts" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_ESP }, ///< spanish peseta
{ 12, "", 2002, "", NBSP "mk", 1, STR_GAME_OPTIONS_CURRENCY_FIM }, ///< finnish markka
{ 13, "", 2002, "FF" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_FRF }, ///< french franc
{ 681, "", 2002, "", "Dr.", 1, STR_GAME_OPTIONS_CURRENCY_GRD }, ///< greek drachma
{ 378, "", CF_NOEURO, "", NBSP "Ft", 1, STR_GAME_OPTIONS_CURRENCY_HUF }, ///< hungarian forint
{ 130, "", CF_NOEURO, "", NBSP "Kr", 1, STR_GAME_OPTIONS_CURRENCY_ISK }, ///< icelandic krona
{ 3873, "", 2002, "", NBSP "L.", 1, STR_GAME_OPTIONS_CURRENCY_ITL }, ///< italian lira
{ 4, "", 2002, "NLG" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_NLG }, ///< dutch gulden
{ 12, "", CF_NOEURO, "", NBSP "Kr", 1, STR_GAME_OPTIONS_CURRENCY_NOK }, ///< norwegian krone
{ 6, "", CF_NOEURO, "", NBSP u8"z\u0142", 1, STR_GAME_OPTIONS_CURRENCY_PLN }, ///< polish zloty
{ 5, "", CF_NOEURO, "", NBSP "Lei", 1, STR_GAME_OPTIONS_CURRENCY_RON }, ///< romanian leu
{ 50, "", CF_NOEURO, "", NBSP "p", 1, STR_GAME_OPTIONS_CURRENCY_RUR }, ///< russian rouble
{ 479, "", 2007, "", NBSP "SIT", 1, STR_GAME_OPTIONS_CURRENCY_SIT }, ///< slovenian tolar
{ 13, "", CF_NOEURO, "", NBSP "Kr", 1, STR_GAME_OPTIONS_CURRENCY_SEK }, ///< swedish krona
{ 3, "", CF_NOEURO, "", NBSP "TL", 1, STR_GAME_OPTIONS_CURRENCY_TRY }, ///< turkish lira
{ 60, "", 2009, "", NBSP "Sk", 1, STR_GAME_OPTIONS_CURRENCY_SKK }, ///< slovak koruna
{ 4, "", CF_NOEURO, "R$" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_BRL }, ///< brazil real
{ 31, "", 2011, "", NBSP "EEK", 1, STR_GAME_OPTIONS_CURRENCY_EEK }, ///< estonian krooni
{ 4, "", 2015, "", NBSP "Lt", 1, STR_GAME_OPTIONS_CURRENCY_LTL }, ///< lithuanian litas
{ 1850, "", CF_NOEURO, u8"\u20a9", "", 0, STR_GAME_OPTIONS_CURRENCY_KRW }, ///< south korean won
{ 13, "", CF_NOEURO, "R" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_ZAR }, ///< south african rand
{ 1, "", CF_NOEURO, "", "", 2, STR_GAME_OPTIONS_CURRENCY_CUSTOM }, ///< custom currency (add further languages below)
{ 3, "", CF_NOEURO, "", NBSP "GEL", 1, STR_GAME_OPTIONS_CURRENCY_GEL }, ///< Georgian Lari
{ 4901, "", CF_NOEURO, "", NBSP "Rls", 1, STR_GAME_OPTIONS_CURRENCY_IRR }, ///< Iranian Rial
{ 80, "", CF_NOEURO, "", NBSP "rub", 1, STR_GAME_OPTIONS_CURRENCY_RUB }, ///< New Russian Ruble
{ 24, "", CF_NOEURO, "$", "", 0, STR_GAME_OPTIONS_CURRENCY_MXN }, ///< Mexican peso
{ 40, "", CF_NOEURO, "NTD" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_NTD }, ///< new taiwan dollar
{ 8, "", CF_NOEURO, u8"\u00a5", "", 0, STR_GAME_OPTIONS_CURRENCY_CNY }, ///< chinese renminbi
{ 10, "", CF_NOEURO, "HKD" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_HKD }, ///< hong kong dollar
{ 90, "", CF_NOEURO, u8"\u20b9", "", 0, STR_GAME_OPTIONS_CURRENCY_INR }, ///< Indian Rupee
{ 19, "", CF_NOEURO, "Rp", "", 0, STR_GAME_OPTIONS_CURRENCY_IDR }, ///< Indonesian Rupiah
{ 5, "", CF_NOEURO, "RM", "", 0, STR_GAME_OPTIONS_CURRENCY_MYR }, ///< Malaysian Ringgit
{ 1, "", CF_NOEURO, u8"\u00a3", "", "GBP", 0, STR_GAME_OPTIONS_CURRENCY_GBP }, ///< british pound
{ 2, "", CF_NOEURO, "$", "", "USD", 0, STR_GAME_OPTIONS_CURRENCY_USD }, ///< american dollar
{ 2, "", CF_ISEURO, u8"\u20ac", "", "EUR", 0, STR_GAME_OPTIONS_CURRENCY_EUR }, ///< euro
{ 220, "", CF_NOEURO, u8"\u00a5", "", "JPY", 0, STR_GAME_OPTIONS_CURRENCY_JPY }, ///< japanese yen
{ 27, "", 2002, "", NBSP "S.", "ATS", 1, STR_GAME_OPTIONS_CURRENCY_ATS }, ///< austrian schilling
{ 81, "", 2002, "BEF" NBSP, "", "BEF", 0, STR_GAME_OPTIONS_CURRENCY_BEF }, ///< belgian franc
{ 2, "", CF_NOEURO, "CHF" NBSP, "", "CHF", 0, STR_GAME_OPTIONS_CURRENCY_CHF }, ///< swiss franc
{ 41, "", CF_NOEURO, "", NBSP u8"K\u010d", "CZK", 1, STR_GAME_OPTIONS_CURRENCY_CZK }, ///< czech koruna
{ 4, "", 2002, "DM" NBSP, "", "DEM", 0, STR_GAME_OPTIONS_CURRENCY_DEM }, ///< deutsche mark
{ 11, "", CF_NOEURO, "", NBSP "kr", "DKK", 1, STR_GAME_OPTIONS_CURRENCY_DKK }, ///< danish krone
{ 333, "", 2002, "Pts" NBSP, "", "ESP", 0, STR_GAME_OPTIONS_CURRENCY_ESP }, ///< spanish peseta
{ 12, "", 2002, "", NBSP "mk", "FIM", 1, STR_GAME_OPTIONS_CURRENCY_FIM }, ///< finnish markka
{ 13, "", 2002, "FF" NBSP, "", "FRF", 0, STR_GAME_OPTIONS_CURRENCY_FRF }, ///< french franc
{ 681, "", 2002, "", "Dr.", "GRD", 1, STR_GAME_OPTIONS_CURRENCY_GRD }, ///< greek drachma
{ 378, "", CF_NOEURO, "", NBSP "Ft", "HUF", 1, STR_GAME_OPTIONS_CURRENCY_HUF }, ///< hungarian forint
{ 130, "", CF_NOEURO, "", NBSP "Kr", "ISK", 1, STR_GAME_OPTIONS_CURRENCY_ISK }, ///< icelandic krona
{ 3873, "", 2002, "", NBSP "L.", "ITL", 1, STR_GAME_OPTIONS_CURRENCY_ITL }, ///< italian lira
{ 4, "", 2002, "NLG" NBSP, "", "NLG", 0, STR_GAME_OPTIONS_CURRENCY_NLG }, ///< dutch gulden
{ 12, "", CF_NOEURO, "", NBSP "Kr", "NOK", 1, STR_GAME_OPTIONS_CURRENCY_NOK }, ///< norwegian krone
{ 6, "", CF_NOEURO, "", NBSP u8"z\u0142", "PLN", 1, STR_GAME_OPTIONS_CURRENCY_PLN }, ///< polish zloty
{ 5, "", CF_NOEURO, "", NBSP "Lei", "RON", 1, STR_GAME_OPTIONS_CURRENCY_RON }, ///< romanian leu
{ 50, "", CF_NOEURO, "", NBSP "p", "RUR", 1, STR_GAME_OPTIONS_CURRENCY_RUR }, ///< russian rouble
{ 479, "", 2007, "", NBSP "SIT", "SIT", 1, STR_GAME_OPTIONS_CURRENCY_SIT }, ///< slovenian tolar
{ 13, "", CF_NOEURO, "", NBSP "Kr", "SEK", 1, STR_GAME_OPTIONS_CURRENCY_SEK }, ///< swedish krona
{ 3, "", CF_NOEURO, "", NBSP "TL", "TRY", 1, STR_GAME_OPTIONS_CURRENCY_TRY }, ///< turkish lira
{ 60, "", 2009, "", NBSP "Sk", "SKK", 1, STR_GAME_OPTIONS_CURRENCY_SKK }, ///< slovak koruna
{ 4, "", CF_NOEURO, "R$" NBSP, "", "BRL", 0, STR_GAME_OPTIONS_CURRENCY_BRL }, ///< brazil real
{ 31, "", 2011, "", NBSP "EEK", "EEK", 1, STR_GAME_OPTIONS_CURRENCY_EEK }, ///< estonian krooni
{ 4, "", 2015, "", NBSP "Lt", "LTL", 1, STR_GAME_OPTIONS_CURRENCY_LTL }, ///< lithuanian litas
{ 1850, "", CF_NOEURO, u8"\u20a9", "", "KRW", 0, STR_GAME_OPTIONS_CURRENCY_KRW }, ///< south korean won
{ 13, "", CF_NOEURO, "R" NBSP, "", "ZAR", 0, STR_GAME_OPTIONS_CURRENCY_ZAR }, ///< south african rand
{ 1, "", CF_NOEURO, "", "", "", 2, STR_GAME_OPTIONS_CURRENCY_CUSTOM }, ///< custom currency (add further languages below)
{ 3, "", CF_NOEURO, "", NBSP "GEL", "GEL", 1, STR_GAME_OPTIONS_CURRENCY_GEL }, ///< Georgian Lari
{ 4901, "", CF_NOEURO, "", NBSP "Rls", "IRR", 1, STR_GAME_OPTIONS_CURRENCY_IRR }, ///< Iranian Rial
{ 80, "", CF_NOEURO, "", NBSP "rub", "RUB", 1, STR_GAME_OPTIONS_CURRENCY_RUB }, ///< New Russian Ruble
{ 24, "", CF_NOEURO, "$", "", "MXN", 0, STR_GAME_OPTIONS_CURRENCY_MXN }, ///< Mexican peso
{ 40, "", CF_NOEURO, "NTD" NBSP, "", "NTD", 0, STR_GAME_OPTIONS_CURRENCY_NTD }, ///< new taiwan dollar
{ 8, "", CF_NOEURO, u8"\u00a5", "", "CNY", 0, STR_GAME_OPTIONS_CURRENCY_CNY }, ///< chinese renminbi
{ 10, "", CF_NOEURO, "HKD" NBSP, "", "HKD", 0, STR_GAME_OPTIONS_CURRENCY_HKD }, ///< hong kong dollar
{ 90, "", CF_NOEURO, u8"\u20b9", "", "INR", 0, STR_GAME_OPTIONS_CURRENCY_INR }, ///< Indian Rupee
{ 19, "", CF_NOEURO, "Rp", "", "IDR", 0, STR_GAME_OPTIONS_CURRENCY_IDR }, ///< Indonesian Rupiah
{ 5, "", CF_NOEURO, "RM", "", "MYR", 0, STR_GAME_OPTIONS_CURRENCY_MYR }, ///< Malaysian Ringgit
};

/** Array of currencies used by the system */
Expand Down Expand Up @@ -162,23 +162,3 @@ void ResetCurrencies(bool preserve_custom)
_currency_specs[i] = origin_currency_specs[i];
}
}

/**
* Build a list of currency names StringIDs to use in a dropdown list
* @return Pointer to a (static) array of StringIDs
*/
StringID *BuildCurrencyDropdown()
{
/* Allow room for all currencies, plus a terminator entry */
static StringID names[CURRENCY_END + 1];
uint i;

/* Add each name */
for (i = 0; i < CURRENCY_END; i++) {
names[i] = _currency_specs[i].name;
}
/* Terminate the list */
names[i] = INVALID_STRING_ID;

return names;
}
6 changes: 3 additions & 3 deletions src/currency.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct CurrencySpec {
TimerGameCalendar::Year to_euro; ///< Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
std::string prefix; ///< Prefix to apply when formatting money in this currency.
std::string suffix; ///< Suffix to apply when formatting money in this currency.
std::string code; ///< 3 letter untranslated code to identify the currency.
/**
* The currency symbol is represented by two possible values, prefix and suffix
* Usage of one or the other is determined by #symbol_pos.
Expand All @@ -89,8 +90,8 @@ struct CurrencySpec {

CurrencySpec() = default;

CurrencySpec(uint16 rate, const char *separator, TimerGameCalendar::Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) :
rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), symbol_pos(symbol_pos), name(name)
CurrencySpec(uint16 rate, const char *separator, TimerGameCalendar::Year to_euro, const char *prefix, const char *suffix, const char *code, byte symbol_pos, StringID name) :
rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), code(code), symbol_pos(symbol_pos), name(name)
{
}
};
Expand All @@ -103,7 +104,6 @@ extern CurrencySpec _currency_specs[CURRENCY_END];

uint64 GetMaskOfAllowedCurrencies();
void ResetCurrencies(bool preserve_custom = true);
StringID *BuildCurrencyDropdown();
byte GetNewgrfCurrencyIdConverted(byte grfcurr_id);

#endif /* CURRENCY_H */

0 comments on commit 9dd9b8e

Please sign in to comment.