diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 91f40cd396..3bd50bb871 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -285,7 +285,10 @@ struct IConsoleWindow : Window break; case WKC_RETURN: case WKC_NUM_ENTER: { - IConsolePrintF(CC_COMMAND, "] %s", _iconsole_cmdline.buf); + /* We always want the ] at the left side; we always force these strings to be left + * aligned anyway. So enforce this in all cases by addding a left-to-right marker, + * otherwise it will be drawn at the wrong side with right-to-left texts. */ + IConsolePrintF(CC_COMMAND, LRM "] %s", _iconsole_cmdline.buf); const char *cmd = IConsoleHistoryAdd(_iconsole_cmdline.buf); IConsoleClearCommand(); diff --git a/src/network/network.cpp b/src/network/network.cpp index 68d3887f23..7d3dbbe13a 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -202,7 +202,13 @@ void NetworkTextMessage(NetworkAction action, ConsoleColour colour, bool self_se SetDParamStr(0, name); SetDParamStr(1, str); SetDParam(2, data); - GetString(message, strid, lastof(message)); + + /* All of these strings start with "***". These characters are interpreted as both left-to-right and + * right-to-left characters depending on the context. As the next text might be an user's name, the + * user name's characters will influence the direction of the "***" instead of the language setting + * of the game. Manually set the direction of the "***" by inserting a text-direction marker. */ + char *msg_ptr = message + Utf8Encode(message, _dynlang.text_dir == TD_LTR ? CHAR_TD_LRM : CHAR_TD_RLM); + GetString(msg_ptr, strid, lastof(message)); DEBUG(desync, 1, "msg: %08x; %02x; %s", _date, _date_fract, message); IConsolePrintF(colour, "%s", message); diff --git a/src/string_type.h b/src/string_type.h index 7fb8e01378..9532c86ad5 100644 --- a/src/string_type.h +++ b/src/string_type.h @@ -15,6 +15,9 @@ /** A non-breaking space. */ #define NBSP "\xC2\xA0" +/** A left-to-right marker, marks the next character as left-to-right. */ +#define LRM "\xE2\x80\x8E" + /** * Valid filter types for IsValidChar. */ @@ -28,4 +31,14 @@ enum CharSetFilter { typedef uint32 WChar; +/* The following are directional formatting codes used to get the LTR and RTL strings right: + * http://www.unicode.org/unicode/reports/tr9/#Directional_Formatting_Codes */ +static const WChar CHAR_TD_LRM = 0x200E; ///< The next character acts like a left-to-right character. +static const WChar CHAR_TD_RLM = 0x200F; ///< The next character acts like a right-to-left character. +static const WChar CHAR_TD_LRE = 0x202A; ///< The following text is embedded left-to-right. +static const WChar CHAR_TD_RLE = 0x202B; ///< The following text is embedded right-to-left. +static const WChar CHAR_TD_LRO = 0x202D; ///< Force the following characters to be treated as left-to-right characters. +static const WChar CHAR_TD_RLO = 0x202E; ///< Force the following characters to be treated as right-to-left characters. +static const WChar CHAR_TD_PDF = 0x202C; ///< Restore the text-direction state to before the last LRE, RLE, LRO or RLO. + #endif /* STRING_TYPE_H */ diff --git a/src/table/strgen_tables.h b/src/table/strgen_tables.h index e8f827ee2c..b6facd5d79 100644 --- a/src/table/strgen_tables.h +++ b/src/table/strgen_tables.h @@ -137,13 +137,13 @@ static const CmdStruct _cmd_structs[] = { /* The following are directional formatting codes used to get the RTL strings right: * http://www.unicode.org/unicode/reports/tr9/#Directional_Formatting_Codes */ - {"LRM", EmitSingleChar, 0x200E, 0, C_DONTCOUNT}, - {"RLM", EmitSingleChar, 0x200F, 0, C_DONTCOUNT}, - {"LRE", EmitSingleChar, 0x202A, 0, C_DONTCOUNT}, - {"RLE", EmitSingleChar, 0x202B, 0, C_DONTCOUNT}, - {"LRO", EmitSingleChar, 0x202D, 0, C_DONTCOUNT}, - {"RLO", EmitSingleChar, 0x202E, 0, C_DONTCOUNT}, - {"PDF", EmitSingleChar, 0x202C, 0, C_DONTCOUNT}, + {"LRM", EmitSingleChar, CHAR_TD_LRM, 0, C_DONTCOUNT}, + {"RLM", EmitSingleChar, CHAR_TD_RLM, 0, C_DONTCOUNT}, + {"LRE", EmitSingleChar, CHAR_TD_LRE, 0, C_DONTCOUNT}, + {"RLE", EmitSingleChar, CHAR_TD_RLE, 0, C_DONTCOUNT}, + {"LRO", EmitSingleChar, CHAR_TD_LRO, 0, C_DONTCOUNT}, + {"RLO", EmitSingleChar, CHAR_TD_RLO, 0, C_DONTCOUNT}, + {"PDF", EmitSingleChar, CHAR_TD_PDF, 0, C_DONTCOUNT}, }; /** Description of a plural form */