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

Commit 8b221ae6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use variable definition for variable font family" into main

parents 6275c619 4b4024b5
Loading
Loading
Loading
Loading
+22 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontFamily.Builder.VariableFontFamilyType;
import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
import android.os.Build;
@@ -528,6 +529,7 @@ public final class FontConfig implements Parcelable {
        private final @NonNull List<Font> mFonts;
        private final @NonNull LocaleList mLocaleList;
        private final @Variant int mVariant;
        private final int mVariableFontFamilyType;

        /** @hide */
        @Retention(SOURCE)
@@ -567,10 +569,11 @@ public final class FontConfig implements Parcelable {
         * @hide Only system server can create this instance and passed via IPC.
         */
        public FontFamily(@NonNull List<Font> fonts, @NonNull LocaleList localeList,
                @Variant int variant) {
                @Variant int variant, int variableFontFamilyType) {
            mFonts = fonts;
            mLocaleList = localeList;
            mVariant = variant;
            mVariableFontFamilyType = variableFontFamilyType;
        }

        /**
@@ -621,6 +624,20 @@ public final class FontConfig implements Parcelable {
            return mVariant;
        }

        /**
         * Returns the font family type.
         *
         * @see Builder#VARIABLE_FONT_FAMILY_TYPE_NONE
         * @see Builder#VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL
         * @see Builder#VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY
         * @see Builder#VARIABLE_FONT_FAMILY_TYPE_TWO_FONTS_WGHT
         * @hide
         * @return variable font family type.
         */
        public @VariableFontFamilyType int getVariableFontFamilyType() {
            return mVariableFontFamilyType;
        }

        @Override
        public int describeContents() {
            return 0;
@@ -631,6 +648,7 @@ public final class FontConfig implements Parcelable {
            dest.writeTypedList(mFonts, flags);
            dest.writeString8(mLocaleList.toLanguageTags());
            dest.writeInt(mVariant);
            dest.writeInt(mVariableFontFamilyType);
        }

        public static final @NonNull Creator<FontFamily> CREATOR = new Creator<FontFamily>() {
@@ -641,8 +659,10 @@ public final class FontConfig implements Parcelable {
                source.readTypedList(fonts, Font.CREATOR);
                String langTags = source.readString8();
                int variant = source.readInt();
                int varFamilyType = source.readInt();

                return new FontFamily(fonts, LocaleList.forLanguageTags(langTags), variant);
                return new FontFamily(fonts, LocaleList.forLanguageTags(langTags), variant,
                        varFamilyType);
            }

            @Override
+31 −8
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.fail;

import android.graphics.fonts.FontCustomizationParser;
import android.graphics.fonts.FontFamily;
import android.graphics.fonts.FontStyle;
import android.os.LocaleList;
import android.text.FontConfig;
@@ -64,7 +65,8 @@ public final class FontListParserTest {
                Collections.singletonList(new FontConfig.FontFamily(
                    Arrays.asList(new FontConfig.Font(new File("test.ttf"), null, "test",
                        new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 0, "", null)),
                    LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif");
                    LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT,
                        FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), "sans-serif");
        FontConfig.NamedFamilyList family = readNamedFamily(xml);
        assertThat(family).isEqualTo(expected);
    }
@@ -84,7 +86,8 @@ public final class FontListParserTest {
                        new FontConfig.Font(new File("test.ttf"), null, "test",
                                new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
                                0, "", "serif")),
                LocaleList.forLanguageTags("en"), VARIANT_DEFAULT);
                LocaleList.forLanguageTags("en"), VARIANT_DEFAULT,
                FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE);

        FontConfig.FontFamily family = readFamily(xml);
        assertThat(family).isEqualTo(expected);
@@ -101,7 +104,8 @@ public final class FontListParserTest {
                        new FontConfig.Font(new File("test.ttf"), null, "test",
                                new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
                                0, "", null)),
                LocaleList.forLanguageTags("en"), VARIANT_COMPACT);
                LocaleList.forLanguageTags("en"), VARIANT_COMPACT,
                FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE);

        FontConfig.FontFamily family = readFamily(xml);
        assertThat(family).isEqualTo(expected);
@@ -118,7 +122,8 @@ public final class FontListParserTest {
                        new FontConfig.Font(new File("test.ttf"), null, "test",
                                new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
                                0, "", null)),
                LocaleList.forLanguageTags("en"), VARIANT_ELEGANT);
                LocaleList.forLanguageTags("en"), VARIANT_ELEGANT,
                FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE);

        FontConfig.FontFamily family = readFamily(xml);
        assertThat(family).isEqualTo(expected);
