From b8242601ecfdbad93d57493b66727b73025c8860 Mon Sep 17 00:00:00 2001 From: Michael Burgardt Date: Mon, 14 Feb 2022 02:43:55 +0100 Subject: [PATCH] Fix localisations (#13622) * Fix translations with messed-up string placement * Fix Hebrew and Persian text display Hebrew is now displayed properly as right-to-left. Miscellaneous whitespaces, like the zero width non-joiner used in Persian, no longer break right-to-left texts. --- gfx/font_driver.c | 38 ++++++++++++++++++++++++++++++-------- intl/msg_hash_ast.c | 9 ++++++++- intl/msg_hash_fa.c | 11 ++++++++++- intl/msg_hash_he.c | 11 ++++++++++- intl/msg_hash_sk.c | 11 ++++++++++- 5 files changed, 68 insertions(+), 12 deletions(-) diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 3fc2538c93..9e996128e8 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -797,21 +797,27 @@ static bool font_init_first( #ifdef HAVE_LANGEXTRA -/* ACII: 0xxxxxxx (c & 0x80) == 0x00 +/* ASCII: 0xxxxxxx (c & 0x80) == 0x00 * other start: 11xxxxxx (c & 0xC0) == 0xC0 * other cont: 10xxxxxx (c & 0xC0) == 0x80 - * Neutral : - * 0020 - 002F : 001xxxxx (c & 0xE0) == 0x20 + * Neutral: + * 0020 - 002F: 001xxxxx (c & 0xE0) == 0x20 + * misc. white space: + * 2000 - 200D: 11100010 10000000 1000xxxx (c[2] < 0x8E) (3 bytes) + * Hebrew: + * 0591 - 05F4: 1101011x (c & 0xFE) == 0xD6 (2 bytes) * Arabic: - * 0600 - 06FF : 110110xx (c & 0xFC) == 0xD8 (2 bytes) */ + * 0600 - 06FF: 110110xx (c & 0xFC) == 0xD8 (2 bytes) + */ /* clang-format off */ #define IS_ASCII(p) ((*(p)&0x80) == 0x00) #define IS_MBSTART(p) ((*(p)&0xC0) == 0xC0) #define IS_MBCONT(p) ((*(p)&0xC0) == 0x80) #define IS_DIR_NEUTRAL(p) ((*(p)&0xE0) == 0x20) +#define IS_HEBREW(p) ((*(p)&0xFE) == 0xD6) #define IS_ARABIC(p) ((*(p)&0xFC) == 0xD8) -#define IS_RTL(p) IS_ARABIC(p) +#define IS_RTL(p) (IS_HEBREW(p) || IS_ARABIC(p)) #define GET_ID_ARABIC(p) (((unsigned char)(p)[0] << 6) | ((unsigned char)(p)[1] & 0x3F)) /* 0x0620 to 0x064F */ @@ -951,6 +957,22 @@ static const unsigned arabic_shape_map[0x100][0x4] = { }; /* clang-format on */ +/* Checks for miscellaneous whitespace characters in the range U+2000 to U+200D */ +static INLINE unsigned is_misc_ws(const unsigned char* src) +{ + unsigned res = 0; + if (*(src) == 0xE2) /* first byte */ + { + src++; + if (*(src) == 0x80) /* second byte */ + { + src++; + res = (*(src) < 0x8E); /* third byte */ + } + } + return res; +} + static INLINE unsigned font_get_replacement(const char* src, const char* start) { if (IS_ARABIC(src)) /* 0x0600 to 0x06FF */ @@ -1063,7 +1085,7 @@ static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, siz while (src > (const unsigned char*)msg && IS_MBCONT(src)) src--; - if (src >= (const unsigned char*)msg && (IS_RTL(src) || IS_DIR_NEUTRAL(src))) + if (src >= (const unsigned char*)msg && (IS_RTL(src) || IS_DIR_NEUTRAL(src) || is_misc_ws(src))) { unsigned replacement = font_get_replacement((const char*)src, msg); if (replacement) @@ -1108,7 +1130,7 @@ static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, siz { reverse = false; src++; - while (IS_MBCONT(src) || IS_RTL(src) || IS_DIR_NEUTRAL(src)) + while (IS_MBCONT(src) || IS_RTL(src) || IS_DIR_NEUTRAL(src) || is_misc_ws(src)) src++; } } @@ -1117,7 +1139,7 @@ static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, siz if (IS_RTL(src)) { reverse = true; - while (IS_MBCONT(src) || IS_RTL(src) || IS_DIR_NEUTRAL(src)) + while (IS_MBCONT(src) || IS_RTL(src) || IS_DIR_NEUTRAL(src) || is_misc_ws(src)) src++; } else diff --git a/intl/msg_hash_ast.c b/intl/msg_hash_ast.c index e82db85a69..4849c23590 100644 --- a/intl/msg_hash_ast.c +++ b/intl/msg_hash_ast.c @@ -12,10 +12,17 @@ * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ + +#include #include -#include +#include + +#include +#include #include "../msg_hash.h" +#include "../configuration.h" +#include "../verbosity.h" #if defined(_MSC_VER) && !defined(_XBOX) && (_MSC_VER >= 1500 && _MSC_VER < 1900) #if (_MSC_VER >= 1700) diff --git a/intl/msg_hash_fa.c b/intl/msg_hash_fa.c index b04335f8ec..0a588e6a84 100644 --- a/intl/msg_hash_fa.c +++ b/intl/msg_hash_fa.c @@ -12,10 +12,16 @@ * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ + +#include #include -#include +#include + +#include +#include #include "../msg_hash.h" +#include "../verbosity.h" #if defined(_MSC_VER) && !defined(_XBOX) && (_MSC_VER >= 1500 && _MSC_VER < 1900) #if (_MSC_VER >= 1700) @@ -25,6 +31,8 @@ #pragma warning(disable:4566) #endif +#ifdef RARCH_INTERNAL +#include "../configuration.h" int msg_hash_get_help_fa_enum(enum msg_hash_enums msg, char *s, size_t len) { int ret = 0; @@ -39,6 +47,7 @@ int msg_hash_get_help_fa_enum(enum msg_hash_enums msg, char *s, size_t len) return ret; } +#endif const char *msg_hash_to_str_fa(enum msg_hash_enums msg) { diff --git a/intl/msg_hash_he.c b/intl/msg_hash_he.c index e3e52874da..6019dedac2 100644 --- a/intl/msg_hash_he.c +++ b/intl/msg_hash_he.c @@ -12,10 +12,16 @@ * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ + +#include #include -#include +#include + +#include +#include #include "../msg_hash.h" +#include "../verbosity.h" #if defined(_MSC_VER) && !defined(_XBOX) && (_MSC_VER >= 1500 && _MSC_VER < 1900) #if (_MSC_VER >= 1700) @@ -25,6 +31,8 @@ #pragma warning(disable:4566) #endif +#ifdef RARCH_INTERNAL +#include "../configuration.h" int msg_hash_get_help_he_enum(enum msg_hash_enums msg, char *s, size_t len) { int ret = 0; @@ -39,6 +47,7 @@ int msg_hash_get_help_he_enum(enum msg_hash_enums msg, char *s, size_t len) return ret; } +#endif const char *msg_hash_to_str_he(enum msg_hash_enums msg) { diff --git a/intl/msg_hash_sk.c b/intl/msg_hash_sk.c index b9ec2f83f3..14a1f8244d 100644 --- a/intl/msg_hash_sk.c +++ b/intl/msg_hash_sk.c @@ -12,10 +12,16 @@ * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ + +#include #include -#include +#include + +#include +#include #include "../msg_hash.h" +#include "../verbosity.h" #if defined(_MSC_VER) && !defined(_XBOX) && (_MSC_VER >= 1500 && _MSC_VER < 1900) #if (_MSC_VER >= 1700) @@ -25,6 +31,8 @@ #pragma warning(disable:4566) #endif +#ifdef RARCH_INTERNAL +#include "../configuration.h" int msg_hash_get_help_sk_enum(enum msg_hash_enums msg, char *s, size_t len) { int ret = 0; @@ -39,6 +47,7 @@ int msg_hash_get_help_sk_enum(enum msg_hash_enums msg, char *s, size_t len) return ret; } +#endif const char *msg_hash_to_str_sk(enum msg_hash_enums msg) {