Offer Arabic and Persian wherever a text drawer can shape them

They were only listed on Windows and Android, from before the Cocoa and
SDL3_ttf drawers existed, so Mac, iOS and Linux didn't have them.

The SDL drawer now takes the paragraph direction from the RTL embedding
TextDrawer adds, and strips the marks before FriBidi sees them. Otherwise
the marks count as a second level, and every Arabic line would go through
FriBidi's reordering and shaping instead of SDL3_ttf's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-11-08 14:07:20 +01:00
1 parent 036c609c40
commit 1439187e54
2 files changed
+11 -4

No files matched your search

+9 -1
View File
@@ -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;
}
+2 -3
View File
@@ -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;
}