mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-21 05:53:02 +01:00
Implement C++ solution to truncate UTF8 strings
This commit is contained in:
committed by
Gymnasiast
parent
645685de18
commit
0957542503
@@ -105,11 +105,7 @@ public:
|
||||
|
||||
void SetText(std::string_view text, size_t maxLength)
|
||||
{
|
||||
char* tmp = new char[maxLength];
|
||||
safe_strcpy(tmp, std::string(text).c_str(), maxLength);
|
||||
_buffer = tmp;
|
||||
delete[] tmp;
|
||||
_buffer.resize(maxLength);
|
||||
_buffer = String::UTF8Truncate(text, maxLength);
|
||||
_maxInputLength = maxLength;
|
||||
gTextInput = context_start_text_input(_buffer.data(), maxLength);
|
||||
}
|
||||
|
||||
@@ -807,6 +807,22 @@ namespace String
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string_view UTF8Truncate(std::string_view v, size_t size)
|
||||
{
|
||||
auto trunc = v.substr(0, size);
|
||||
for (size_t i = 0; i < trunc.size();)
|
||||
{
|
||||
auto length = UTF8GetCodePointSize(trunc.substr(i, trunc.size()));
|
||||
if (!length.has_value())
|
||||
{
|
||||
return trunc.substr(0, i);
|
||||
}
|
||||
i += *length;
|
||||
}
|
||||
|
||||
return trunc;
|
||||
}
|
||||
} // namespace String
|
||||
|
||||
char32_t CodepointView::iterator::GetNextCodepoint(const char* ch, const char** next)
|
||||
|
||||
@@ -147,6 +147,37 @@ namespace String
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns codepoint size or no value if not valid
|
||||
*/
|
||||
constexpr std::optional<int> UTF8GetCodePointSize(std::string_view v)
|
||||
{
|
||||
if (v.size() >= 1 && !(v[0] & 0x80))
|
||||
{
|
||||
return { 1 };
|
||||
}
|
||||
else if (v.size() >= 2 && ((v[0] & 0xE0) == 0xC0))
|
||||
{
|
||||
return { 2 };
|
||||
}
|
||||
else if (v.size() >= 3 && ((v[0] & 0xF0) == 0xE0))
|
||||
{
|
||||
return { 3 };
|
||||
}
|
||||
else if (v.size() >= 4 && ((v[0] & 0xF8) == 0xF0))
|
||||
{
|
||||
return { 4 };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates a string to at most `size` bytes,
|
||||
* making sure not to cut in the middle of a sequence.
|
||||
*/
|
||||
std::string_view UTF8Truncate(std::string_view v, size_t size);
|
||||
|
||||
} // namespace String
|
||||
|
||||
class CodepointView
|
||||
|
||||
Reference in New Issue
Block a user