Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d5ab7e4 authored by Seigo Nonaka's avatar Seigo Nonaka
Browse files

Add utility method for identifying font type.

Bug: 176939176
Test: atest FontFileUtilTest
Change-Id: Iaf4e23128ee274c2beb10280eb64ba73e6bc2ad8
parent 9e4440d7
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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));
        }
    }
}
+21 −0
Original line number Diff line number Diff line
@@ -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);
}
+24 −0
Original line number Diff line number Diff line
@@ -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) {