Split RTL implementations to files; add preprocessor guards

This commit is contained in:
Gymnasiast 2020-09-05 14:01:38 +02:00
parent f11d1294fe
commit 4ff77ebc35
No known key found for this signature in database
GPG Key ID: DBFFF47AB2CA3EDD
7 changed files with 130 additions and 70 deletions

View File

@ -22,6 +22,7 @@
<OPENRCT2_CL_ADDITIONALOPTIONS Condition="'$(OPENRCT2_SHA1_SHORT)'!=''">/D "OPENRCT2_COMMIT_SHA1_SHORT=\"$(OPENRCT2_SHA1_SHORT)\"" $(OPENRCT2_CL_ADDITIONALOPTIONS)</OPENRCT2_CL_ADDITIONALOPTIONS>
<OPENRCT2_CL_ADDITIONALOPTIONS Condition="'$(OPENRCT2_DESCRIBE)'!=''">/D "OPENRCT2_VERSION_TAG=\"$(OPENRCT2_DESCRIBE)\"" $(OPENRCT2_CL_ADDITIONALOPTIONS)</OPENRCT2_CL_ADDITIONALOPTIONS>
<OPENRCT2_CL_ADDITIONALOPTIONS Condition="'$(Configuration)'=='Release'">/D "USE_BREAKPAD" $(OPENRCT2_CL_ADDITIONALOPTIONS)</OPENRCT2_CL_ADDITIONALOPTIONS>
<OPENRCT2_CL_ADDITIONALOPTIONS Condition="'$(Platform)'=='Win32' || '$(Platform)'=='x64'">/D "USE_FRIBIDI" $(OPENRCT2_CL_ADDITIONALOPTIONS)</OPENRCT2_CL_ADDITIONALOPTIONS>
<RootDir>$(MsBuildThisFileDirectory)</RootDir>
<TargetDir>$(RootDir)bin\</TargetDir>

View File

@ -34,6 +34,7 @@
<ClCompile>
<PreprocessorDefinitions>__ENABLE_DISCORD__;__ENABLE_LIGHTFX__;USE_BENCHMARK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Breakpad)'=='true'">USE_BREAKPAD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='Win32' || '$(Platform)'=='x64'">USE_FRIBIDI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
@ -770,4 +771,4 @@
<ClCompile Include="world\Wall.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>

View File

@ -17,27 +17,12 @@
#include "../core/StringReader.hpp"
#include "Language.h"
#include "Localisation.h"
#include "RTL.h"
#include <algorithm>
#include <string>
#include <vector>
#ifdef _WIN32
extern "C" {
# include <fribidi/fribidi-bidi-types.h>
# include <fribidi/fribidi-char-sets.h>
# include <fribidi/fribidi-flags.h>
# include <fribidi/fribidi.h>
}
#else
# include <unicode/ubidi.h>
# include <unicode/unistr.h>
# include <unicode/ushape.h>
# include <unicode/ustring.h>
# include <unicode/utf.h>
# include <unicode/utypes.h>
#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;
@ -655,59 +640,6 @@ private:
return true;
}
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);
FriBidiStrIndex utf32len = 0;
for (; utf32len < 1024; utf32len++)
{
if (utf32String[utf32len] == 0)
{
break;
}
}
FriBidiChar reorderedStr[1024] = { 0 };
// All our strings start in LTR direction due to the "STR_0001: prefix", even fully Arabic ones.
FriBidiCharType pbase_dir = FRIBIDI_TYPE_LTR;
fribidi_log2vis(utf32String, utf32len, &pbase_dir, reorderedStr, nullptr, nullptr, nullptr);
char outputString[1024];
fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, reorderedStr, len, outputString);
return std::string(outputString);
#else
UErrorCode err = static_cast<UErrorCode>(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
}
};
namespace LanguagePackFactory

View File

@ -0,0 +1,63 @@
/*****************************************************************************
* Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#if defined(_WIN32) && defined(USE_FRIBIDI)
# include "RTL.h"
# include <string>
extern "C" {
# include <fribidi/fribidi-bidi-types.h>
# include <fribidi/fribidi-char-sets.h>
# include <fribidi/fribidi-flags.h>
# include <fribidi/fribidi.h>
}
static constexpr const uint16_t BufferLength = 1024;
std::string FixRTL(std::string& input)
{
FriBidiChar utf32String[BufferLength] = { 0 };
FriBidiStrIndex len = input.length() + 1;
fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, input.c_str(), len, utf32String);
FriBidiStrIndex utf32len = 0;
for (; utf32len < std::size(utf32String); utf32len++)
{
if (utf32String[utf32len] == 0)
{
break;
}
}
FriBidiChar reorderedStr[BufferLength] = { 0 };
// All our strings start in LTR direction due to the "STR_0001: prefix", even fully Arabic ones.
FriBidiCharType pbase_dir = FRIBIDI_TYPE_LTR;
fribidi_log2vis(utf32String, utf32len, &pbase_dir, reorderedStr, nullptr, nullptr, nullptr);
char outputString[BufferLength];
fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, reorderedStr, len, outputString);
return std::string(outputString);
}
#elif defined(_WIN32)
static bool hasWarned = false;
std::string FixRTL(std::string& input)
{
if (!hasWarned)
{
log_warning("This build of OpenRCT2 cannot properly handle right-to-left text!");
hasWarned = true;
}
return input;
}
#endif

View File

@ -0,0 +1,47 @@
/*****************************************************************************
* Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#ifndef _WIN32
# include "RTL.h"
# include <string>
# include <unicode/ubidi.h>
# include <unicode/unistr.h>
# include <unicode/ushape.h>
# include <unicode/ustring.h>
# include <unicode/utf.h>
# include <unicode/utypes.h>
std::string FixRTL(std::string& input)
{
UErrorCode err = static_cast<UErrorCode>(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

View File

@ -0,0 +1,14 @@
/*****************************************************************************
* Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include <string>
std::string FixRTL(std::string& input);

View File

@ -120,6 +120,8 @@ add_test(NAME sawyercoding COMMAND test_sawyercoding)
set(LANGUAGEPACK_TEST_SOURCES
"${CMAKE_CURRENT_LIST_DIR}/LanguagePackTest.cpp"
"${ROOT_DIR}/src/openrct2/localisation/LanguagePack.cpp"
"${ROOT_DIR}/src/openrct2/localisation/RTL.FriBidi.cpp"
"${ROOT_DIR}/src/openrct2/localisation/RTL.ICU.cpp"
)
add_executable(test_languagepack ${LANGUAGEPACK_TEST_SOURCES})
if (UNIX AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "BSD")