mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #14328 from Gymnasiast/fix/14315
Fix #14315: Crash when renaming APVC in Korean
This commit is contained in:
commit
850e7431c3
|
@ -4,6 +4,7 @@
|
|||
- Feature: [#14296] Allow using early scenario completion in multiplayer.
|
||||
- Fix: [#11829] Visual glitches and crashes when using RCT1 assets from mismatched or corrupt CSG1.DAT and CSG1i.DAT files.
|
||||
- Fix: [#13894] Block brakes do not animate.
|
||||
- Fix: [#14315] Crash when trying to rename Air Powered Vertical Coaster in Korean.
|
||||
|
||||
0.3.3 (2021-03-13)
|
||||
------------------------------------------------------------------------
|
||||
|
|
|
@ -105,8 +105,7 @@ public:
|
|||
|
||||
void SetText(std::string_view text, size_t maxLength)
|
||||
{
|
||||
_buffer = text;
|
||||
_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
|
||||
|
|
Loading…
Reference in New Issue