| /* |
| * Copyright 2021 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "experimental/sktext/include/Text.h" |
| #include "experimental/sktext/include/Types.h" |
| #include "include/core/SkCanvas.h" |
| #include "modules/jetski/src/Utils.h" |
| |
| #include <jni.h> |
| |
| namespace { |
| static jmethodID gFontChain_countMethodID; |
| static jmethodID gFontChain_getAtMethodID; |
| static jmethodID gFontChain_fontSizeMethodID; |
| static jmethodID gFontChain_localeMethodID; |
| |
| class FontChainAdapter : public skia::text::FontChain { |
| public: |
| FontChainAdapter(JNIEnv* env, jobject jFontChain) |
| : fEnv(env) |
| , fFontChainImpl(jFontChain) |
| { } |
| |
| size_t count() const override { |
| return fEnv->CallIntMethod(fFontChainImpl, gFontChain_countMethodID); |
| } |
| |
| sk_sp<SkTypeface> operator[](size_t index) const override { |
| SkASSERT(index < this->count()); |
| SkFont* font = reinterpret_cast<SkFont*>(fEnv->CallLongMethod(fFontChainImpl, gFontChain_getAtMethodID, index)); |
| if (font) { |
| return sk_ref_sp(font->getTypeface()); |
| } |
| return nullptr; |
| } |
| |
| float fontSize() const override { |
| return fEnv->CallFloatMethod(fFontChainImpl, gFontChain_fontSizeMethodID); |
| } |
| |
| SkString locale() const override { |
| jstring jLocale = (jstring)fEnv->CallObjectMethod(fFontChainImpl, gFontChain_localeMethodID); |
| |
| const jetski::utils::CString cstr(fEnv, jLocale); |
| SkString str(cstr); |
| return str; |
| } |
| |
| private: |
| // TODO: Check, can we hold on to env here or do we have to get it every time? |
| JNIEnv* fEnv; |
| jobject fFontChainImpl; |
| }; |
| |
| static jlong FontChain_Create(JNIEnv* env, jobject, jobject jFontChain) { |
| return reinterpret_cast<jlong>(new FontChainAdapter(env, jFontChain)); |
| } |
| |
| static void FontChain_Release(JNIEnv* env, jobject, jlong native_FontChain) { |
| SkSafeUnref(reinterpret_cast<FontChainAdapter*>(native_FontChain)); |
| } |
| |
| } // namespace |
| |
| int register_jetski_FontChain(JNIEnv* env) { |
| const auto clazz = env->FindClass("org/skia/jetski/FontChain"); |
| |
| gFontChain_countMethodID = env->GetMethodID(clazz, "count", "()I"); |
| gFontChain_getAtMethodID = env->GetMethodID(clazz, "getAt", "(I)J"); |
| gFontChain_fontSizeMethodID = env->GetMethodID(clazz, "fontSize", "()F"); |
| gFontChain_localeMethodID = env->GetMethodID(clazz, "locale", "()Ljava/lang/String;"); |
| |
| if (!gFontChain_countMethodID || !gFontChain_getAtMethodID || |
| !gFontChain_fontSizeMethodID || !gFontChain_localeMethodID) { |
| return JNI_ERR; |
| } |
| |
| static const JNINativeMethod methods[] = { |
| {"nCreate" , "(Lorg/skia/jetski/FontChain;)J", reinterpret_cast<void*>(FontChain_Create)}, |
| {"nRelease", "(J)V", reinterpret_cast<void*>(FontChain_Release)}, |
| }; |
| |
| return clazz |
| ? env->RegisterNatives(clazz, methods, std::size(methods)) |
| : JNI_ERR; |
| } |