From 5620edeb6be7c6bcdfd7c57166dd3b043bc0780c Mon Sep 17 00:00:00 2001 From: Dav999 Date: Fri, 5 Jan 2024 02:04:27 +0100 Subject: [PATCH] Fix orientation of levels list I forgot to add the PR_RTL_XFLIP flag to these menu options, so they were always left-aligned, no matter what. What actually took me a bit to figure out was how to make the level completion stars work regardless of the contents of the title - the stars should always be to the left of the title in an LTR language, and always to the right of the title in an RTL language. Level titles can contain bidi characters regardless of the level's rtl flag being set, so I just let bidi handle all the level menu options, with some control characters to make sure everything always appears in the correct order. --- desktop_version/src/Game.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 6ef9b09c..12a8d4e6 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -28,6 +28,7 @@ #include "Screen.h" #include "Script.h" #include "Unused.h" +#include "UTF8.h" #include "UtilityClass.h" #include "VFormat.h" #include "Vlogging.h" @@ -6346,8 +6347,22 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) prefix = ""; break; } + /* We have to make sure the stars and spaces are consistently on the + * correct side of the title, no matter what bidi characters are in there. + * So just always let the bidi engine handle it, with a few control chars. */ char text[MENU_TEXT_BYTES]; - SDL_snprintf(text, sizeof(text), "%s%s", prefix, cl.ListOfMetaData[i].title.c_str()); + SDL_snprintf( + text, sizeof(text), + "%s%s%s%s%s", + // LRM or RLM depending on UI language, to make the stars aligned to left or right + UTF8_encode(font::is_rtl(PR_FONT_INTERFACE) ? 0x200F : 0x200E).bytes, + prefix, + // FIRST STRONG ISOLATE, to start an isolated block oriented however bidi sees fit + UTF8_encode(0x2068).bytes, + cl.ListOfMetaData[i].title.c_str(), + // POP DIRECTIONAL ISOLATE, exit isolated level title + UTF8_encode(0x2069).bytes + ); for (size_t ii = 0; text[ii] != '\0'; ++ii) { text[ii] = SDL_tolower(text[ii]); @@ -6355,9 +6370,9 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) option( text, true, - cl.ListOfMetaData[i].title_is_gettext ? PR_FONT_INTERFACE : PR_FONT_IDX( - cl.ListOfMetaData[i].level_main_font_idx, cl.ListOfMetaData[i].rtl - ) + (cl.ListOfMetaData[i].title_is_gettext ? PR_FONT_INTERFACE : PR_FONT_IDX( + cl.ListOfMetaData[i].level_main_font_idx, font::is_rtl(PR_FONT_INTERFACE) + )) | PR_RTL_XFLIP ); } }