Merge fixes for handling Unicode characters outside of BMP

Closes https://github.com/wxWidgets/wxWidgets/pull/467
This commit is contained in:
Vadim Zeitlin
2017-06-21 18:53:40 +02:00
10 changed files with 483 additions and 119 deletions

View File

@@ -80,27 +80,27 @@ static bool NotAllNULs(const char *p, size_t n)
static size_t encode_utf16(wxUint32 input, wxUint16 *output)
{
if (input <= 0xffff)
if (wxUniChar::IsBMP(input))
{
if (output)
*output = (wxUint16) input;
return 1;
}
else if (input >= 0x110000)
{
return wxCONV_FAILED;
}
else
else if (wxUniChar::IsSupplementary(input))
{
if (output)
{
*output++ = (wxUint16) ((input >> 10) + 0xd7c0);
*output = (wxUint16) ((input & 0x3ff) + 0xdc00);
*output++ = wxUniChar::HighSurrogate(input);
*output = wxUniChar::LowSurrogate(input);
}
return 2;
}
else
{
return wxCONV_FAILED;
}
}
static size_t decode_utf16(const wxUint16* input, wxUint32& output)

View File

@@ -27,6 +27,68 @@
// implementation
// ===========================================================================
#if wxUSE_UNICODE_WCHAR || !wxUSE_UNICODE
#if wxUSE_UNICODE_UTF16
wxStringOperationsWchar::Utf16CharBuffer wxStringOperationsWchar::EncodeChar(const wxUniChar& ch)
{
Utf16CharBuffer buf;
if ( ch.IsSupplementary() )
{
buf.data[0] = (wchar_t)ch.HighSurrogate();
buf.data[1] = (wchar_t)ch.LowSurrogate();
}
else
{
// Assume ch is a BMP character
buf.data[0] = (wchar_t)ch;
}
return buf;
}
wxWCharBuffer wxStringOperationsWchar::EncodeNChars(size_t n, const wxUniChar& ch)
{
if ( ch.IsSupplementary() )
{
wxWCharBuffer buf(n * 2);
wchar_t s[2] = {
(wchar_t)ch.HighSurrogate(),
(wchar_t)ch.LowSurrogate(),
};
wchar_t *ptr = buf.data();
for (size_t i = 0; i < n; i++, ptr += 2)
{
wmemcpy(ptr, s, 2);
}
return buf;
}
else
{
// Assume ch is a BMP character
wxWCharBuffer buf(n);
wmemset(buf.data(), (wchar_t)ch, n);
return buf;
}
}
#else
wxWxCharBuffer wxStringOperationsWchar::EncodeNChars(size_t n, const wxUniChar& ch)
{
wxWxCharBuffer buf(n);
#if wxUSE_UNICODE_WCHAR
wmemset(buf.data(), (wchar_t)ch, n);
#else // ANSI
memset(buf.data(), (unsigned char)ch, n);
#endif
return buf;
}
#endif // wxUSE_UNICODE_UTF16
#endif // wxUSE_UNICODE_WCHAR || !wxUSE_UNICODE
#if wxUSE_UNICODE_UTF8
// ---------------------------------------------------------------------------

View File

@@ -502,7 +502,7 @@ wxScopedU16CharBuffer wxUString::utf16_str() const
// TODO: error range checks
if (code < 0x10000)
if (wxUniChar::IsBMP(code))
utf16_length++;
else
utf16_length += 2;
@@ -520,15 +520,15 @@ wxScopedU16CharBuffer wxUString::utf16_str() const
// TODO: error range checks
if (code < 0x10000)
if (wxUniChar::IsBMP(code))
{
out[0] = code;
out++;
}
else
{
out[0] = (code - 0x10000) / 0x400 + 0xd800;
out[1] = (code - 0x10000) % 0x400 + 0xdc00;
out[0] = wxUniChar::HighSurrogate(code);
out[1] = wxUniChar::LowSurrogate(code);
out += 2;
}
}