Loading graphics/java/android/graphics/fonts/FontFileUtil.java +42 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import dalvik.annotation.optimization.FastNative; import java.nio.ByteBuffer; import java.nio.ByteOrder; Loading Loading @@ -131,4 +133,44 @@ public class FontFileUtil { buffer.order(originalOrder); } } /** * Analyze head OpenType table and return fontRevision value as 32bit integer. * * The font revision is stored in 16.16 bit fixed point value. This function returns this fixed * point value as 32 bit integer, i.e. the value multiplied with 65536. * * IllegalArgumentException will be thrown for invalid font data. * If the font file is invalid, returns -1L. * * @param buffer a buffer of OpenType font * @param index a font index * @return font revision that shifted 16 bits left. */ public static long getRevision(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index) { return nGetFontRevision(buffer, index); } /** * Analyze name OpenType table and return PostScript name. * * IllegalArgumentException will be thrown for invalid font data. * null will be returned if not found or the PostScript name is invalid. * * @param buffer a buffer of OpenType font * @param index a font index * @return a post script name or null if it is invalid or not found. */ public static String getPostScriptName(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index) { return nGetFontPostScriptName(buffer, index); } @FastNative private static native long nGetFontRevision(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index); @FastNative private static native String nGetFontPostScriptName(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index); } libs/hwui/jni/fonts/Font.cpp +55 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <hwui/Paint.h> #include <hwui/Typeface.h> #include <minikin/FontFamily.h> #include <minikin/FontFileParser.h> #include <ui/FatVector.h> #include <memory> Loading Loading @@ -233,6 +234,51 @@ static jlong FontBufferHelper_getReleaseFunc(CRITICAL_JNI_PARAMS) { /////////////////////////////////////////////////////////////////////////////// // Fast Native static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) { NPE_CHECK_RETURN_ZERO(env, buffer); const void* fontPtr = env->GetDirectBufferAddress(buffer); if (fontPtr == nullptr) { jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer"); return 0; } jlong fontSize = env->GetDirectBufferCapacity(buffer); if (fontSize <= 0) { jniThrowException(env, "java/lang/IllegalArgumentException", "buffer size must not be zero or negative"); return 0; } minikin::FontFileParser parser(fontPtr, fontSize, index); std::optional<uint32_t> revision = parser.getFontRevision(); if (!revision.has_value()) { return -1L; } return revision.value(); } static jstring FontFileUtil_getFontPostScriptName(JNIEnv* env, jobject, jobject buffer, jint index) { NPE_CHECK_RETURN_ZERO(env, buffer); const void* fontPtr = env->GetDirectBufferAddress(buffer); if (fontPtr == nullptr) { jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer"); return nullptr; } jlong fontSize = env->GetDirectBufferCapacity(buffer); if (fontSize <= 0) { jniThrowException(env, "java/lang/IllegalArgumentException", "buffer size must not be zero or negative"); return nullptr; } minikin::FontFileParser parser(fontPtr, fontSize, index); std::optional<std::string> psName = parser.getPostScriptName(); if (!psName.has_value()) { return nullptr; // null } return env->NewStringUTF(psName->c_str()); } /////////////////////////////////////////////////////////////////////////////// static const JNINativeMethod gFontBuilderMethods[] = { { "nInitBuilder", "()J", (void*) Font_Builder_initBuilder }, { "nAddAxis", "(JIF)V", (void*) Font_Builder_addAxis }, Loading @@ -254,13 +300,21 @@ static const JNINativeMethod gFontBufferHelperMethods[] = { { "nGetReleaseFunc", "()J", (void*) FontBufferHelper_getReleaseFunc }, }; static const JNINativeMethod gFontFileUtilMethods[] = { { "nGetFontRevision", "(Ljava/nio/ByteBuffer;I)J", (void*) FontFileUtil_getFontRevision }, { "nGetFontPostScriptName", "(Ljava/nio/ByteBuffer;I)Ljava/lang/String;", (void*) FontFileUtil_getFontPostScriptName }, }; int register_android_graphics_fonts_Font(JNIEnv* env) { return RegisterMethodsOrDie(env, "android/graphics/fonts/Font$Builder", gFontBuilderMethods, NELEM(gFontBuilderMethods)) + RegisterMethodsOrDie(env, "android/graphics/fonts/Font", gFontMethods, NELEM(gFontMethods)) + RegisterMethodsOrDie(env, "android/graphics/fonts/NativeFontBufferHelper", gFontBufferHelperMethods, NELEM(gFontBufferHelperMethods)); gFontBufferHelperMethods, NELEM(gFontBufferHelperMethods)) + RegisterMethodsOrDie(env, "android/graphics/fonts/FontFileUtil", gFontFileUtilMethods, NELEM(gFontFileUtilMethods)); } namespace fonts { Loading Loading
graphics/java/android/graphics/fonts/FontFileUtil.java +42 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import dalvik.annotation.optimization.FastNative; import java.nio.ByteBuffer; import java.nio.ByteOrder; Loading Loading @@ -131,4 +133,44 @@ public class FontFileUtil { buffer.order(originalOrder); } } /** * Analyze head OpenType table and return fontRevision value as 32bit integer. * * The font revision is stored in 16.16 bit fixed point value. This function returns this fixed * point value as 32 bit integer, i.e. the value multiplied with 65536. * * IllegalArgumentException will be thrown for invalid font data. * If the font file is invalid, returns -1L. * * @param buffer a buffer of OpenType font * @param index a font index * @return font revision that shifted 16 bits left. */ public static long getRevision(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index) { return nGetFontRevision(buffer, index); } /** * Analyze name OpenType table and return PostScript name. * * IllegalArgumentException will be thrown for invalid font data. * null will be returned if not found or the PostScript name is invalid. * * @param buffer a buffer of OpenType font * @param index a font index * @return a post script name or null if it is invalid or not found. */ public static String getPostScriptName(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index) { return nGetFontPostScriptName(buffer, index); } @FastNative private static native long nGetFontRevision(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index); @FastNative private static native String nGetFontPostScriptName(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index); }
libs/hwui/jni/fonts/Font.cpp +55 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <hwui/Paint.h> #include <hwui/Typeface.h> #include <minikin/FontFamily.h> #include <minikin/FontFileParser.h> #include <ui/FatVector.h> #include <memory> Loading Loading @@ -233,6 +234,51 @@ static jlong FontBufferHelper_getReleaseFunc(CRITICAL_JNI_PARAMS) { /////////////////////////////////////////////////////////////////////////////// // Fast Native static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) { NPE_CHECK_RETURN_ZERO(env, buffer); const void* fontPtr = env->GetDirectBufferAddress(buffer); if (fontPtr == nullptr) { jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer"); return 0; } jlong fontSize = env->GetDirectBufferCapacity(buffer); if (fontSize <= 0) { jniThrowException(env, "java/lang/IllegalArgumentException", "buffer size must not be zero or negative"); return 0; } minikin::FontFileParser parser(fontPtr, fontSize, index); std::optional<uint32_t> revision = parser.getFontRevision(); if (!revision.has_value()) { return -1L; } return revision.value(); } static jstring FontFileUtil_getFontPostScriptName(JNIEnv* env, jobject, jobject buffer, jint index) { NPE_CHECK_RETURN_ZERO(env, buffer); const void* fontPtr = env->GetDirectBufferAddress(buffer); if (fontPtr == nullptr) { jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer"); return nullptr; } jlong fontSize = env->GetDirectBufferCapacity(buffer); if (fontSize <= 0) { jniThrowException(env, "java/lang/IllegalArgumentException", "buffer size must not be zero or negative"); return nullptr; } minikin::FontFileParser parser(fontPtr, fontSize, index); std::optional<std::string> psName = parser.getPostScriptName(); if (!psName.has_value()) { return nullptr; // null } return env->NewStringUTF(psName->c_str()); } /////////////////////////////////////////////////////////////////////////////// static const JNINativeMethod gFontBuilderMethods[] = { { "nInitBuilder", "()J", (void*) Font_Builder_initBuilder }, { "nAddAxis", "(JIF)V", (void*) Font_Builder_addAxis }, Loading @@ -254,13 +300,21 @@ static const JNINativeMethod gFontBufferHelperMethods[] = { { "nGetReleaseFunc", "()J", (void*) FontBufferHelper_getReleaseFunc }, }; static const JNINativeMethod gFontFileUtilMethods[] = { { "nGetFontRevision", "(Ljava/nio/ByteBuffer;I)J", (void*) FontFileUtil_getFontRevision }, { "nGetFontPostScriptName", "(Ljava/nio/ByteBuffer;I)Ljava/lang/String;", (void*) FontFileUtil_getFontPostScriptName }, }; int register_android_graphics_fonts_Font(JNIEnv* env) { return RegisterMethodsOrDie(env, "android/graphics/fonts/Font$Builder", gFontBuilderMethods, NELEM(gFontBuilderMethods)) + RegisterMethodsOrDie(env, "android/graphics/fonts/Font", gFontMethods, NELEM(gFontMethods)) + RegisterMethodsOrDie(env, "android/graphics/fonts/NativeFontBufferHelper", gFontBufferHelperMethods, NELEM(gFontBufferHelperMethods)); gFontBufferHelperMethods, NELEM(gFontBufferHelperMethods)) + RegisterMethodsOrDie(env, "android/graphics/fonts/FontFileUtil", gFontFileUtilMethods, NELEM(gFontFileUtilMethods)); } namespace fonts { Loading