forked from Mirrorlandia_minetest/minetest
Hand roll UTF-16 conversion in CGUITTFont (#14121)
This commit is contained in:
parent
00d9d96e48
commit
61d0f613df
@ -32,8 +32,6 @@
|
|||||||
|
|
||||||
#include <irrlicht.h>
|
#include <irrlicht.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <codecvt>
|
|
||||||
#include <locale>
|
|
||||||
#include "CGUITTFont.h"
|
#include "CGUITTFont.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
@ -1251,21 +1249,31 @@ std::u32string CGUITTFont::convertWCharToU32String(const wchar_t* const charArra
|
|||||||
{
|
{
|
||||||
static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "unexpected wchar size");
|
static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "unexpected wchar size");
|
||||||
|
|
||||||
if (sizeof(wchar_t) == 4) // Systems where wchar_t is UTF-32
|
if (sizeof(wchar_t) == 4) // wchar_t is UTF-32
|
||||||
return std::u32string(reinterpret_cast<const char32_t*>(charArray));
|
return std::u32string(reinterpret_cast<const char32_t*>(charArray));
|
||||||
|
|
||||||
// Systems where wchar_t is UTF-16:
|
// wchar_t is UTF-16 and we need to convert.
|
||||||
// First, convert to UTF-8
|
// std::codecvt could do this for us but aside from being deprecated,
|
||||||
std::u16string utf16String(reinterpret_cast<const char16_t*>(charArray));
|
// it turns out that it's laughably slow on MSVC. Thanks Microsoft.
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter1;
|
|
||||||
std::string utf8String = converter1.to_bytes(utf16String);
|
|
||||||
|
|
||||||
// Next, convert to UTF-32
|
std::u32string ret;
|
||||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter2;
|
ret.reserve(wcslen(charArray));
|
||||||
return converter2.from_bytes(utf8String);
|
const wchar_t *p = charArray;
|
||||||
|
while (*p) {
|
||||||
// This is inefficient, but importantly it is _correct_, rather than a hand-rolled UTF-16 to
|
char32_t c = *p;
|
||||||
// UTF-32 converter which may or may not be correct.
|
if (c >= 0xD800 && c < 0xDC00) {
|
||||||
|
p++;
|
||||||
|
char32_t c2 = *p;
|
||||||
|
if (!c2)
|
||||||
|
break;
|
||||||
|
else if (c2 < 0xDC00 || c2 > 0xDFFF)
|
||||||
|
continue; // can't find low surrogate, skip
|
||||||
|
c = 0x10000 + ( ((c & 0x3ff) << 10) | (c2 & 0x3ff) );
|
||||||
|
}
|
||||||
|
ret.push_back(c);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user