Create a compile-time table for converting color codepoints to utf8 (#11349)

For this to be possible, the function to convert a codepoint to urf8 was
moved to the header and made constexpr.

Now it's not necessary to store a std::string just to serve as a buffer
for holding this string. All the computation is done at compile time.
This commit is contained in:
Breno Rodrigues Guimarães 2020-04-19 10:51:01 -03:00 committed by GitHub
parent deb56c2a72
commit 3c1bdcd201
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 37 deletions

View File

@ -95,7 +95,6 @@ const char* language_get_string(rct_string_id id);
bool language_open(int32_t id);
uint32_t utf8_get_next(const utf8* char_ptr, const utf8** nextchar_ptr);
utf8* utf8_write_codepoint(utf8* dst, uint32_t codepoint);
int32_t utf8_insert_codepoint(utf8* dst, uint32_t codepoint);
bool utf8_is_codepoint_start(const utf8* text);
void utf8_remove_format_codes(utf8* text, bool allowcolours);
@ -109,4 +108,34 @@ void language_free_object_string(rct_string_id stringId);
rct_string_id language_get_object_override_string_id(const char* identifier, uint8_t index);
rct_string_id language_allocate_object_string(const std::string& target);
constexpr utf8* utf8_write_codepoint(utf8* dst, uint32_t codepoint)
{
if (codepoint <= 0x7F)
{
dst[0] = (utf8)codepoint;
return dst + 1;
}
else if (codepoint <= 0x7FF)
{
dst[0] = 0xC0 | ((codepoint >> 6) & 0x1F);
dst[1] = 0x80 | (codepoint & 0x3F);
return dst + 2;
}
else if (codepoint <= 0xFFFF)
{
dst[0] = 0xE0 | ((codepoint >> 12) & 0x0F);
dst[1] = 0x80 | ((codepoint >> 6) & 0x3F);
dst[2] = 0x80 | (codepoint & 0x3F);
return dst + 3;
}
else
{
dst[0] = 0xF0 | ((codepoint >> 18) & 0x07);
dst[1] = 0x80 | ((codepoint >> 12) & 0x3F);
dst[2] = 0x80 | ((codepoint >> 6) & 0x3F);
dst[3] = 0x80 | (codepoint & 0x3F);
return dst + 4;
}
}
#endif

View File

@ -49,36 +49,6 @@ uint32_t utf8_get_next(const utf8* char_ptr, const utf8** nextchar_ptr)
return result;
}
utf8* utf8_write_codepoint(utf8* dst, uint32_t codepoint)
{
if (codepoint <= 0x7F)
{
dst[0] = (utf8)codepoint;
return dst + 1;
}
else if (codepoint <= 0x7FF)
{
dst[0] = 0xC0 | ((codepoint >> 6) & 0x1F);
dst[1] = 0x80 | (codepoint & 0x3F);
return dst + 2;
}
else if (codepoint <= 0xFFFF)
{
dst[0] = 0xE0 | ((codepoint >> 12) & 0x0F);
dst[1] = 0x80 | ((codepoint >> 6) & 0x3F);
dst[2] = 0x80 | (codepoint & 0x3F);
return dst + 3;
}
else
{
dst[0] = 0xF0 | ((codepoint >> 18) & 0x07);
dst[1] = 0x80 | ((codepoint >> 12) & 0x3F);
dst[2] = 0x80 | ((codepoint >> 6) & 0x3F);
dst[3] = 0x80 | (codepoint & 0x3F);
return dst + 4;
}
}
/**
* Inserts the given codepoint at the given address, shifting all characters after along.
* @returns the size of the inserted codepoint.

View File

@ -33,6 +33,30 @@
static Banner _banners[MAX_BANNERS];
namespace
{
template<uint32_t TFrom, uint32_t TTo> struct CodePointToUtf8
{
constexpr CodePointToUtf8()
{
for (uint32_t i = TFrom; i <= TTo; ++i)
{
utf8_write_codepoint(m_colors[i - TFrom], i);
}
}
constexpr auto operator()(uint8_t colourId) const
{
return m_colors[colourId];
}
using Utf8Colour = utf8[5]; // A 32bit codepoint uses at most 4 bytes in utf8
Utf8Colour m_colors[TTo - TFrom + 1]{};
};
} // namespace
static constexpr CodePointToUtf8<FORMAT_COLOUR_CODE_START, FORMAT_COLOUR_CODE_END> colourToUtf8;
std::string Banner::GetText() const
{
uint8_t args[32]{};
@ -47,14 +71,10 @@ size_t Banner::FormatTextTo(void* argsV, bool addColour) const
int numColourArgs = 0;
if (addColour)
{
textColourUtf8.resize(5); // one code point in utf8 takes at most 4 bytes
auto terminator = utf8_write_codepoint(textColourUtf8.data(), FORMAT_COLOUR_CODE_START + text_colour);
*terminator = '\0';
set_format_arg_on(args, numColourArgs, rct_string_id, STR_STRING_STRINGID);
numColourArgs += sizeof(rct_string_id);
set_format_arg_on(args, numColourArgs, const char*, textColourUtf8.data());
set_format_arg_on(args, numColourArgs, const char*, colourToUtf8(text_colour));
numColourArgs += sizeof(const char*);
args += numColourArgs;

View File

@ -34,7 +34,6 @@ struct Banner
uint8_t colour{};
ride_id_t ride_index{};
uint8_t text_colour{};
mutable std::string textColourUtf8;
TileCoordsXY position;
bool IsNull() const