COMMON: Rewrite Encoder and drop dependency on iconv (#2586)

Different platforms have different levels of support of encodings and
often have slight variations. We already have tables for most encoding
with only CJK missing. Full transcoding inclusion allows us to get reliable
encoding results independently of platform. The biggest con is the need for
external tables encoding.dat.

It removes a duplicate table for korean in graphics/korfont.cpp
This commit is contained in:
Vladimir Serbinenko 2020-11-15 16:20:35 +01:00 committed by GitHub
parent 228806a158
commit 68a9136e4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
74 changed files with 40828 additions and 2997 deletions

View file

@ -45,7 +45,6 @@
#include "common/config-manager.h"
#include "common/error.h"
#include "common/textconsole.h"
#include "common/encoding.h"
#include "engines/engine.h"
#include "backends/platform/android/android.h"
@ -86,7 +85,6 @@ jmethodID JNI::_MID_setWindowCaption = 0;
jmethodID JNI::_MID_showVirtualKeyboard = 0;
jmethodID JNI::_MID_showKeyboardControl = 0;
jmethodID JNI::_MID_getSysArchives = 0;
jmethodID JNI::_MID_convertEncoding = 0;
jmethodID JNI::_MID_getAllStorageLocations = 0;
jmethodID JNI::_MID_initSurface = 0;
jmethodID JNI::_MID_deinitSurface = 0;
@ -236,7 +234,7 @@ void JNI::displayMessageOnOSD(const Common::U32String &msg) {
// called from common/osd_message_queue, method: OSDMessageQueue::pollEvent()
JNIEnv *env = JNI::getEnv();
jstring java_msg = convertToJString(env, msg.encode(), "UTF-8");
jstring java_msg = convertToJString(env, msg);
if (java_msg == nullptr) {
// Show a placeholder indicative of the translation error instead of silent failing
java_msg = env->NewStringUTF("?");
@ -303,15 +301,15 @@ Common::U32String JNI::getTextFromClipboard() {
return Common::U32String();
}
Common::String text = convertFromJString(env, javaText, "UTF-8");
Common::U32String text = convertFromJString(env, javaText);
env->DeleteLocalRef(javaText);
return text.decode();
return text;
}
bool JNI::setTextInClipboard(const Common::U32String &text) {
JNIEnv *env = JNI::getEnv();
jstring javaText = convertToJString(env, text.encode(), "UTF-8");
jstring javaText = convertToJString(env, text);
bool success = env->CallBooleanMethod(_jobj, _MID_setTextInClipboard, javaText);
@ -344,7 +342,7 @@ bool JNI::isConnectionLimited() {
void JNI::setWindowCaption(const Common::String &caption) {
JNIEnv *env = JNI::getEnv();
jstring java_caption = convertToJString(env, caption, "ISO-8859-1");
jstring java_caption = convertToJString(env, caption.decode(Common::kISO8859_1));
env->CallVoidMethod(_jobj, _MID_setWindowCaption, java_caption);
@ -428,36 +426,6 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
s.add("ASSET", _asset_archive, priority - 1, false);
}
char *JNI::convertEncoding(const char *to, const char *from, const char *string, size_t length) {
JNIEnv *env = JNI::getEnv();
jstring javaTo = env->NewStringUTF(to);
jstring javaFrom = env->NewStringUTF(from);
jbyteArray javaString = env->NewByteArray(length);
env->SetByteArrayRegion(javaString, 0, length, reinterpret_cast<const jbyte*>(string));
jbyteArray javaOut = (jbyteArray)env->CallObjectMethod(_jobj, _MID_convertEncoding, javaTo, javaFrom, javaString);
if (!javaOut || env->ExceptionCheck()) {
LOGE("Failed to convert text from %s to %s", from, to);
env->ExceptionDescribe();
env->ExceptionClear();
return nullptr;
}
int outLength = env->GetArrayLength(javaOut);
char *buf = (char *)malloc(outLength + 1);
if (!buf)
return nullptr;
env->GetByteArrayRegion(javaOut, 0, outLength, reinterpret_cast<jbyte *>(buf));
buf[outLength] = 0;
return buf;
}
bool JNI::initSurface() {
JNIEnv *env = JNI::getEnv();
@ -586,7 +554,6 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
FIND_METHOD(, showKeyboardControl, "(Z)V");
FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
FIND_METHOD(, convertEncoding, "(Ljava/lang/String;Ljava/lang/String;[B)[B");
FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
FIND_METHOD(, deinitSurface, "()V");
FIND_METHOD(, createDirectoryWithSAF, "(Ljava/lang/String;)Z");
@ -752,29 +719,21 @@ void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
}
}
jstring JNI::convertToJString(JNIEnv *env, const Common::String &str, const Common::String &from) {
Common::Encoding converter("UTF-8", from.c_str());
char *utf8Str = converter.convert(str.c_str(), converter.stringLength(str.c_str(), from));
if (utf8Str == nullptr)
return nullptr;
jstring jstr = env->NewStringUTF(utf8Str);
free(utf8Str);
jstring JNI::convertToJString(JNIEnv *env, const Common::U32String &str) {
uint len = 0;
uint16 *u16str = str.encodeUTF16Native(&len);
jstring jstr = env->NewString(u16str, len);
delete[] u16str;
return jstr;
}
Common::String JNI::convertFromJString(JNIEnv *env, const jstring &jstr, const Common::String &to) {
const char *utf8Str = env->GetStringUTFChars(jstr, 0);
if (!utf8Str)
return Common::String();
Common::Encoding converter(to.c_str(), "UTF-8");
char *asciiStr = converter.convert(utf8Str, env->GetStringUTFLength(jstr));
env->ReleaseStringUTFChars(jstr, utf8Str);
Common::String str(asciiStr);
free(asciiStr);
Common::U32String JNI::convertFromJString(JNIEnv *env, const jstring &jstr) {
const uint16 *utf16Str = env->GetStringChars(jstr, 0);
uint jcount = env->GetStringLength(jstr);
if (!utf16Str)
return Common::U32String();
Common::U32String str = Common::U32String::decodeUTF16Native(utf16Str, jcount);
env->ReleaseStringChars(jstr, utf16Str);
return str;
}
@ -830,7 +789,7 @@ bool JNI::createDirectoryWithSAF(const Common::String &dirPath) {
}
Common::String JNI::createFileWithSAF(const Common::String &filePath) {
Common::U32String JNI::createFileWithSAF(const Common::String &filePath) {
JNIEnv *env = JNI::getEnv();
jstring javaFilePath = env->NewStringUTF(filePath.c_str());
@ -845,7 +804,7 @@ Common::String JNI::createFileWithSAF(const Common::String &filePath) {
hackyFilenameJSTR = env->NewStringUTF("");
}
Common::String hackyFilenameStr = convertFromJString(env, hackyFilenameJSTR, "UTF-8");
Common::U32String hackyFilenameStr = convertFromJString(env, hackyFilenameJSTR);
//LOGD("JNI - _MID_createFileWithSAF returned %s", hackyFilenameStr.c_str());
env->DeleteLocalRef(hackyFilenameJSTR);