diff --git a/Common/Render/Text/draw_text_sdl.cpp b/Common/Render/Text/draw_text_sdl.cpp index ab93190da6..02a08072d6 100644 --- a/Common/Render/Text/draw_text_sdl.cpp +++ b/Common/Render/Text/draw_text_sdl.cpp @@ -58,6 +58,15 @@ static bool ReorderBidi(std::string_view str, std::string *out) { result.push_back('\n'); } std::string_view line = lines[i]; + FriBidiParType baseDir = FRIBIDI_PAR_ON; + // TextDrawer::ApplyBaseDirection wraps RTL lines in RLE ... PDF. Take the direction from that instead, + // so the marks don't count as a second level and send pure Arabic lines down the reordering path. + const std::string_view rle = "\xE2\x80\xAB"; + const std::string_view pdf = "\xE2\x80\xAC"; + if (line.size() >= rle.size() + pdf.size() && startsWith(line, rle) && endsWith(line, pdf)) { + line = line.substr(rle.size(), line.size() - rle.size() - pdf.size()); + baseDir = FRIBIDI_PAR_RTL; + } logical.resize(line.size() + 1); FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, line.data(), (FriBidiStrIndex)line.size(), logical.data()); if (len <= 0) { @@ -66,7 +75,6 @@ static bool ReorderBidi(std::string_view str, std::string *out) { } visual.resize(len + 1); levels.resize(len); - FriBidiParType baseDir = FRIBIDI_PAR_ON; if (!fribidi_log2vis(logical.data(), len, &baseDir, visual.data(), nullptr, nullptr, levels.data())) { return false; } diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index c5e981a65f..941bd0c755 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -304,9 +304,8 @@ NewLanguageScreen::NewLanguageScreen(std::string_view title) : ListPopupScreen(t continue; } - // We only support Arabic on platforms where we have support for the native text rendering - // APIs, as proper Arabic support is way too difficult to implement ourselves. -#if !(PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID)) + // Arabic script needs a text drawer that does shaping (see TextDrawer::Create), the atlas font can't. +#if defined(__LIBRETRO__) || !(PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS) || defined(USE_SDL3_TTF)) if (tempLangs[i].name.find("ar_AE") != std::string::npos) { continue; }