1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-12 10:32:26 +01:00

Merge pull request #2378 from IntelOrca/support-unicode-currencies

support unicode currencies with ascii fallback
This commit is contained in:
Ted John
2015-11-27 17:56:44 +00:00
11 changed files with 123 additions and 37 deletions

View File

@@ -3899,7 +3899,7 @@ STR_5557 :Stay connected after desynchronisation (Multiplayer)
STR_5558 :A restart is required for this setting to take effect
STR_5559 :10 min. inspections
STR_5560 :{SMALLFONT}{BLACK}Sets the inspection time to 'Every 10 minutes' on all rides
STR_5561 :Failed to load language file
STR_5561 :Failed to load language
STR_5562 :WARNING!
STR_5563 :This feature is currently unstable, take extra caution.
STR_5564 :Insert Corrupt Element
@@ -3918,6 +3918,7 @@ STR_5576 :Port:
STR_5577 :South Korean Won (W)
STR_5578 :Russian Rouble (R)
STR_5579 :Window scale factor:
STR_5580 :Czech koruna (Kc)
#####################
# Rides/attractions #

View File

@@ -126,3 +126,61 @@ int font_get_line_height_small(int fontSpriteBase)
{
return font_get_line_height(fontSpriteBase) / 2;
}
bool font_supports_string(const utf8 *text, int fontSize)
{
const utf8 *src = text;
uint32 codepoint;
while ((codepoint = utf8_get_next(src, &src)) != 0) {
if (gUseTrueTypeFont) {
bool supported = TTF_GlyphIsProvided(gCurrentTTFFontSet->size[fontSize].font, (uint16)codepoint);
if (!supported) {
return false;
}
} else {
bool supported = false;
switch (codepoint) {
case FORMAT_ENDQUOTES:
case FORMAT_AMINUSCULE:
case FORMAT_UP:
case FORMAT_SYMBOL_i:
case FORMAT_CENT:
case FORMAT_POUND:
case FORMAT_YEN:
case FORMAT_COPYRIGHT:
case FORMAT_DOWN:
case FORMAT_LEFTGUILLEMET:
case FORMAT_TICK:
case FORMAT_CROSS:
case FORMAT_RIGHT:
case FORMAT_DEGREE:
case FORMAT_SYMBOL_RAILWAY:
case FORMAT_SQUARED:
case FORMAT_OPENQUOTES:
case FORMAT_EURO:
case FORMAT_SYMBOL_ROAD:
case FORMAT_SYMBOL_FLAG:
case FORMAT_APPROX:
case FORMAT_POWERNEGATIVEONE:
case FORMAT_BULLET:
case FORMAT_RIGHTGUILLEMET:
case FORMAT_SMALLUP:
case FORMAT_SMALLDOWN:
case FORMAT_LEFT:
case FORMAT_INVERTEDQUESTION:
supported = true;
break;
default:
if (codepoint >= 32 && codepoint < 256) {
supported = true;
}
break;
}
if (!supported) {
return false;
}
}
}
return true;
}

View File

@@ -43,5 +43,6 @@ int font_sprite_get_codepoint_sprite(int fontSpriteBase, int codepoint);
int font_get_size_from_sprite_base(uint16 spriteBase);
int font_get_line_height(int fontSpriteBase);
int font_get_line_height_small(int fontSpriteBase);
bool font_supports_string(const utf8 *text, int fontSize);
#endif

View File