@@ -140,7 +145,8 @@ public final class FontListParserTest {
                        new FontStyle(100, FONT_SLANT_UPRIGHT), 0, "", null),
                      new FontConfig.Font(new File("italic.ttf"), null, "test",
                        new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC), 0, "", null)),
                    LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif");
                    LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT,
                        FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), "sans-serif");
        FontConfig.NamedFamilyList family = readNamedFamily(xml);
        assertThat(family).isEqualTo(expected);
    }
@@ -166,7 +172,8 @@ public final class FontListParserTest {
                        new FontConfig.Font(new File("test-VF.ttf"), null, "test",
                                new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
                                0, "'wdth' 400.0,'wght' 700.0", null)),
                        LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)),
                        LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT,
                        FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)),
                "sans-serif");
        FontConfig.NamedFamilyList family = readNamedFamily(xml);
        assertThat(family).isEqualTo(expected);
@@ -187,7 +194,8 @@ public final class FontListParserTest {
                        new FontConfig.Font(new File("test.ttc"), null, "test",
                                new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
                                1, "", null)),
                                LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)),
                                LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT,
                        FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)),
                "sans-serif");
        FontConfig.NamedFamilyList family = readNamedFamily(xml);
        assertThat(family).isEqualTo(expected);
@@ -206,7 +214,8 @@ public final class FontListParserTest {
                        new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 0, "", null),
                      new FontConfig.Font(new File("test.ttc"), null, "test",
                        new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 1, "", null)),
                    LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif");
                    LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT,
                        FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), "sans-serif");
        FontConfig.NamedFamilyList family = readNamedFamily(xml);
        assertThat(family).isEqualTo(expected);
    }
