summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.lib1
-rw-r--r--src/lang/unfinished/persian.txt1
-rw-r--r--src/strgen/strgen.cpp17
-rw-r--r--src/strings.cpp27
-rw-r--r--src/strings_type.h7
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
};