mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-22 06:23:04 +01:00
Fix banner text formatting, import / export
This commit is contained in:
@@ -509,6 +509,13 @@ namespace String
|
||||
return utf8_write_codepoint(dst, codepoint);
|
||||
}
|
||||
|
||||
void AppendCodepoint(std::string& str, codepoint_t codepoint)
|
||||
{
|
||||
char buffer[8]{};
|
||||
utf8_write_codepoint(buffer, codepoint);
|
||||
str.append(buffer);
|
||||
}
|
||||
|
||||
bool IsWhiteSpace(codepoint_t codepoint)
|
||||
{
|
||||
// 0x3000 is the 'ideographic space', a 'fullwidth' character used in CJK languages.
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace String
|
||||
codepoint_t GetNextCodepoint(utf8* ptr, utf8** nextPtr = nullptr);
|
||||
codepoint_t GetNextCodepoint(const utf8* ptr, const utf8** nextPtr = nullptr);
|
||||
utf8* WriteCodepoint(utf8* dst, codepoint_t codepoint);
|
||||
void AppendCodepoint(std::string& str, codepoint_t codepoint);
|
||||
|
||||
bool IsWhiteSpace(codepoint_t codepoint);
|
||||
utf8* Trim(utf8* str);
|
||||
|
||||
@@ -3006,7 +3006,8 @@ private:
|
||||
const auto originalString = _s4.string_table[(stringId - USER_STRING_START) % 1024];
|
||||
std::string_view originalStringView(originalString, USER_STRING_MAX_LENGTH);
|
||||
auto asUtf8 = rct2_to_utf8(originalStringView, RCT2_LANGUAGE_ID_ENGLISH_UK);
|
||||
return asUtf8.data();
|
||||
auto justText = RCT12RemoveFormattingUTF8(asUtf8);
|
||||
return justText.data();
|
||||
}
|
||||
|
||||
void FixLandOwnership()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "RCT12.h"
|
||||
|
||||
#include "../core/String.hpp"
|
||||
#include "../localisation/Localisation.h"
|
||||
#include "../ride/Track.h"
|
||||
#include "../world/Banner.h"
|
||||
@@ -1041,6 +1042,24 @@ RCT12RideId OpenRCT2RideIdToRCT12RideId(const ride_id_t rideId)
|
||||
return rideId;
|
||||
}
|
||||
|
||||
static bool RCT12IsFormatChar(codepoint_t c)
|
||||
{
|
||||
if (c >= RCT2_STRING_FORMAT_ARG_START && c <= RCT2_STRING_FORMAT_ARG_END)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (c >= RCT2_STRING_FORMAT_COLOUR_START && c <= RCT2_STRING_FORMAT_COLOUR_END)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool RCT12IsFormatChar(char c)
|
||||
{
|
||||
return RCT12IsFormatChar(static_cast<codepoint_t>(c));
|
||||
}
|
||||
|
||||
bool IsLikelyUTF8(std::string_view s)
|
||||
{
|
||||
// RCT2 uses CP-1252 so some characters may be >= 128. However we don't expect any
|
||||
@@ -1048,15 +1067,28 @@ bool IsLikelyUTF8(std::string_view s)
|
||||
// that the string is UTF-8.
|
||||
for (auto c : s)
|
||||
{
|
||||
auto chr = static_cast<uint8_t>(c);
|
||||
if (chr >= RCT2_STRING_FORMAT_ARG_START && chr <= RCT2_STRING_FORMAT_ARG_END)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (chr >= RCT2_STRING_FORMAT_COLOUR_START && chr <= RCT2_STRING_FORMAT_COLOUR_END)
|
||||
if (RCT12IsFormatChar(c))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string RCT12RemoveFormattingUTF8(std::string_view s)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(s.size() * 2);
|
||||
|
||||
CodepointView codepoints(s);
|
||||
for (auto codepoint : codepoints)
|
||||
{
|
||||
if (!RCT12IsFormatChar(codepoint))
|
||||
{
|
||||
String::AppendCodepoint(result, codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
result.shrink_to_fit();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -868,3 +868,4 @@ RCT12ObjectEntryIndex OpenRCT2EntryIndexToRCTEntryIndex(const ObjectEntryIndex i
|
||||
ride_id_t RCT12RideIdToOpenRCT2RideId(const RCT12RideId rideId);
|
||||
RCT12RideId OpenRCT2RideIdToRCT12RideId(const ride_id_t rideId);
|
||||
bool IsLikelyUTF8(std::string_view s);
|
||||
std::string RCT12RemoveFormattingUTF8(std::string_view s);
|
||||
|
||||
@@ -1367,12 +1367,13 @@ void S6Exporter::ExportBanner(RCT12Banner& dst, const Banner& src)
|
||||
|
||||
dst.string_idx = STR_DEFAULT_SIGN;
|
||||
|
||||
auto bannerText = src.text;
|
||||
std::string bannerText;
|
||||
if (!(src.flags & BANNER_FLAG_IS_WALL) && !(src.flags & BANNER_FLAG_IS_LARGE_SCENERY))
|
||||
{
|
||||
auto formatCode = static_cast<char>(RCT2_STRING_FORMAT_COLOUR_START + src.text_colour);
|
||||
bannerText.insert(bannerText.begin(), formatCode);
|
||||
auto formatCode = static_cast<codepoint_t>(RCT2_STRING_FORMAT_COLOUR_START + src.text_colour);
|
||||
String::AppendCodepoint(bannerText, formatCode);
|
||||
}
|
||||
bannerText.append(src.text);
|
||||
|
||||
auto stringId = AllocateUserString(bannerText);
|
||||
if (stringId != std::nullopt)
|
||||
|
||||
@@ -1661,7 +1661,8 @@ public:
|
||||
const auto originalString = _s6.custom_strings[(stringId - USER_STRING_START) % 1024];
|
||||
std::string_view originalStringView(originalString, USER_STRING_MAX_LENGTH);
|
||||
auto asUtf8 = rct2_to_utf8(originalStringView, RCT2_LANGUAGE_ID_ENGLISH_UK);
|
||||
return asUtf8.data();
|
||||
auto justText = RCT12RemoveFormattingUTF8(asUtf8);
|
||||
return justText.data();
|
||||
}
|
||||
|
||||
std::vector<rct_object_entry> GetRequiredObjects()
|
||||
|
||||
@@ -46,8 +46,15 @@ void Banner::FormatTextTo(Formatter& ft, bool addColour) const
|
||||
{
|
||||
auto formatToken = FormatTokenFromTextColour(text_colour);
|
||||
auto tokenText = FormatTokenToString(formatToken);
|
||||
|
||||
thread_local std::string tokenTextColourBuffer;
|
||||
tokenTextColourBuffer.clear();
|
||||
tokenTextColourBuffer.push_back('{');
|
||||
tokenTextColourBuffer.append(tokenText);
|
||||
tokenTextColourBuffer.push_back('}');
|
||||
|
||||
ft.Add<rct_string_id>(STR_STRING_STRINGID);
|
||||
ft.Add<const char*>(tokenText.data());
|
||||
ft.Add<const char*>(tokenTextColourBuffer.c_str());
|
||||
}
|
||||
|
||||
FormatTextTo(ft);
|
||||
|
||||
Reference in New Issue
Block a user