@@ -372,6 +381,20 @@ public final class FontListParserTest {
                .isEqualTo("emoji.ttf");
    }

    @Test
    public void varFamilyType() throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
                + "<familyset>"
                + "  <family name='sans-serif' varFamilyType='1'>"
                + "    <font>test.ttf</font>"
                + "  </family>"
                + "</familyset>";
        FontConfig config = readFamilies(xml, true /* include non-existing font files */);
        List<FontConfig.FontFamily> families = config.getFontFamilies();
        assertThat(families.size()).isEqualTo(1);  // legacy one should be ignored.
        assertThat(families.get(0).getVariableFontFamilyType()).isEqualTo(1);
    }

    private FontConfig readFamilies(String xml, boolean allowNonExisting)
            throws IOException, XmlPullParserException {
        ByteArrayInputStream buffer = new ByteArrayInputStream(
+82 −829

File changed.

Preview size limit exceeded, changes collapsed.

+40 −1
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package android.graphics;

import static android.graphics.fonts.FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE;
import static android.graphics.fonts.FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL;
import static android.graphics.fonts.FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY;
import static android.graphics.fonts.FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_TWO_FONTS_WGHT;
import static android.text.FontConfig.NamedFamilyList;

import android.annotation.NonNull;
@@ -28,6 +32,7 @@ import android.os.Build;
import android.os.LocaleList;
import android.text.FontConfig;
import android.util.ArraySet;
import android.util.Log;
import android.util.Xml;

import org.xmlpull.v1.XmlPullParser;
@@ -256,6 +261,7 @@ public class FontListParser {
        final String lang = parser.getAttributeValue("", "lang");
        final String variant = parser.getAttributeValue(null, "variant");
        final String ignore = parser.getAttributeValue(null, "ignore");
        final String varFamilyTypeStr = parser.getAttributeValue(null, "varFamilyType");
        final List<FontConfig.Font> fonts = new ArrayList<>();
        while (keepReading(parser)) {
            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
@@ -278,12 +284,45 @@ public class FontListParser {
                intVariant = FontConfig.FontFamily.VARIANT_ELEGANT;
            }
        }
        int varFamilyType = VARIABLE_FONT_FAMILY_TYPE_NONE;
        if (varFamilyTypeStr != null) {
            varFamilyType = Integer.parseInt(varFamilyTypeStr);
            if (varFamilyType <= -1 || varFamilyType > 3) {
                Log.e(TAG, "Error: unexpected varFamilyType value: " + varFamilyTypeStr);
                varFamilyType = VARIABLE_FONT_FAMILY_TYPE_NONE;
            }

            // validation but don't read font content for performance reasons.
            switch (varFamilyType) {
                case VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY:
                    if (fonts.size() != 1) {
                        Log.e(TAG, "Error: Single font support wght axis, but two or more fonts are"
                                + " included in the font family.");
                        varFamilyType = VARIABLE_FONT_FAMILY_TYPE_NONE;
                    }
                    break;
                case VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL:
                    if (fonts.size() != 1) {
                        Log.e(TAG, "Error: Single font support both ital and wght axes, but two or"
                                + " more fonts are included in the font family.");
                        varFamilyType = VARIABLE_FONT_FAMILY_TYPE_NONE;
                    }
                    break;
                case VARIABLE_FONT_FAMILY_TYPE_TWO_FONTS_WGHT:
                    if (fonts.size() != 2) {
                        Log.e(TAG, "Error: two fonts that support wght axis, but one or three or"
                                + " more fonts are included in the font family.");
                        varFamilyType = VARIABLE_FONT_FAMILY_TYPE_NONE;
                    }
            }
        }

        boolean skip = (ignore != null && (ignore.equals("true") || ignore.equals("1")));
        if (skip || fonts.isEmpty()) {
            return null;
        }
        return new FontConfig.FontFamily(fonts, LocaleList.forLanguageTags(lang), intVariant);
        return new FontConfig.FontFamily(fonts, LocaleList.forLanguageTags(lang), intVariant,
                varFamilyType);
    }

    private static void throwIfAttributeExists(String attrName, XmlPullParser parser) {
+34 −1
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ package android.graphics.fonts;

import static com.android.text.flags.Flags.FLAG_DEPRECATE_FONTS_XML;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -32,6 +35,7 @@ import dalvik.annotation.optimization.FastNative;

import libcore.util.NativeAllocationRegistry;

import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Set;

@@ -184,32 +188,59 @@ public final class FontFamily {
        }

        /**
         * A special variable font family type that indicates `analyzeAndResolveVariableType` could
         * not be identified the variable font family type.
         *
         * @see #buildVariableFamily()
         * @hide
         */
        public static final int VARIABLE_FONT_FAMILY_TYPE_UNKNOWN = -1;

        /**
         * A variable font family type that indicates no variable font family can be used.
         *
         * The font family is used as bundle of static fonts.
         * @see #buildVariableFamily()
         * @hide
         */
        public static final int VARIABLE_FONT_FAMILY_TYPE_NONE = 0;
        /**
         * A variable font family type that indicates single font file can be used for multiple
         * weight. For the italic style, fake italic may be applied.
         *
         * @see #buildVariableFamily()
         * @hide
         */
        public static final int VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY = 1;
        /**
         * A variable font family type that indicates single font file can be used for multiple
         * weight and italic.
         *
         * @see #buildVariableFamily()
         * @hide
         */
        public static final int VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL = 2;
        /**
         * A variable font family type that indicates two font files are included in the family:
         * one can be used for upright with various weights, the other one can be used for italic
         * with various weights.
         *
         * @see #buildVariableFamily()
         * @hide
         */
        public static final int VARIABLE_FONT_FAMILY_TYPE_TWO_FONTS_WGHT = 3;

        /** @hide */
        @Retention(SOURCE)
        @IntDef(prefix = { "VARIABLE_FONT_FAMILY_TYPE_" }, value = {
                VARIABLE_FONT_FAMILY_TYPE_UNKNOWN,
                VARIABLE_FONT_FAMILY_TYPE_NONE,
                VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY,
                VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL,
                VARIABLE_FONT_FAMILY_TYPE_TWO_FONTS_WGHT
        })
        public @interface VariableFontFamilyType {}

        /**
         * The registered italic axis used for adjusting requested style.
         * https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_ital
@@ -222,7 +253,9 @@ public final class FontFamily {
         */
        private static final int TAG_wght = 0x77676874;  // w(0x77), g(0x67), h(0x68), t(0x74)

        private static int analyzeAndResolveVariableType(ArrayList<Font> fonts) {
        /** @hide */
        public static @VariableFontFamilyType int analyzeAndResolveVariableType(
                ArrayList<Font> fonts) {
            if (fonts.size() > 2) {
                return VARIABLE_FONT_FAMILY_TYPE_UNKNOWN;
            }
Loading