Merge "Add utility method for identifying font type."

This commit is contained in:
Seigo Nonaka
2021-01-21 17:58:54 +00:00
committed by Android (Google) Code Review
3 changed files with 63 additions and 0 deletions

View File

@@ -17,11 +17,15 @@
package android.graphics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.fonts.Font;
import android.graphics.fonts.FontFileUtil;
import android.graphics.fonts.FontVariationAxis;
import android.graphics.fonts.SystemFonts;
import android.util.Log;
import android.util.Pair;
@@ -144,4 +148,18 @@ public class FontFileUtilTest {
assertEquals(path + "#" + axes, italic, FontFileUtil.unpackItalic(packed));
}
}
@Test
public void testExtension() throws IOException {
for (Font f : SystemFonts.getAvailableFonts()) {
String name = f.getFile().getName();
if (!name.endsWith(".ttf") && !name.endsWith(".otf")) {
continue; // Only test ttf/otf file
}
int isOtfFile = FontFileUtil.isPostScriptType1Font(f.getBuffer(), 0);
assertNotEquals(-1, isOtfFile);
String extension = isOtfFile == 1 ? ".otf" : ".ttf";
assertTrue(name.endsWith(extension));
}
}
}

View File

@@ -166,6 +166,23 @@ public class FontFileUtil {
return nGetFontPostScriptName(buffer, index);
}
/**
* Analyze name OpenType table and return true if the font has PostScript Type 1 glyphs.
*
* IllegalArgumentException will be thrown for invalid font data.
* -1 will be returned if the byte buffer is not a OpenType font data.
* 0 will be returned if the font file doesn't have PostScript Type 1 glyphs, i.e. ttf file.
* 1 will be returned if the font file has PostScript Type 1 glyphs, i.e. otf file.
*
* @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 int isPostScriptType1Font(@NonNull ByteBuffer buffer,
@IntRange(from = 0) int index) {
return nIsPostScriptType1Font(buffer, index);
}
@FastNative
private static native long nGetFontRevision(@NonNull ByteBuffer buffer,
@IntRange(from = 0) int index);
@@ -173,4 +190,8 @@ public class FontFileUtil {
@FastNative
private static native String nGetFontPostScriptName(@NonNull ByteBuffer buffer,
@IntRange(from = 0) int index);
@FastNative
private static native int nIsPostScriptType1Font(@NonNull ByteBuffer buffer,
@IntRange(from = 0) int index);
}

View File

@@ -277,6 +277,28 @@ static jstring FontFileUtil_getFontPostScriptName(JNIEnv* env, jobject, jobject
}
return env->NewStringUTF(psName->c_str());
}
static jint FontFileUtil_isPostScriptType1Font(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 -1;
}
jlong fontSize = env->GetDirectBufferCapacity(buffer);
if (fontSize <= 0) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"buffer size must not be zero or negative");
return -1;
}
minikin::FontFileParser parser(fontPtr, fontSize, index);
std::optional<bool> isType1 = parser.isPostScriptType1Font();
if (!isType1.has_value()) {
return -1; // not an OpenType font. HarfBuzz failed to parse it.
}
return isType1.value();
}
///////////////////////////////////////////////////////////////////////////////
static const JNINativeMethod gFontBuilderMethods[] = {
@@ -304,6 +326,8 @@ static const JNINativeMethod gFontFileUtilMethods[] = {
{ "nGetFontRevision", "(Ljava/nio/ByteBuffer;I)J", (void*) FontFileUtil_getFontRevision },
{ "nGetFontPostScriptName", "(Ljava/nio/ByteBuffer;I)Ljava/lang/String;",
(void*) FontFileUtil_getFontPostScriptName },
{ "nIsPostScriptType1Font", "(Ljava/nio/ByteBuffer;I)I",
(void*) FontFileUtil_isPostScriptType1Font },
};
int register_android_graphics_fonts_Font(JNIEnv* env) {