platform/cc/shaper/interop.cc (201 lines of code) (raw):

#include <jni.h> #include "interop.hh" #include "SkFont.h" #include "SkShaper.h" #include "SkLoadICU.h" namespace skija { namespace shaper { namespace BidiRun { jfieldID _end; jfieldID _level; void onLoad(JNIEnv* env) { jclass cls = env->FindClass("org/jetbrains/skija/shaper/BidiRun"); _end = env->GetFieldID(cls, "_end", "I"); _level = env->GetFieldID(cls, "_level", "I"); } } namespace FontMgrRunIterator { jclass cls; void onLoad(JNIEnv* env) { jclass local = env->FindClass("org/jetbrains/skija/shaper/FontMgrRunIterator"); cls = static_cast<jclass>(env->NewGlobalRef(local)); } void onUnload(JNIEnv* env) { env->DeleteGlobalRef(cls); } } namespace FontRun { jfieldID _end; jmethodID _getFontPtr; void onLoad(JNIEnv* env) { jclass cls = env->FindClass("org/jetbrains/skija/shaper/FontRun"); _end = env->GetFieldID(cls, "_end", "I"); _getFontPtr = env->GetMethodID(cls, "_getFontPtr", "()J"); } } namespace HbIcuScriptRunIterator { jclass cls; void onLoad(JNIEnv* env) { jclass local = env->FindClass("org/jetbrains/skija/shaper/HbIcuScriptRunIterator"); cls = static_cast<jclass>(env->NewGlobalRef(local)); } void onUnload(JNIEnv* env) { env->DeleteGlobalRef(cls); } } namespace IcuBidiRunIterator { jclass cls; void onLoad(JNIEnv* env) { jclass local = env->FindClass("org/jetbrains/skija/shaper/IcuBidiRunIterator"); cls = static_cast<jclass>(env->NewGlobalRef(local)); } void onUnload(JNIEnv* env) { env->DeleteGlobalRef(cls); } } namespace LanguageRun { jfieldID _end; jfieldID _language; void onLoad(JNIEnv* env) { jclass cls = env->FindClass("org/jetbrains/skija/shaper/LanguageRun"); _end = env->GetFieldID(cls, "_end", "I"); _language = env->GetFieldID(cls, "_language", "Ljava/lang/String;"); } } namespace RunHandler { jclass cls; jmethodID beginLine; jmethodID runInfo; jmethodID commitRunInfo; jmethodID runOffset; jmethodID commitRun; jmethodID commitLine; void onLoad(JNIEnv* env) { jclass local = env->FindClass("org/jetbrains/skija/shaper/RunHandler"); cls = static_cast<jclass>(env->NewGlobalRef(local)); beginLine = env->GetMethodID(cls, "beginLine", "()V"); runInfo = env->GetMethodID(cls, "runInfo", "(Lorg/jetbrains/skija/shaper/RunInfo;)V"); commitRunInfo = env->GetMethodID(cls, "commitRunInfo", "()V"); runOffset = env->GetMethodID(cls, "runOffset", "(Lorg/jetbrains/skija/shaper/RunInfo;)Lorg/jetbrains/skija/Point;"); commitRun = env->GetMethodID(cls, "commitRun", "(Lorg/jetbrains/skija/shaper/RunInfo;[S[Lorg/jetbrains/skija/Point;[I)V"); commitLine = env->GetMethodID(cls, "commitLine", "()V"); } void onUnload(JNIEnv* env) { env->DeleteGlobalRef(cls); } } namespace RunInfo { jclass cls; jmethodID ctor; jfieldID _fontPtr; void onLoad(JNIEnv* env) { jclass local = env->FindClass("org/jetbrains/skija/shaper/RunInfo"); cls = static_cast<jclass>(env->NewGlobalRef(local)); ctor = env->GetMethodID(cls, "<init>", "(JIFFJII)V"); _fontPtr = env->GetFieldID(cls, "_fontPtr", "J"); } void onUnload(JNIEnv* env) { env->DeleteGlobalRef(cls); } jobject toJava(JNIEnv* env, const SkShaper::RunHandler::RunInfo& info, size_t begin, size_t end) { SkFont* font = new SkFont(info.fFont); return env->NewObject( cls, ctor, reinterpret_cast<jlong>(font), info.fBidiLevel, info.fAdvance.fX, info.fAdvance.fY, info.glyphCount, begin, end - begin); } jobject toJava(JNIEnv* env, const SkShaper::RunHandler::RunInfo& info, skija::UtfIndicesConverter& indicesConverter) { size_t begin = indicesConverter.from8To16(info.utf8Range.fBegin); size_t end = indicesConverter.from8To16(info.utf8Range.fBegin + info.utf8Range.fSize); return toJava(env, info, begin, end); } } namespace ScriptRun { jfieldID _end; jfieldID _scriptTag; void onLoad(JNIEnv* env) { jclass cls = env->FindClass("org/jetbrains/skija/shaper/ScriptRun"); _end = env->GetFieldID(cls, "_end", "I"); _scriptTag = env->GetFieldID(cls, "_scriptTag", "I"); } } namespace ShapingOptions { jfieldID _fontMgr; jfieldID _features; jfieldID _leftToRight; jfieldID _approximateSpaces; jfieldID _approximatePunctuation; void onLoad(JNIEnv* env) { jclass cls = env->FindClass("org/jetbrains/skija/shaper/ShapingOptions"); _fontMgr = env->GetFieldID(cls, "_fontMgr", "Lorg/jetbrains/skija/FontMgr;"); _features = env->GetFieldID(cls, "_features", "[Lorg/jetbrains/skija/FontFeature;"); _leftToRight = env->GetFieldID(cls, "_leftToRight", "Z"); _approximateSpaces = env->GetFieldID(cls, "_approximateSpaces", "Z"); _approximatePunctuation = env->GetFieldID(cls, "_approximatePunctuation", "Z"); } std::vector<SkShaper::Feature> getFeatures(JNIEnv* env, jobject opts) { return skija::FontFeature::fromJavaArray(env, (jobjectArray) env->GetObjectField(opts, _features)); } } namespace TextBlobBuilderRunHandler { jclass cls; void onLoad(JNIEnv* env) { jclass local = env->FindClass("org/jetbrains/skija/shaper/TextBlobBuilderRunHandler"); cls = static_cast<jclass>(env->NewGlobalRef(local)); } void onUnload(JNIEnv* env) { env->DeleteGlobalRef(cls); } } void onLoad(JNIEnv* env) { BidiRun::onLoad(env); FontMgrRunIterator::onLoad(env); FontRun::onLoad(env); HbIcuScriptRunIterator::onLoad(env); IcuBidiRunIterator::onLoad(env); LanguageRun::onLoad(env); RunHandler::onLoad(env); RunInfo::onLoad(env); ScriptRun::onLoad(env); ShapingOptions::onLoad(env); TextBlobBuilderRunHandler::onLoad(env); SkLoadICU(); } void onUnload(JNIEnv* env) { TextBlobBuilderRunHandler::onUnload(env); RunInfo::onUnload(env); RunHandler::onUnload(env); IcuBidiRunIterator::onUnload(env); HbIcuScriptRunIterator::onUnload(env); FontMgrRunIterator::onUnload(env); } std::shared_ptr<UBreakIterator> graphemeBreakIterator(SkString& text) { UErrorCode status = U_ZERO_ERROR; ICUUText utext(utext_openUTF8(nullptr, text.c_str(), text.size(), &status)); if (U_FAILURE(status)) { SkDEBUGF("utext_openUTF8 error: %s", u_errorName(status)); return nullptr; } std::shared_ptr<UBreakIterator> graphemeIter( ubrk_open(static_cast<UBreakIteratorType>(UBreakIteratorType::UBRK_CHARACTER), uloc_getDefault(), nullptr, 0, &status), [](UBreakIterator* p) { ubrk_close(p); } ); if (U_FAILURE(status)) { SkDEBUGF("ubrk_open error: %s", u_errorName(status)); return nullptr; } ubrk_setUText(graphemeIter.get(), utext.get(), &status); if (U_FAILURE(status)) { SkDEBUGF("ubrk_setUText error: %s", u_errorName(status)); return nullptr; } return graphemeIter; } } }