@@ -881,8 +881,9 @@ static uint32 _ttf_getwidth_cache_get_or_add(TTF_Font *font, const utf8 *text)
bool ttf_initialise()
{
if (!_ttfInitialised) {
if (TTF_Init() != 0)
if (TTF_Init() != 0) {
return false;
}
for (int i = 0; i < 4; i++) {
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
@@ -893,6 +894,7 @@ bool ttf_initialise()
fontDesc->font = TTF_OpenFont(fontPath, fontDesc->ptSize);
if (fontDesc->font == NULL) {
log_error("Unable to load '%s'", fontPath);
return false;
}
}

View File

@@ -21,17 +21,18 @@
#include "currency.h"
#include "string_ids.h"
const rct_currency_spec g_currency_specs[CURRENCY_END] = {
{ 10 , "\xC2\xA3" , CURRENCY_PREFIX, STR_POUNDS }, // British Pound
{ 10 , "$" , CURRENCY_PREFIX, STR_DOLLARS}, // US Dollar
{ 10 , "F" , CURRENCY_SUFFIX, STR_FRANC }, // French Franc
{ 10 , "DM" , CURRENCY_PREFIX, STR_DEUTSCHMARK }, // Deutschmark
{ 1000 , "\xC2\xA5" , CURRENCY_PREFIX, STR_YEN }, // Japanese Yen
{ 10 , "Pts" , CURRENCY_SUFFIX, STR_PESETA }, // Spanish Peseta
{ 1000 , "L" , CURRENCY_PREFIX, STR_LIRA }, // Italian Lira
{ 10 , "fl. " , CURRENCY_PREFIX, STR_GUILDERS }, // Dutch Guilder
{ 10 , "kr." , CURRENCY_SUFFIX, STR_KRONA }, // Swedish Krona
{ 10 , "\xE2\x82\xAC" , CURRENCY_PREFIX, STR_EUROS }, // Euro
{ 10000 , "W" , CURRENCY_PREFIX, STR_WON }, // South Korean Won
{ 1000 , "R " , CURRENCY_PREFIX, STR_ROUBLE }, // Russian Rouble
const currency_descriptor CurrencyDescriptors[CURRENCY_END] = {
{ 10 , CURRENCY_PREFIX, "\xC2\xA3" , CURRENCY_SUFFIX, "GBP" , STR_POUNDS }, // British Pound
{ 10 , CURRENCY_PREFIX, "$" , CURRENCY_PREFIX, "$" , STR_DOLLARS }, // US Dollar
{ 10 , CURRENCY_SUFFIX, "F" , CURRENCY_SUFFIX, "F" , STR_FRANC }, // French Franc
{ 10 , CURRENCY_PREFIX, "DM" , CURRENCY_PREFIX, "DM" , STR_DEUTSCHMARK }, // Deutschmark
{ 1000 , CURRENCY_PREFIX, "\xC2\xA5" , CURRENCY_SUFFIX, "YEN" , STR_YEN }, // Japanese Yen
{ 10 , CURRENCY_SUFFIX, "Pts" , CURRENCY_SUFFIX, "Pts" , STR_PESETA }, // Spanish Peseta
{ 1000 , CURRENCY_PREFIX, "L" , CURRENCY_PREFIX, "L" , STR_LIRA }, // Italian Lira
{ 10 , CURRENCY_PREFIX, "\xC6\x92" , CURRENCY_PREFIX, "fl." , STR_GUILDERS }, // Dutch Guilder
{ 10 , CURRENCY_SUFFIX, "kr." , CURRENCY_SUFFIX, "kr." , STR_KRONA }, // Swedish Krona
{ 10 , CURRENCY_PREFIX, "\xE2\x82\xAC" , CURRENCY_SUFFIX, "EUR" , STR_EUROS }, // Euro
{ 10000 , CURRENCY_PREFIX, "\xE2\x82\xA9" , CURRENCY_PREFIX, "W" , STR_WON }, // South Korean Won
{ 1000 , CURRENCY_PREFIX, "R " , CURRENCY_PREFIX, "R " , STR_ROUBLE }, // Russian Rouble
{ 100 , CURRENCY_SUFFIX, " K\xC4\x8D" , CURRENCY_SUFFIX, " Kc" , STR_CZECH_KORUNA }, // Czech koruna
};

View File

@@ -37,6 +37,7 @@ typedef enum {
CURRENCY_EUROS, // Euro
CURRENCY_WON, // South Korean Won
CURRENCY_ROUBLE, // Russian Rouble
CURRENCY_CZECH_KORUNA, // Czech koruna
CURRENCY_END // Last item
} CURRENCY_TYPE;
@@ -50,14 +51,16 @@ typedef enum {
// Currency format specification - inspired by OpenTTD
typedef struct {
// Rate is relative to 0.1 GBP
// Rate is relative to 0.10 GBP
int rate;
utf8 symbol[CURRENCY_SYMBOL_MAX_SIZE];
int affix;
int stringId;
} rct_currency_spec;
uint8 affix_unicode;
utf8 symbol_unicode[CURRENCY_SYMBOL_MAX_SIZE];
uint8 affix_ascii;
char symbol_ascii[CURRENCY_SYMBOL_MAX_SIZE];
rct_string_id stringId;
} currency_descriptor;
// List of currency formats
extern const rct_currency_spec g_currency_specs[CURRENCY_END];
extern const currency_descriptor CurrencyDescriptors[CURRENCY_END];
#endif

View File

@@ -173,6 +173,11 @@ int language_open(int id)
gCurrentTTFFontSet = LanguagesDescriptors[id].font;
if (!ttf_initialise()) {
log_warning("Unable to initialise TrueType fonts.");
// Fall back to sprite font
gUseTrueTypeFont = false;
gCurrentTTFFontSet = nullptr;
return 0;
}
}

View File

@@ -345,9 +345,9 @@ void format_comma_separated_fixed_2dp(char **dest, long long value)
void format_currency(char **dest, long long value)
{
const rct_currency_spec *currencySpec = &g_currency_specs[gConfigGeneral.currency_format];
const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
int rate = currencySpec->rate;
int rate = currencyDesc->rate;
value *= rate;
// Negative sign
@@ -363,10 +363,15 @@ void format_currency(char **dest, long long value)
}
// Currency symbol
const utf8 *symbol = currencySpec->symbol;
const utf8 *symbol = currencyDesc->symbol_unicode;
uint8 affix = currencyDesc->affix_unicode;
if (!font_supports_string(symbol, FONT_SIZE_MEDIUM)) {
symbol = currencyDesc->symbol_ascii;
affix = currencyDesc->affix_ascii;
}
// Prefix
if (currencySpec->affix == CURRENCY_PREFIX) {
if (affix == CURRENCY_PREFIX) {
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
*dest += strlen(*dest);
}
@@ -374,7 +379,7 @@ void format_currency(char **dest, long long value)
format_comma_separated_integer(dest, value);
// Currency symbol suffix
if (currencySpec->affix == CURRENCY_SUFFIX) {
if (affix == CURRENCY_SUFFIX) {
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
*dest += strlen(*dest);
}
@@ -382,9 +387,9 @@ void format_currency(char **dest, long long value)
void format_currency_2dp(char **dest, long long value)
{
const rct_currency_spec *currencySpec = &g_currency_specs[gConfigGeneral.currency_format];
const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
int rate = currencySpec->rate;
int rate = currencyDesc->rate;
value *= rate;
// Negative sign
@@ -394,10 +399,15 @@ void format_currency_2dp(char **dest, long long value)
}
// Currency symbol
const utf8 *symbol = currencySpec->symbol;
const utf8 *symbol = currencyDesc->symbol_unicode;
uint8 affix = currencyDesc->affix_unicode;
if (!font_supports_string(symbol, FONT_SIZE_MEDIUM)) {
symbol = currencyDesc->symbol_ascii;
affix = currencyDesc->affix_ascii;
}
// Prefix
if (currencySpec->affix == CURRENCY_PREFIX) {
if (affix == CURRENCY_PREFIX) {
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
*dest += strlen(*dest);
}
@@ -410,7 +420,7 @@ void format_currency_2dp(char **dest, long long value)
}
// Currency symbol suffix
if (currencySpec->affix == CURRENCY_SUFFIX) {
if (affix == CURRENCY_SUFFIX) {
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
*dest += strlen(*dest);
}

View File

@@ -2174,6 +2174,8 @@ enum {
STR_UI_SCALING_DESC = 5579,
STR_CZECH_KORUNA = 5580,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
STR_COUNT = 32768
};

View File

@@ -251,10 +251,13 @@ bool openrct2_initialise()
audio_init();
audio_populate_devices();
}
if (!language_open(gConfigGeneral.language))
{
log_fatal("Failed to open language, exiting.");
return false;
if (!language_open(gConfigGeneral.language)) {
log_error("Failed to open configured language...");
if (!language_open(LANGUAGE_ENGLISH_UK)) {
log_fatal("Failed to open fallback language...");
return false;
}
}
http_init();

View File

@@ -803,7 +803,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
for (i = 0; i < num_items; i++) {
gDropdownItemsFormat[i] = 1142;
gDropdownItemsArgs[i] = g_currency_specs[i].stringId;
gDropdownItemsArgs[i] = CurrencyDescriptors[i].stringId;
}
window_options_show_dropdown(w, widget, num_items);
@@ -1204,7 +1204,7 @@ static void window_options_invalidate(rct_window *w)
case WINDOW_OPTIONS_PAGE_CULTURE:
// currency: pounds, dollars, etc. (10 total)
RCT2_GLOBAL(0x013CE952 + 12, uint16) = g_currency_specs[gConfigGeneral.currency_format].stringId;
RCT2_GLOBAL(0x013CE952 + 12, uint16) = CurrencyDescriptors[gConfigGeneral.currency_format].stringId;
// distance: metric/imperial
RCT2_GLOBAL(0x013CE952 + 14, uint16) = STR_IMPERIAL + gConfigGeneral.measurement_format;