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

Commit 903dc926 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor font parser for making SystemApi."

parents 121f5679 f5859819
Loading
Loading
Loading
Loading
+240 −90
Original line number Diff line number Diff line
@@ -19,171 +19,268 @@ package android.text;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
import android.net.Uri;
import android.os.Build;
import android.os.LocaleList;

import java.io.File;
import java.lang.annotation.Retention;
import java.util.List;


/**
 * Font configuration descriptions for System fonts.
 * @hide
 * @hide  // TODO Make this SystemApi.
 */
public final class FontConfig {
    private final @NonNull Family[] mFamilies;
    private final @NonNull Alias[] mAliases;
    private final @NonNull List<Family> mFamilies;
    private final @NonNull List<Alias> mAliases;

    public FontConfig(@NonNull Family[] families, @NonNull Alias[] aliases) {
    /**
     * Construct a SystemFontConfig instance.
     *
     * @param families a list of font families.
     * @param aliases a list of aliases.
     *
     * @hide Only system server can create this instance and passed via IPC.
     */
    public FontConfig(@NonNull List<Family> families, @NonNull List<Alias> aliases) {
        mFamilies = families;
        mAliases = aliases;
    }

    /**
     * Returns the ordered list of families included in the system fonts.
     *
     * @return a list of font families.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public @NonNull Family[] getFamilies() {
    public @NonNull List<Family> getFontFamilies() {
        return mFamilies;
    }

    /**
     * Returns the list of aliases defined for the font families in the system fonts.
     *
     * @return a list of font families.
     */
    public @NonNull Alias[] getAliases() {
    public @NonNull List<Alias> getAliases() {
        return mAliases;
    }

    /**
     * Class that holds information about a Font.
     * Returns the ordered list of families included in the system fonts.
     * @deprecated Use getFontFamilies instead.
     */
    @Deprecated
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public @NonNull Family[] getFamilies() {
        return mFamilies.toArray(new Family[0]);
    }

    /**
     * A class represents single font entry in system font configuration.
     */
    public static final class Font {
        private final @NonNull String mFontName;
        private final int mTtcIndex;
        private final @NonNull FontVariationAxis[] mAxes;
        private final int mWeight;
        private final boolean mIsItalic;
        private Uri mUri;
        private final String mFallbackFor;
        private final @NonNull File mFilePath;
        private final @Nullable File mOriginalPath;
        private final @NonNull FontStyle mStyle;
        private final @IntRange(from = 0) int mIndex;
        private final @NonNull String mFontVariationSettings;
        private final @Nullable String mFallback;

        /**
         * @hide
         * Construct a Font instance.
         *
         * @hide Only system server can create this instance and passed via IPC.
         */
        public Font(@NonNull String fontName, int ttcIndex, @NonNull FontVariationAxis[] axes,
                int weight, boolean isItalic, String fallbackFor) {
            mFontName = fontName;
            mTtcIndex = ttcIndex;
            mAxes = axes;
            mWeight = weight;
            mIsItalic = isItalic;
            mFallbackFor = fallbackFor;
        public Font(@NonNull File filePath, @Nullable File originalPath, @NonNull FontStyle style,
                @IntRange(from = 0) int index, @NonNull String fontVariationSettings,
                @Nullable String fallback) {
            mFilePath = filePath;
            mOriginalPath = originalPath;
            mStyle = style;
            mIndex = index;
            mFontVariationSettings = fontVariationSettings;
            mFallback = fallback;
        }

        /**
         * Returns a file to the font file.
         *
         * @return a font file.
         */
        public @NonNull File getFilePath() {
            return mFilePath;
        }

        /**
         * Returns an original font file in the system directory.
         *
         * If the font file is not updated, returns null.
         *
         * @return returns the original font file in the system if the font file is updated. Returns
         *         null if the font file is not updated.
         */
        public @Nullable File getOriginalPath() {
            return mOriginalPath;
        }

        /**
         * Returns the name associated by the system to this font.
         * Returns a font style.
         *
         * @return a font style.
         */
        public @NonNull FontStyle getStyle() {
            return mStyle;
        }

        /**
         * Returns a font index.
         *
         * @return a font index.
         */
        public @IntRange(from = 0) int getIndex() {
            return mIndex;
        }

        /**
         * Return a font variation settings.
         *
         * @return a font variation settings.
         */
        public @NonNull String getFontVariationSettings() {
            return mFontVariationSettings;
        }

        /**
         * Returns font family name that uses this font as a fallback.
         *
         * If this font is a fallback for the default font family, this is null.
         *
         * @return a font family name.
         */
        public @NonNull String getFontName() {
            return mFontName;
        public @Nullable String getFallback() {
            return mFallback;
        }

        /**
         * Returns the index to be used to access this font when accessing a TTC file.
         * @deprecated Use getIndex instead.
         * @hide
         */
        @Deprecated
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public int getTtcIndex() {
            return mTtcIndex;
            return mIndex;
        }

        /**
         * Returns the list of axes associated to this font.
         * @deprecated Use getFontVariationSettings
         * @hide
         */
        @Deprecated
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public @NonNull FontVariationAxis[] getAxes() {
            return mAxes;
            return FontVariationAxis.fromFontVariationSettings(mFontVariationSettings);
        }

        /**
         * Returns the weight value for this font.
         * @deprecated Use getStyle instead.
         * @hide
         */
        @Deprecated
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public int getWeight() {
            return mWeight;
            return getStyle().getWeight();
        }

        /**
         * Returns whether this font is italic.
         * @deprecated Use getStyle instead.
         * @hide
         */
        @Deprecated
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public boolean isItalic() {
            return mIsItalic;
            return getStyle().getSlant() == FontStyle.FONT_SLANT_ITALIC;
        }
    }

    /**
         * Returns the content uri associated to this font.
     * A class represents alias between named font families.
     *
         * You can reach to the font contents by calling {@link
         * android.content.ContentResolver#openInputStream}.
     * In the system font configuration, an font family can be an alias of another font family with
     * different font weight. For example, "sans-serif-medium" can be a medium weight of
     * sans-serif font family.
     */
        public @Nullable Uri getUri() {
            return mUri;
        }

        public void setUri(@NonNull Uri uri) {
            mUri = uri;
        }

        public String getFallbackFor() {
            return mFallbackFor;
        }
    }
    public static final class Alias {
        private final @NonNull String mAliasName;
        private final @NonNull String mReferName;
        private final @IntRange(from = 0, to = 1000) int mWeight;

        /**
     * Class that holds information about a Font alias.
         * Construct an alias instance.
         *
         * @param aliasName an alias of the named font family.
         * @param referName a referring font family name.
         * @param weight a font weight of the referring font family.
         * @hide Only system server can create this instance and passed via IPC.
         */
    public static final class Alias {
        private final @NonNull String mName;
        private final @NonNull String mToName;
        private final int mWeight;

        public Alias(@NonNull String name, @NonNull String toName, int weight) {
            mName = name;
            mToName = toName;
        public Alias(@NonNull String aliasName, @NonNull String referName,
                @IntRange(from = 0, to = 1000) int weight) {
            mAliasName = aliasName;
            mReferName = referName;
            mWeight = weight;
        }

        /**
         * Returns the new name for the alias.
         * An alias of the named font family.
         *
         * @return an alias of the named font family.
         */
        public @NonNull String getName() {
            return mName;
        public @NonNull String getAliasName() {
            return mAliasName;
        }

        /**
         * Returns the existing name to which this alias points to.
         * A name of font family referring from {@link #getAliasName()}
         *
         * @return a referring font family name.
         */
        public @NonNull String getToName() {
            return mToName;
        public @NonNull String getReferName() {
            return mReferName;
        }

        /**
         * Returns the weight associated with this alias.
         * A font weight of the referring font family.
         *
         * @return a font weight of the referring font family.
         */
        public int getWeight() {
        public @IntRange(from = 0, to = 1000) int getWeight() {
            return mWeight;
        }
    }

    /**
     * Class that holds information about a Font family.
     * A class represents single font family entry in system font configuration.
     *
     * <p>
     * A font family is a bundle of fonts for drawing text in various styles.
     * For example, regular style font and bold style font can be bundled into a single font family,
     * then system will select the correct style font from family for drawing.
     */
    public static final class Family {
        private final @NonNull String mName;
        private final @NonNull Font[] mFonts;
        // Comma separated BCP47 complient locale strings
        private final @NonNull String mLanguages;
        private final @NonNull List<Font> mFonts;
        private final @Nullable String mName;
        private final @Nullable LocaleList mLocaleList;
        private final @Variant int mVariant;

        /** @hide */
        @Retention(SOURCE)
@@ -212,52 +309,105 @@ public final class FontConfig {
        /**
         * Value for font variant.
         *
         * Indiates the font is for elegant variant.
         * Indicates the font is for elegant variant.
         * @see android.graphics.Paint#setElegantTextHeight
         */
        public static final int VARIANT_ELEGANT = 2;

        // Must be same with Minikin's variant values.
        // See frameworks/minikin/include/minikin/FontFamily.h
        private final @Variant int mVariant;

        public Family(@NonNull String name, @NonNull Font[] fonts, @NonNull String languages,
                @Variant int variant) {
            mName = name;
        /**
         * Construct a family instance.
         *
         * @hide Only system server can create this instance and passed via IPC.
         */
        public Family(@NonNull List<Font> fonts, @Nullable String name,
                @Nullable LocaleList localeList, @Variant int variant) {
            mFonts = fonts;
            mLanguages = languages;
            mName = name;
            mLocaleList = localeList;
            mVariant = variant;
        }

        /**
         * Returns the name given by the system to this font family.
         * Returns a list of font files in this family.
         *
         * @return a list of font files.
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public @Nullable String getName() {
        public @NonNull List<Font> getFontList() {
            return mFonts;
        }

        /**
         * Returns a family name if this family defines a new fallback.
         *
         * @return non-null if a family name is associated. Otherwise null.
         */
        public @Nullable String getFallbackName() {
            return mName;
        }

        /**
         * Returns the list of fonts included in this family.
         * Returns a locale list if associated.
         *
         * @return non-null if a locale list is associated. Otherwise null.
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public @Nullable Font[] getFonts() {
            return mFonts;
        public @NonNull LocaleList getLocaleList() {
            return mLocaleList;
        }

        /**
         * Returns the comma separated BCP47 complient languages for this family. May be null.
         * Returns a text height variant.
         *
         * @return text height variant.
         */
        public @NonNull String getLanguages() {
            return mLanguages;
        public @Variant int getTextHeightVariant() {
            return mVariant;
        }

        /**
         * Returns the font variant for this family, e.g. "elegant" or "compact". May be null.
         * Returns a family variant associated.
         *
         * @return a family variant.
         * @deprecated Use getTextHeightVariant instead.
         * @hide
         */
        @Deprecated
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public @Variant int getVariant() {
            return mVariant;
        }

        /**
         * Returns a family name if associated.
         *
         * @return non-null if a family name is associated. Otherwise null.
         * @deprecated Use getFallbackName instead.
         * @hide
         */
        @Deprecated
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public @Nullable String getName() {
            return mName;
        }

        /**
         * Returns the list of fonts included in this family.
         * @deprecated Use getFontFiles instead
         * @hide
         */
        @Deprecated
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public @Nullable Font[] getFonts() {
            return mFonts.toArray(new Font[0]);
        }

        /**
         * Returns the comma separated BCP47 compliant languages for this family. May be null.
         * @deprecated Use getLocaleList instead
         * @hide
         */
        @Deprecated
        public @NonNull String getLanguages() {
            return mLocaleList.toLanguageTags();
        }
    }
}
+67 −67

File changed.

Preview size limit exceeded, changes collapsed.

+4 −6
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.graphics.fonts.FontFamily;
import android.graphics.fonts.SystemFonts;
import android.os.SharedMemory;
import android.text.FontConfig;
import android.util.Pair;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
@@ -41,7 +40,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;

import java.nio.ByteOrder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@@ -197,10 +195,10 @@ public class TypefaceTest {
    @SmallTest
    @Test
    public void testSerialize() throws Exception {
        HashMap<String, Typeface> systemFontMap = new HashMap<>();
        Pair<FontConfig.Alias[], Map<String, FontFamily[]>> res =
                SystemFonts.initializePreinstalledFonts();
        Typeface.initSystemDefaultTypefaces(systemFontMap, res.second, res.first);
        FontConfig fontConfig = SystemFonts.getSystemPreinstalledFontConfig();
        Map<String, FontFamily[]> fallbackMap = SystemFonts.buildSystemFallback(fontConfig);
        Map<String, Typeface> systemFontMap = SystemFonts.buildSystemTypefaces(fontConfig,
                fallbackMap);
        SharedMemory sharedMemory = Typeface.serializeFontMap(systemFontMap);
        Map<String, Typeface> copiedFontMap =
                Typeface.deserializeFontMap(sharedMemory.mapReadOnly().order(ByteOrder.BIG_ENDIAN));
+14 −9
Original line number Diff line number Diff line
@@ -19,14 +19,15 @@ package android.text;
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.FontListParser;
import android.graphics.Typeface;
import android.graphics.fonts.FontCustomizationParser;
import android.graphics.fonts.FontFamily;
import android.graphics.fonts.SystemFonts;
import android.util.ArrayMap;

import androidx.test.InstrumentationRegistry;

import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -34,12 +35,13 @@ import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Map;

public class FontFallbackSetup implements AutoCloseable {
    private final String[] mTestFontFiles;
    private final String mXml;
    private final String mTestFontsDir;
    final ArrayMap<String, Typeface> mFontMap = new ArrayMap<>();
    private final Map<String, Typeface> mFontMap;

    public FontFallbackSetup(@NonNull String testSubDir, @NonNull String[] testFontFiles,
            @NonNull String xml) {
@@ -75,12 +77,15 @@ public class FontFallbackSetup implements AutoCloseable {
            throw new RuntimeException(e);
        }

        final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
        final FontCustomizationParser.Result oemCustomization =
                new FontCustomizationParser.Result();
        final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(testFontsXml,
                mTestFontsDir, oemCustomization, fallbackMap);
        Typeface.initSystemDefaultTypefaces(mFontMap, fallbackMap, aliases);
        FontConfig fontConfig;
        try {
            fontConfig = FontListParser.parse(testFontsXml, mTestFontsDir, null, null, null);
        } catch (IOException | XmlPullParserException e) {
            throw new RuntimeException(e);
        }

        Map<String, FontFamily[]> fallbackMap = SystemFonts.buildSystemFallback(fontConfig);
        mFontMap = SystemFonts.buildSystemTypefaces(fontConfig, fallbackMap);
    }

    @NonNull
+104 −33

File changed.

Preview size limit exceeded, changes collapsed.

Loading