diff options
-rw-r--r-- | config.lib | 1 | ||||
-rw-r--r-- | src/lang/unfinished/persian.txt | 1 | ||||
-rw-r--r-- | src/strgen/strgen.cpp | 17 | ||||
-rw-r--r-- | src/strings.cpp | 27 | ||||
-rw-r--r-- | src/strings_type.h | 7 |
5 files changed, 50 insertions, 3 deletions
diff --git a/config.lib b/config.lib index 05d4ec449..637d20b59 100644 --- a/config.lib +++ b/config.lib @@ -2634,6 +2634,7 @@ showhelp() { echo " enables libfreetype support" echo " --with-fontconfig[=pkg-config fontconfig]" echo " enables fontconfig support" + echo " --with-icu[=icu-config] enables icu (used for right-to-left support)" echo " --with-iconv[=iconv-path] enables iconv support" echo " --with-psp-config[=psp-config] enables psp-config support (PSP ONLY)" echo " --with-makedepend[=makedepend] enables makedepend support" diff --git a/src/lang/unfinished/persian.txt b/src/lang/unfinished/persian.txt index 7c6cfd0dd..a60062b1f 100644 --- a/src/lang/unfinished/persian.txt +++ b/src/lang/unfinished/persian.txt @@ -2,6 +2,7 @@ ##ownname Farsi ##isocode fa_IR ##plural 0 +##textdir rtl # diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp index 00766bd2d..403050104 100644 --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -6,6 +6,7 @@ #include "../core/alloc_func.hpp" #include "../core/endian_func.hpp" #include "../string_func.h" +#include "../strings_type.h" #include "../table/control_codes.h" #include <stdio.h> @@ -35,14 +36,15 @@ typedef void (*ParseCmdProc)(char *buf, int value); struct LanguagePackHeader { - uint32 ident; + uint32 ident; // 32-bits identifier uint32 version; // 32-bits of auto generated version info which is basically a hash of strings.h char name[32]; // the international name of this language char own_name[32]; // the localized name of this language char isocode[16]; // the ISO code for the language (not country code) uint16 offsets[32]; // the offsets byte plural_form; // plural form index - byte pad[3]; // pad header to be a multiple of 4 + byte text_dir; // default direction of the text + byte pad[2]; // pad header to be a multiple of 4 }; struct CmdStruct { @@ -95,6 +97,7 @@ static int _next_string_id; static uint32 _hash; static char _lang_name[32], _lang_ownname[32], _lang_isocode[16]; static byte _lang_pluralform; +static byte _lang_textdir; #define MAX_NUM_GENDER 8 static char _genders[MAX_NUM_GENDER][8]; static int _numgenders; @@ -649,6 +652,14 @@ static void HandlePragma(char *str) _lang_pluralform = atoi(str + 7); if (_lang_pluralform >= lengthof(_plural_form_counts)) error("Invalid pluralform %d", _lang_pluralform); + } else if (!memcmp(str, "textdir ", 8)) { + if (!memcmp(str + 8, "ltr", 3)) { + _lang_textdir = TD_LTR; + } else if (!memcmp(str + 8, "rtl", 3)) { + _lang_textdir = TD_RTL; + } else { + error("Invalid textdir %s", str + 8); + } } else if (!memcmp(str, "gender ", 7)) { char* buf = str + 7; @@ -911,6 +922,7 @@ static void ParseFile(const char *file, bool english) /* For each new file we parse, reset the genders, and language codes */ _numgenders = 0; _lang_name[0] = _lang_ownname[0] = _lang_isocode[0] = '\0'; + _lang_textdir = TD_LTR; // TODO:!! We can't reset the cases. In case the translated strings // derive some strings from english.... @@ -1159,6 +1171,7 @@ static void WriteLangfile(const char *filename) hdr.ident = TO_LE32(0x474E414C); // Big Endian value for 'LANG' hdr.version = TO_LE32(_hash); hdr.plural_form = _lang_pluralform; + hdr.text_dir = _lang_textdir; strcpy(hdr.name, _lang_name); strcpy(hdr.own_name, _lang_ownname); strcpy(hdr.isocode, _lang_isocode); diff --git a/src/strings.cpp b/src/strings.cpp index 5d85f8cf5..ee0ad8625 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -61,7 +61,8 @@ struct LanguagePack { char isocode[16]; // the ISO code for the language (not country code) uint16 offsets[32]; // the offsets byte plural_form; // how to compute plural forms - byte pad[3]; // pad header to be a multiple of 4 + byte text_dir; // default direction of the text + byte pad[2]; // pad header to be a multiple of 4 char data[VARARRAY_SIZE]; // list of strings }; @@ -1273,6 +1274,7 @@ bool ReadLanguagePack(int lang_index) ttd_strlcpy(_dynlang.curr_file, c_file, lengthof(_dynlang.curr_file)); _dynlang.curr = lang_index; + _dynlang.text_dir = (TextDirection)lang_pack->text_dir; SetCurrentGrfLangID(_langpack->isocode); SortNetworkLanguages(); return true; @@ -1511,6 +1513,29 @@ void CheckForMissingGlyphsInLoadedLanguagePack() } } } + +#if !defined(WITH_ICU) + /* + * For right-to-left languages we need the ICU library. If + * we do not have support for that library we warn the user + * about it with a message. As we do not want the string to + * be translated by the translators, we 'force' it into the + * binary and 'load' it via a BindCString. To do this + * properly we have to set the color of the string, + * otherwise we end up with a lot of artefacts. The color + * 'character' might change in the future, so for safety + * we just Utf8 Encode it into the string, which takes + * exactly three characters, so it replaces the "XXX" with + * the color marker. + */ + if (_dynlang.text_dir != TD_LTR) { + static char *err_str = strdup("XXXThis version of OpenTTD does not support right-to-left languages. Recompile with icu enabled."); + Utf8Encode(err_str, SCC_YELLOW); + SetDParamStr(0, err_str); + ShowErrorMessage(INVALID_STRING_ID, STR_JUST_RAW_STRING, 0, 0); + } +#endif + } diff --git a/src/strings_type.h b/src/strings_type.h index 00c7d6538..481808570 100644 --- a/src/strings_type.h +++ b/src/strings_type.h @@ -15,6 +15,12 @@ enum { MAX_LANG = 64, ///< Maximal number of languages supported by the game }; +/** Directions a text can go to */ +enum TextDirection { + TD_LTR, ///< Text is written left-to-right by default + TD_RTL, ///< Text is written right-to-left by default +}; + /** Information about a language */ struct Language { char *name; ///< The internal name of the language @@ -26,6 +32,7 @@ struct DynamicLanguages { int num; ///< Number of languages int curr; ///< Currently selected language index char curr_file[MAX_PATH]; ///< Currently selected language file name without path (needed for saving the filename of the loaded language). + TextDirection text_dir; ///< Text direction of the currently selected language Language ent[MAX_LANG]; ///< Information about the languages }; |