Use utf16 for java string to stringw conversion

This commit is contained in:
Benau 2019-06-10 16:09:07 +08:00
parent c0faf69a42
commit 591bd0c3af
2 changed files with 26 additions and 11 deletions

View File

@ -1300,13 +1300,16 @@ void CIrrDeviceAndroid::fromSTKEditBox(int widget_id, const core::stringw& text,
return; return;
} }
std::vector<char> utf8; // Android use 32bit wchar_t and java use utf16 string
// We should not use the modified utf8 from java as it fails for emoji
// because it's larger than 16bit
std::vector<uint16_t> utf16;
// Use utf32 for emoji later // Use utf32 for emoji later
static_assert(sizeof(wchar_t) == sizeof(uint32_t), "wchar_t is not 32bit"); static_assert(sizeof(wchar_t) == sizeof(uint32_t), "wchar_t is not 32bit");
uint32_t* chars = (uint32_t*)text.c_str(); const uint32_t* chars = (const uint32_t*)text.c_str();
utf8::unchecked::utf32to8(chars, chars + text.size(), back_inserter(utf8)); utf8::unchecked::utf32to16(chars, chars + text.size(), back_inserter(utf16));
utf8.push_back(0); jstring jstring_text = env->NewString((const jchar*)utf16.data(), utf16.size());
jstring jstring_text = env->NewStringUTF(utf8.data());
env->CallVoidMethod(native_activity, method_id, (jint)widget_id, jstring_text, (jint)selection_start, (jint)selection_end, (jint)type); env->CallVoidMethod(native_activity, method_id, (jint)widget_id, jstring_text, (jint)selection_start, (jint)selection_end, (jint)type);
if (was_detached) if (was_detached)

View File

@ -22,6 +22,7 @@
#include "guiengine/widgets/CGUIEditBox.hpp" #include "guiengine/widgets/CGUIEditBox.hpp"
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
#include "utils/translation.hpp" #include "utils/translation.hpp"
#include "utils/utf8.h"
#include <IGUIElement.h> #include <IGUIElement.h>
#include <IGUIEnvironment.h> #include <IGUIEnvironment.h>
@ -264,13 +265,24 @@ ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
if (text == NULL) if (text == NULL)
return; return;
const char* utf8_text = env->GetStringUTFChars(text, NULL); const uint16_t* utf16_text = (const uint16_t*)env->GetStringChars(text, NULL);
if (utf8_text == NULL) if (utf16_text == NULL)
return; return;
const size_t len = env->GetStringLength(text);
// Android use 32bit wchar_t // Android use 32bit wchar_t and java use utf16 string
std::u32string to_editbox = StringUtils::utf8ToUtf32(utf8_text); // We should not use the modified utf8 from java as it fails for emoji
env->ReleaseStringUTFChars(text, utf8_text); // because it's larger than 16bit
std::u32string to_editbox;
try
{
utf8::utf16to32(utf16_text, utf16_text + len,
back_inserter(to_editbox));
}
catch (std::exception& e)
{
(void)e;
}
env->ReleaseStringChars(text, utf16_text);
GUIEngine::addGUIFunctionBeforeRendering([widget_id, to_editbox, start, GUIEngine::addGUIFunctionBeforeRendering([widget_id, to_editbox, start,
end, composing_start, composing_end]() end, composing_start, composing_end]()