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

Commit 3c937cf5 authored by Deepanshu Gupta's avatar Deepanshu Gupta
Browse files

Support Typeface.createFromFile()

Add support for Typeface.createFromFile() for platform fonts. The
feature existed in the KitKat LayoutLib but was dropped for the L
preview. This change adds it back.

Change-Id: Ib1abe67a32c28a1fb0e2a4f3061c358b55129434
parent 7ea293bc
Loading
Loading
Loading
Loading
+45 −43
Original line number Diff line number Diff line
@@ -83,6 +83,13 @@ public class FontFamily_Delegate {
    private List<String> mPath = new ArrayList<String>();


    // ---- Public helper class ----

    public enum FontVariant {
        // The order needs to be kept in sync with android.graphics.FontFamily.
        NONE, COMPACT, ELEGANT
    }

    // ---- Public Helper methods ----

    public static FontFamily_Delegate getDelegate(long nativeFontFamily) {
@@ -124,6 +131,40 @@ public class FontFamily_Delegate {
        return mVariant;
    }

    /*package*/ static int getFontStyle(String path) {
        int style = Font.PLAIN;
        String fontName = path.substring(path.lastIndexOf('/'));
        if (fontName.endsWith(FONT_SUFFIX_BOLDITALIC)) {
            style = Font.BOLD | Font.ITALIC;
        } else if (fontName.endsWith(FONT_SUFFIX_BOLD)) {
            style = Font.BOLD;
        } else if (fontName.endsWith(FONT_SUFFIX_ITALIC)) {
            style = Font.ITALIC;
        }
        return style;
    }

    /*package*/ static Font loadFont(String path) {
        if (path.startsWith(SYSTEM_FONTS) ) {
            String relativePath = path.substring(SYSTEM_FONTS.length());
            File f = new File(sFontLocation, relativePath);

            try {
                return Font.createFont(Font.TRUETYPE_FONT, f);
            } catch (Exception e) {
                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
                        String.format("Unable to load font %1$s", relativePath),
                        e /*throwable*/, null /*data*/);
            }
        } else {
            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                    "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
                    null /*throwable*/, null /*data*/);
        }

        return null;
    }


    // ---- native methods ----

@@ -169,6 +210,9 @@ public class FontFamily_Delegate {
        return false;
    }


    // ---- private helper methods ----

    private void init() {
        for (String path : mPath) {
            addFont(path);
@@ -183,51 +227,9 @@ public class FontFamily_Delegate {
        }
        FontInfo fontInfo = new FontInfo();
        fontInfo.mFont = font;
        addFontMetadata(fontInfo, path);
        fontInfo.mStyle = getFontStyle(path);
        // TODO ensure that mFonts doesn't have the font with this style already.
        mFonts.add(fontInfo);
        return true;
    }

    private static void addFontMetadata(FontInfo fontInfo, String path) {
        int style = Font.PLAIN;
        String fontName = path.substring(path.lastIndexOf('/'), path.length());
        if (fontName.endsWith(FONT_SUFFIX_BOLDITALIC)) {
            style = Font.BOLD | Font.ITALIC;
        } else if (fontName.endsWith(FONT_SUFFIX_BOLD)) {
            style = Font.BOLD;
        } else if (fontName.endsWith(FONT_SUFFIX_ITALIC)) {
            style = Font.ITALIC;
        }
        fontInfo.mStyle = style;
    }

    private static Font loadFont(String path) {
        if (path.startsWith(SYSTEM_FONTS) ) {
            String relativePath = path.substring(SYSTEM_FONTS.length());
            File f = new File(sFontLocation, relativePath);

            try {
                return Font.createFont(Font.TRUETYPE_FONT, f);
            } catch (Exception e) {
                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
                        String.format("Unable to load font %1$s", relativePath),
                        e /*throwable*/, null /*data*/);
            }
        } else {
            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                    "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
                    null /*throwable*/, null /*data*/);
        }

        return null;
    }


    // ---- Public helper class ----

    public enum FontVariant {
        // The order needs to be kept in sync with android.graphics.FontFamily.
        NONE, COMPACT, ELEGANT
    }
}
+35 −4
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.graphics;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -27,6 +29,7 @@ import android.graphics.FontFamily_Delegate.FontVariant;
import java.awt.Font;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
@@ -55,8 +58,12 @@ public final class Typeface_Delegate {

    // ---- delegate data ----

    @Nullable
    private final FontFamily_Delegate[] mFontFamilies;  // the reference to FontFamily_Delegate.
    private int mStyle;
    @Nullable
    private final Font mFont;
    /** @see FontFamily_Delegate.FontInfo#mStyle */
    private final int mStyle;

    private static long sDefaultTypeface;

@@ -77,8 +84,14 @@ public final class Typeface_Delegate {
     * @param variant The variant preferred. Can only be {@link FontVariant#COMPACT} or
     *                {@link FontVariant#ELEGANT}
     */
    @NonNull
    public List<Font> getFonts(FontVariant variant) {
        assert variant != FontVariant.NONE;
        if (mFontFamilies == null) {
            // We don't care about the variant here, since the Typeface was created with a single
            // Font File. So, we simply return that Font.
            return getFontAsList();
        }
        List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
        for (int i = 0; i < mFontFamilies.length; i++) {
            FontFamily_Delegate ffd = mFontFamilies[i];
@@ -144,10 +157,14 @@ public final class Typeface_Delegate {

    @LayoutlibDelegate
    /*package*/ static synchronized long nativeCreateFromFile(String path) {
        if (!path.startsWith(SYSTEM_FONTS)) {
            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Typeface.createFromFile() is not supported.,", null, null);
                    "Typeface.createFromFile() can only work with platform fonts located in " +
                            SYSTEM_FONTS, null, null);
            return 0;
        }
        return sManager.addNewDelegate(new Typeface_Delegate(path));
    }

    @LayoutlibDelegate
    /*package*/ static synchronized long nativeCreateFromArray(long[] familyArray) {
@@ -188,6 +205,20 @@ public final class Typeface_Delegate {

    private Typeface_Delegate(FontFamily_Delegate[] fontFamilies, int style) {
        mFontFamilies = fontFamilies;
        mFont = null;
        mStyle = style;
    }

    private Typeface_Delegate(String path) {
        mFont = FontFamily_Delegate.loadFont(path);
        mFontFamilies = null;
        mStyle = FontFamily_Delegate.getFontStyle(path);
    }

    private List<Font> getFontAsList() {
        if (mFont != null) {
            return Collections.singletonList(mFont);
        }
        return Collections.emptyList();
    }
}