diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index a141e10d96..8dcd0234d2 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -196,8 +196,6 @@ if (HAVE_DISCORD_RPC) target_link_libraries(libopenrct2 discord-rpc) endif() -target_link_libraries(libopenrct2 fribidi) - # Includes target_include_directories(${PROJECT_NAME} PRIVATE ${LIBZIP_INCLUDE_DIRS}) target_include_directories(${PROJECT_NAME} PRIVATE ${PNG_INCLUDE_DIRS} diff --git a/src/openrct2/localisation/LanguagePack.cpp b/src/openrct2/localisation/LanguagePack.cpp index b24ba013bc..81f19531e4 100644 --- a/src/openrct2/localisation/LanguagePack.cpp +++ b/src/openrct2/localisation/LanguagePack.cpp @@ -9,13 +9,6 @@ #include "LanguagePack.h" -extern "C" { -#include -#include -#include -#include -} - #include "../common.h" #include "../core/FileStream.hpp" #include "../core/Memory.hpp" @@ -29,6 +22,22 @@ extern "C" { #include #include +#ifdef _WIN32 +extern "C" { +# include +# include +# include +# include +} +#else +# include +# include +# include +# include +# include +# include +#endif + // Don't try to load more than language files that exceed 64 MiB constexpr uint64_t MAX_LANGUAGE_SIZE = 64 * 1024 * 1024; constexpr uint64_t MAX_OBJECT_OVERRIDES = 4096; @@ -649,6 +658,7 @@ private: std::string FixRTL(std::string& input) { +#ifdef _WIN32 FriBidiChar utf32String[1024] = { 0 }; FriBidiStrIndex len = input.length() + 1; fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, input.c_str(), len, utf32String); @@ -672,6 +682,31 @@ private: fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, reorderedStr, len, outputString); return std::string(outputString); +#else + UErrorCode err = static_cast(0); + // Force a hard left-to-right at the beginning (will mess up mixed strings' word order otherwise) + std::string text2 = std::string(u8"\xE2\x80\xAA") + input; + + icu::UnicodeString ustr = icu::UnicodeString::fromUTF8(icu::StringPiece(text2)); + + int32_t length = ustr.length(); + icu::UnicodeString reordered; + icu::UnicodeString shaped; + UBiDi* bidi = ubidi_openSized(length, 0, &err); + // UBIDI_DEFAULT_LTR preserves formatting codes. + ubidi_setPara(bidi, ustr.getBuffer(), length, UBIDI_DEFAULT_LTR, nullptr, &err); + ubidi_writeReordered(bidi, reordered.getBuffer(length), length, UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &err); + ubidi_close(bidi); + reordered.releaseBuffer(length); + u_shapeArabic( + reordered.getBuffer(), length, shaped.getBuffer(length), length, + U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_NEAR | U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, &err); + shaped.releaseBuffer(length); + + std::string cppstring; + shaped.toUTF8String(cppstring); + return cppstring; +#endif } };