(svn r14480) -Add: warning when trying to use a right-to-left language without support for it in OpenTTD.
authorrubidium
Fri, 17 Oct 2008 17:42:51 +0000
changeset 10249 77b68778b102
parent 10248 f0297aac2ff2
child 10250 da7d3c53747d
(svn r14480) -Add: warning when trying to use a right-to-left language without support for it in OpenTTD.
config.lib
src/lang/unfinished/persian.txt
src/strgen/strgen.cpp
src/strings.cpp
src/strings_type.h
--- a/config.lib	Fri Oct 17 17:14:09 2008 +0000
+++ b/config.lib	Fri Oct 17 17:42:51 2008 +0000
@@ -2634,6 +2634,7 @@
 	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"
--- a/src/lang/unfinished/persian.txt	Fri Oct 17 17:14:09 2008 +0000
+++ b/src/lang/unfinished/persian.txt	Fri Oct 17 17:42:51 2008 +0000
@@ -2,6 +2,7 @@
 ##ownname Farsi
 ##isocode fa_IR
 ##plural 0
+##textdir rtl
 
 #
 
--- a/src/strgen/strgen.cpp	Fri Oct 17 17:14:09 2008 +0000
+++ b/src/strgen/strgen.cpp	Fri Oct 17 17:42:51 2008 +0000
@@ -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 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 @@
 		_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 @@
 	/* 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 @@
 	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);
--- a/src/strings.cpp	Fri Oct 17 17:14:09 2008 +0000
+++ b/src/strings.cpp	Fri Oct 17 17:42:51 2008 +0000
@@ -61,7 +61,8 @@
 	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 @@
 	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 @@
 			}
 		}
 	}
+
+#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
+
 }
 
 
--- a/src/strings_type.h	Fri Oct 17 17:14:09 2008 +0000
+++ b/src/strings_type.h	Fri Oct 17 17:42:51 2008 +0000
@@ -15,6 +15,12 @@
 	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 @@
 	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
 };