/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "graphics_jni_helpers.h" #include #include "FontUtils.h" #include #include #include namespace android { namespace { struct NativeFamilyBuilder { std::vector> fonts; }; } // namespace static inline NativeFamilyBuilder* toBuilder(jlong ptr) { return reinterpret_cast(ptr); } static inline FontWrapper* toFontWrapper(jlong ptr) { return reinterpret_cast(ptr); } static void releaseFontFamily(jlong family) { delete reinterpret_cast(family); } // Regular JNI static jlong FontFamily_Builder_initBuilder(JNIEnv*, jobject) { return reinterpret_cast(new NativeFamilyBuilder()); } // Critical Native static void FontFamily_Builder_addFont(CRITICAL_JNI_PARAMS_COMMA jlong builderPtr, jlong fontPtr) { toBuilder(builderPtr)->fonts.push_back(toFontWrapper(fontPtr)->font); } // Regular JNI static jlong FontFamily_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jstring langTags, jint variant, jboolean isCustomFallback, jboolean isDefaultFallback, jint variationFamilyType) { std::unique_ptr builder(toBuilder(builderPtr)); uint32_t localeId; if (langTags == nullptr) { localeId = minikin::registerLocaleList(""); } else { ScopedUtfChars str(env, langTags); localeId = minikin::registerLocaleList(str.c_str()); } std::shared_ptr family = minikin::FontFamily::create( localeId, static_cast(variant), std::move(builder->fonts), isCustomFallback, isDefaultFallback, static_cast(variationFamilyType)); if (family->getCoverage().length() == 0) { // No coverage means minikin rejected given font for some reasons. jniThrowException(env, "java/lang/IllegalArgumentException", "Failed to create internal object. maybe invalid font data"); return 0; } return reinterpret_cast(new FontFamilyWrapper(std::move(family))); } // CriticalNative static jlong FontFamily_Builder_GetReleaseFunc(CRITICAL_JNI_PARAMS) { return reinterpret_cast(releaseFontFamily); } // FastNative static jstring FontFamily_getLangTags(JNIEnv* env, jobject, jlong familyPtr) { FontFamilyWrapper* family = reinterpret_cast(familyPtr); uint32_t localeListId = family->family->localeListId(); if (localeListId == 0) { return nullptr; } std::string langTags = minikin::getLocaleString(localeListId); return env->NewStringUTF(langTags.c_str()); } // CriticalNative static jint FontFamily_getVariant(CRITICAL_JNI_PARAMS_COMMA jlong familyPtr) { FontFamilyWrapper* family = reinterpret_cast(familyPtr); return static_cast(family->family->variant()); } // CriticalNative static jint FontFamily_getFontSize(CRITICAL_JNI_PARAMS_COMMA jlong familyPtr) { FontFamilyWrapper* family = reinterpret_cast(familyPtr); return family->family->getNumFonts(); } // CriticalNative static jlong FontFamily_getFont(CRITICAL_JNI_PARAMS_COMMA jlong familyPtr, jint index) { FontFamilyWrapper* family = reinterpret_cast(familyPtr); std::shared_ptr font = family->family->getFontRef(index); return reinterpret_cast(new FontWrapper(std::move(font))); } /////////////////////////////////////////////////////////////////////////////// static const JNINativeMethod gFontFamilyBuilderMethods[] = { {"nInitBuilder", "()J", (void*)FontFamily_Builder_initBuilder}, {"nAddFont", "(JJ)V", (void*)FontFamily_Builder_addFont}, {"nBuild", "(JLjava/lang/String;IZZI)J", (void*)FontFamily_Builder_build}, {"nGetReleaseNativeFamily", "()J", (void*)FontFamily_Builder_GetReleaseFunc}, }; static const JNINativeMethod gFontFamilyMethods[] = { {"nGetFontSize", "(J)I", (void*)FontFamily_getFontSize}, {"nGetFont", "(JI)J", (void*)FontFamily_getFont}, {"nGetLangTags", "(J)Ljava/lang/String;", (void*)FontFamily_getLangTags}, {"nGetVariant", "(J)I", (void*)FontFamily_getVariant}, }; int register_android_graphics_fonts_FontFamily(JNIEnv* env) { return RegisterMethodsOrDie(env, "android/graphics/fonts/FontFamily$Builder", gFontFamilyBuilderMethods, NELEM(gFontFamilyBuilderMethods)) + RegisterMethodsOrDie(env, "android/graphics/fonts/FontFamily", gFontFamilyMethods, NELEM(gFontFamilyMethods)); } }