diff options
| author | 2024-01-31 04:26:06 +0000 | |
|---|---|---|
| committer | 2024-01-31 04:26:06 +0000 | |
| commit | ebb3b96cdedec7343e46794c463fdccf59c8891a (patch) | |
| tree | 4a76d5cd99f91dbc9ab84856bbdae7055200facd | |
| parent | 0744deb63f8a3ded3bdae4a91839fa18c02dbbba (diff) | |
| parent | 4035d7e59b54b3ce71cfb657bd35519398229de3 (diff) | |
Merge "Redesign the fallback XML syntax to be able to have static and variable font." into main
8 files changed, 551 insertions, 420 deletions
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index 94c8eaf13ccb..783f3b7aa64b 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -26,7 +26,6 @@ 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.icu.util.ULocale; @@ -240,6 +239,23 @@ public final class FontConfig implements Parcelable { private final @IntRange(from = 0) int mIndex; private final @NonNull String mFontVariationSettings; private final @Nullable String mFontFamilyName; + private final @VarTypeAxes int mVarTypeAxes; + + /** @hide */ + @Retention(SOURCE) + @IntDef(prefix = { "VAR_TYPE_AXES_" }, value = { + VAR_TYPE_AXES_NONE, + VAR_TYPE_AXES_WGHT, + VAR_TYPE_AXES_ITAL, + }) + public @interface VarTypeAxes {} + + /** @hide */ + public static final int VAR_TYPE_AXES_NONE = 0; + /** @hide */ + public static final int VAR_TYPE_AXES_WGHT = 1; + /** @hide */ + public static final int VAR_TYPE_AXES_ITAL = 2; /** * Construct a Font instance. @@ -248,7 +264,8 @@ public final class FontConfig implements Parcelable { */ public Font(@NonNull File file, @Nullable File originalFile, @NonNull String postScriptName, @NonNull FontStyle style, @IntRange(from = 0) int index, - @NonNull String fontVariationSettings, @Nullable String fontFamilyName) { + @NonNull String fontVariationSettings, @Nullable String fontFamilyName, + @VarTypeAxes int varTypeAxes) { mFile = file; mOriginalFile = originalFile; mPostScriptName = postScriptName; @@ -256,6 +273,7 @@ public final class FontConfig implements Parcelable { mIndex = index; mFontVariationSettings = fontVariationSettings; mFontFamilyName = fontFamilyName; + mVarTypeAxes = varTypeAxes; } @Override @@ -273,6 +291,7 @@ public final class FontConfig implements Parcelable { dest.writeInt(mIndex); dest.writeString8(mFontVariationSettings); dest.writeString8(mFontFamilyName); + dest.writeInt(mVarTypeAxes); } public static final @NonNull Creator<Font> CREATOR = new Creator<Font>() { @@ -288,9 +307,10 @@ public final class FontConfig implements Parcelable { int index = source.readInt(); String varSettings = source.readString8(); String fallback = source.readString8(); + int varTypeAxes = source.readInt(); return new Font(path, originalPath, postScriptName, new FontStyle(weight, slant), - index, varSettings, fallback); + index, varSettings, fallback, varTypeAxes); } @Override @@ -366,6 +386,15 @@ public final class FontConfig implements Parcelable { } /** + * Returns the list of supported axes tags for variable family type resolution. + * + * @hide + */ + public @VarTypeAxes int getVarTypeAxes() { + return mVarTypeAxes; + } + + /** * Returns the list of axes associated to this font. * @deprecated Use getFontVariationSettings * @hide @@ -408,13 +437,14 @@ public final class FontConfig implements Parcelable { && Objects.equals(mOriginalFile, font.mOriginalFile) && Objects.equals(mStyle, font.mStyle) && Objects.equals(mFontVariationSettings, font.mFontVariationSettings) - && Objects.equals(mFontFamilyName, font.mFontFamilyName); + && Objects.equals(mFontFamilyName, font.mFontFamilyName) + && mVarTypeAxes == font.mVarTypeAxes; } @Override public int hashCode() { return Objects.hash(mFile, mOriginalFile, mStyle, mIndex, mFontVariationSettings, - mFontFamilyName); + mFontFamilyName, mVarTypeAxes); } @Override @@ -426,6 +456,7 @@ public final class FontConfig implements Parcelable { + ", mIndex=" + mIndex + ", mFontVariationSettings='" + mFontVariationSettings + '\'' + ", mFontFamilyName='" + mFontFamilyName + '\'' + + ", mVarTypeAxes='" + mVarTypeAxes + '\'' + '}'; } } @@ -549,7 +580,6 @@ 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) @@ -589,11 +619,10 @@ 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, int variableFontFamilyType) { + @Variant int variant) { mFonts = fonts; mLocaleList = localeList; mVariant = variant; - mVariableFontFamilyType = variableFontFamilyType; } /** @@ -644,20 +673,6 @@ 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; @@ -668,7 +683,6 @@ 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>() { @@ -679,10 +693,8 @@ 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, - varFamilyType); + return new FontFamily(fonts, LocaleList.forLanguageTags(langTags), variant); } @Override diff --git a/core/tests/coretests/src/android/graphics/FontListParserTest.java b/core/tests/coretests/src/android/graphics/FontListParserTest.java index 4dd5889fdf5d..5f96c1789015 100644 --- a/core/tests/coretests/src/android/graphics/FontListParserTest.java +++ b/core/tests/coretests/src/android/graphics/FontListParserTest.java @@ -22,14 +22,18 @@ import static android.graphics.fonts.FontStyle.FONT_WEIGHT_NORMAL; import static android.text.FontConfig.FontFamily.VARIANT_COMPACT; import static android.text.FontConfig.FontFamily.VARIANT_DEFAULT; import static android.text.FontConfig.FontFamily.VARIANT_ELEGANT; +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_ONLY; +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_TWO_FONTS_WGHT; 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.graphics.fonts.SystemFonts; import android.os.LocaleList; import android.text.FontConfig; import android.util.Xml; @@ -64,9 +68,9 @@ public final class FontListParserTest { FontConfig.NamedFamilyList expected = new FontConfig.NamedFamilyList( 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, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), "sans-serif"); + new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 0, "", null, + FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif"); FontConfig.NamedFamilyList family = readNamedFamily(xml); assertThat(family).isEqualTo(expected); } @@ -82,12 +86,11 @@ public final class FontListParserTest { Arrays.asList( new FontConfig.Font(new File("test.ttf"), null, "test", new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), - 0, "", null), + 0, "", null, FontConfig.Font.VAR_TYPE_AXES_NONE), new FontConfig.Font(new File("test.ttf"), null, "test", new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), - 0, "", "serif")), - LocaleList.forLanguageTags("en"), VARIANT_DEFAULT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE); + 0, "", "serif", FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.forLanguageTags("en"), VARIANT_DEFAULT); FontConfig.FontFamily family = readFamily(xml); assertThat(family).isEqualTo(expected); @@ -103,9 +106,8 @@ public final class FontListParserTest { Arrays.asList( new FontConfig.Font(new File("test.ttf"), null, "test", new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), - 0, "", null)), - LocaleList.forLanguageTags("en"), VARIANT_COMPACT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE); + 0, "", null, FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.forLanguageTags("en"), VARIANT_COMPACT); FontConfig.FontFamily family = readFamily(xml); assertThat(family).isEqualTo(expected); @@ -121,9 +123,8 @@ public final class FontListParserTest { Arrays.asList( new FontConfig.Font(new File("test.ttf"), null, "test", new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), - 0, "", null)), - LocaleList.forLanguageTags("en"), VARIANT_ELEGANT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE); + 0, "", null, FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.forLanguageTags("en"), VARIANT_ELEGANT); FontConfig.FontFamily family = readFamily(xml); assertThat(family).isEqualTo(expected); @@ -140,13 +141,15 @@ public final class FontListParserTest { FontConfig.NamedFamilyList expected = new FontConfig.NamedFamilyList( Collections.singletonList(new FontConfig.FontFamily(Arrays.asList( new FontConfig.Font(new File("normal.ttf"), null, "test", - new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 0, "", null), + new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 0, "", null, + FontConfig.Font.VAR_TYPE_AXES_NONE), new FontConfig.Font(new File("weight.ttf"), null, "test", - new FontStyle(100, FONT_SLANT_UPRIGHT), 0, "", null), + new FontStyle(100, FONT_SLANT_UPRIGHT), 0, "", null, + FontConfig.Font.VAR_TYPE_AXES_NONE), new FontConfig.Font(new File("italic.ttf"), null, "test", - new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC), 0, "", null)), - LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), "sans-serif"); + new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC), 0, "", null, + FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif"); FontConfig.NamedFamilyList family = readNamedFamily(xml); assertThat(family).isEqualTo(expected); } @@ -168,12 +171,13 @@ public final class FontListParserTest { Collections.singletonList(new FontConfig.FontFamily(Arrays.asList( new FontConfig.Font(new File("test-VF.ttf"), null, "test", new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), - 0, "'wdth' 100.0,'wght' 200.0", null), + 0, "'wdth' 100.0,'wght' 200.0", null, + FontConfig.Font.VAR_TYPE_AXES_NONE), 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, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), + 0, "'wdth' 400.0,'wght' 700.0", null, + FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif"); FontConfig.NamedFamilyList family = readNamedFamily(xml); assertThat(family).isEqualTo(expected); @@ -190,12 +194,11 @@ public final class FontListParserTest { Collections.singletonList(new FontConfig.FontFamily(Arrays.asList( new FontConfig.Font(new File("test.ttc"), null, "test", new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), - 0, "", null), + 0, "", null, FontConfig.Font.VAR_TYPE_AXES_NONE), new FontConfig.Font(new File("test.ttc"), null, "test", new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), - 1, "", null)), - LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), + 1, "", null, FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif"); FontConfig.NamedFamilyList family = readNamedFamily(xml); assertThat(family).isEqualTo(expected); @@ -211,11 +214,12 @@ public final class FontListParserTest { FontConfig.NamedFamilyList expected = new FontConfig.NamedFamilyList( Collections.singletonList(new FontConfig.FontFamily(Arrays.asList( new FontConfig.Font(new File("test.ttc"), null, "foo", - new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 0, "", null), + new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 0, "", null, + FontConfig.Font.VAR_TYPE_AXES_NONE), new FontConfig.Font(new File("test.ttc"), null, "test", - new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 1, "", null)), - LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE)), "sans-serif"); + new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT), 1, "", null, + FontConfig.Font.VAR_TYPE_AXES_NONE)), + LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT)), "sans-serif"); FontConfig.NamedFamilyList family = readNamedFamily(xml); assertThat(family).isEqualTo(expected); } @@ -385,14 +389,81 @@ public final class FontListParserTest { 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 name='sans-serif'>" + + " <font supportedAxes='wght'>test.ttf</font>" + + " <font supportedAxes='ital'>test.ttf</font>" + + " <font supportedAxes='wght,ital'>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); + assertThat(families.get(0).getFontList().get(0).getVarTypeAxes()) + .isEqualTo(FontConfig.Font.VAR_TYPE_AXES_WGHT); + assertThat(families.get(0).getFontList().get(1).getVarTypeAxes()) + .isEqualTo(FontConfig.Font.VAR_TYPE_AXES_ITAL); + assertThat(families.get(0).getFontList().get(2).getVarTypeAxes()) + .isEqualTo(FontConfig.Font.VAR_TYPE_AXES_WGHT | FontConfig.Font.VAR_TYPE_AXES_ITAL); + } + + @Test + public void varFamilyTypeRsolve() throws Exception { + String xml = "<?xml version='1.0' encoding='UTF-8'?>" + + "<familyset>" + + " <family name='sans-serif'>" + + " <font style='normal' supportedAxes='wght'>test.ttf</font>" + + " </family>" + + " <family>" + + " <font style='normal' supportedAxes='wght'>test.ttf</font>" + + " <font style='italic' supportedAxes='wght'>test.ttf</font>" + + " </family>" + + " <family>" + + " <font supportedAxes='wght,ital'>test.ttf</font>" + + " </family>" + + " <family>" + + " <font supportedAxes='ital'>test.ttf</font>" + + " </family>" + + " <family>" + + " <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(5); + assertThat(SystemFonts.resolveVarFamilyType(families.get(0), null)) + .isEqualTo(VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY); + assertThat(SystemFonts.resolveVarFamilyType(families.get(1), null)) + .isEqualTo(VARIABLE_FONT_FAMILY_TYPE_TWO_FONTS_WGHT); + assertThat(SystemFonts.resolveVarFamilyType(families.get(2), null)) + .isEqualTo(VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL); + assertThat(SystemFonts.resolveVarFamilyType(families.get(3), null)) + .isEqualTo(VARIABLE_FONT_FAMILY_TYPE_NONE); + assertThat(SystemFonts.resolveVarFamilyType(families.get(4), null)) + .isEqualTo(VARIABLE_FONT_FAMILY_TYPE_NONE); + } + + @Test + public void varFamilyTypeRsolve_ForName() throws Exception { + String xml = "<?xml version='1.0' encoding='UTF-8'?>" + + "<familyset>" + + " <family name='sans-serif'>" + + " <font style='normal' supportedAxes='wght'>test.ttf</font>" + + " </family>" + + " <family name='serif'>" + + " <font style='normal' supportedAxes='wght'>test.ttf</font>" + + " </family>" + + " <family>" + + " <font style='normal' supportedAxes='wght'>test.ttf</font>" + + " <font fallbackFor='serif' supportedAxes='wght,ital'>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(2); + assertThat(SystemFonts.resolveVarFamilyType(families.get(1), null)) + .isEqualTo(VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY); + assertThat(SystemFonts.resolveVarFamilyType(families.get(1), "serif")) + .isEqualTo(VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL); } private FontConfig readFamilies(String xml, boolean allowNonExisting) diff --git a/data/fonts/font_fallback.xml b/data/fonts/font_fallback.xml index 1bd182f96bde..15ea15a9b4c1 100644 --- a/data/fonts/font_fallback.xml +++ b/data/fonts/font_fallback.xml @@ -11,12 +11,84 @@ effectively add 300 to the weight, this ensures that 900 is the bold paired with the 500 weight, ensuring adequate contrast. - TODO(rsheeter) update comment; ordering to match 800 to 900 is no longer required + + The font_fallback.xml defines the list of font used by the system. + + `familyset` node: + A `familyset` element must be a root node of the font_fallback.xml. No attributes are allowed + to `familyset` node. + The `familyset` node can contains `family` and `alias` nodes. Any other nodes will be ignored. + + `family` node: + A `family` node defines a single font family definition. + A font family is a set of fonts for drawing text in various styles such as weight, slant. + There are three types of families, default family, named family and locale fallback family. + + The default family is a special family node appeared the first node of the `familyset` node. + The default family is used as first priority fallback. + Only `name` attribute can be used for default family node. If the `name` attribute is + specified, This family will also works as named family. + + The named family is a family that has name attribute. The named family defines a new fallback. + For example, if the name attribute is "serif", it creates serif fallback. Developers can + access the fallback by using Typeface#create API. + The named family can not have attribute other than `name` attribute. The `name` attribute + cannot be empty. + + The locale fallback family is a font family that is used for fallback. The fallback family is + used when the named family or default family cannot be used. The locale fallback family can + have `lang` attribute and `variant` attribute. The `lang` attribute is an optional comma + separated BCP-47i language tag. The `variant` is an optional attribute that can be one one + `element`, `compact`. If a `variant` attribute is not specified, it is treated as default. + + `alias` node: + An `alias` node defines a alias of named family with changing weight offset. An `alias` node + can have mandatory `name` and `to` attribute and optional `weight` attribute. This `alias` + defines new fallback that has the name of specified `name` attribute. The fallback list is + the same to the fallback that of the name specified with `to` attribute. If `weight` attribute + is specified, the base weight offset is shifted to the specified value. For example, if the + `weight` is 500, the output text is drawn with 500 of weight. + + `font` node: + A `font` node defines a single font definition. There are two types of fonts, static font and + variable font. + + A static font can have `weight`, `style`, `index` and `postScriptName` attributes. A `weight` + is a mandatory attribute that defines the weight of the font. Any number between 0 to 1000 is + valid. A `style` is a mandatory attribute that defines the style of the font. A 'style' + attribute can be `normal` or `italic`. An `index` is an optional attribute that defines the + index of the font collection. If this is not specified, it is treated as 0. If the font file + is not a font collection, this attribute is ignored. A `postScriptName` attribute is an + optional attribute. A PostScript name is used for identifying target of system font update. + If this is not specified, the system assumes the filename is same to PostScript name of the + font file. For example, if the font file is "Roboto-Regular.ttf", the system assume the + PostScript name of this font is "Roboto-Regular". + + A variable font can be only defined for the variable font file. A variable font can have + `axis` child nodes for specifying axis values. A variable font can have all attribute of + static font and can have additional `supportedAxes` attribute. A `supportedAxes` attribute + is a comma separated supported axis tags. As of Android V, only `wght` and `ital` axes can + be specified. + + If `supportedAxes` attribute is not specified, this `font` node works as static font of the + single instance of variable font specified with `axis` children. + + If `supportedAxes` attribute is specified, the system dynamically create font instance for the + given weight and style value. If `wght` is specified in `supportedAxes` attribute the `weight` + attribute and `axis` child that has `wght` tag become optional and ignored because it is + determined by system at runtime. Similarly, if `ital` is specified in `supportedAxes` + attribute, the `style` attribute and `axis` child that has `ital` tag become optional and + ignored. + + `axis` node: + An `axis` node defines a font variation value for a tag. An `axis` node can have two mandatory + attributes, `tag` and `value`. If the font is variable font and the same tag `axis` node is + specified in `supportedAxes` attribute, the style value works like a default instance. --> -<familyset version="23"> +<familyset> <!-- first font is default --> - <family name="sans-serif" varFamilyType="2"> - <font>Roboto-Regular.ttf + <family name="sans-serif"> + <font supportedAxes="wght,ital">Roboto-Regular.ttf <axis tag="wdth" stylevalue="100" /> </font> </family> @@ -32,8 +104,8 @@ <alias name="tahoma" to="sans-serif" /> <alias name="verdana" to="sans-serif" /> - <family name="sans-serif-condensed" varFamilyType="2"> - <font>Roboto-Regular.ttf + <family name="sans-serif-condensed"> + <font supportedAxes="wght,ital">Roboto-Regular.ttf <axis tag="wdth" stylevalue="75" /> </font> </family> @@ -72,8 +144,8 @@ <font weight="400" style="normal" postScriptName="ComingSoon-Regular">ComingSoon.ttf</font> </family> - <family name="cursive" varFamilyType="1"> - <font>DancingScript-Regular.ttf</font> + <family name="cursive"> + <font supportedAxes="wght">DancingScript-Regular.ttf</font> </family> <family name="sans-serif-smallcaps"> @@ -90,8 +162,8 @@ </family> <alias name="source-sans-pro-semi-bold" to="source-sans-pro" weight="600"/> - <family name="roboto-flex" varFamilyType="2"> - <font>RobotoFlex-Regular.ttf + <family name="roboto-flex"> + <font supportedAxes="wght">RobotoFlex-Regular.ttf <axis tag="wdth" stylevalue="100" /> </font> </family> @@ -109,11 +181,11 @@ </font> <font weight="700" style="normal">NotoNaskhArabicUI-Bold.ttf</font> </family> - <family lang="und-Ethi" varFamilyType="1"> - <font postScriptName="NotoSansEthiopic-Regular"> + <family lang="und-Ethi"> + <font postScriptName="NotoSansEthiopic-Regular" supportedAxes="wght"> NotoSansEthiopic-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifEthiopic-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifEthiopic-Regular" supportedAxes="wght"> NotoSerifEthiopic-VF.ttf </font> </family> @@ -140,32 +212,32 @@ </font> <font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font> </family> - <family lang="und-Armn" varFamilyType="1"> - <font postScriptName="NotoSansArmenian-Regular"> + <family lang="und-Armn"> + <font postScriptName="NotoSansArmenian-Regular" supportedAxes="wght"> NotoSansArmenian-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifArmenian-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifArmenian-Regular" supportedAxes="wght"> NotoSerifArmenian-VF.ttf </font> </family> - <family lang="und-Geor,und-Geok" varFamilyType="1"> - <font postScriptName="NotoSansGeorgian-Regular"> + <family lang="und-Geor,und-Geok"> + <font postScriptName="NotoSansGeorgian-Regular" supportedAxes="wght"> NotoSansGeorgian-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifGeorgian-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifGeorgian-Regular" supportedAxes="wght"> NotoSerifGeorgian-VF.ttf </font> </family> - <family lang="und-Deva" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansDevanagari-Regular"> + <family lang="und-Deva" variant="elegant"> + <font postScriptName="NotoSansDevanagari-Regular" supportedAxes="wght"> NotoSansDevanagari-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifDevanagari-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifDevanagari-Regular" supportedAxes="wght"> NotoSerifDevanagari-VF.ttf </font> </family> - <family lang="und-Deva" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansDevanagariUI-Regular"> + <family lang="und-Deva" variant="compact"> + <font postScriptName="NotoSansDevanagariUI-Regular" supportedAxes="wght"> NotoSansDevanagariUI-VF.ttf </font> </family> @@ -178,21 +250,9 @@ NotoSansGujarati-Regular.ttf </font> <font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font> - <font weight="400" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="400"/> - </font> - <font weight="500" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="500"/> - </font> - <font weight="600" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="600"/> - </font> - <font weight="700" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="700"/> + <font style="normal" fallbackFor="serif" postScriptName="NotoSerifGujarati-Regular" + supportedAxes="wght"> + NotoSerifGujarati-VF.ttf </font> </family> <family lang="und-Gujr" variant="compact"> @@ -201,81 +261,81 @@ </font> <font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font> </family> - <family lang="und-Guru" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansGurmukhi-Regular"> + <family lang="und-Guru" variant="elegant"> + <font postScriptName="NotoSansGurmukhi-Regular" supportedAxes="wght"> NotoSansGurmukhi-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifGurmukhi-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifGurmukhi-Regular" supportedAxes="wght"> NotoSerifGurmukhi-VF.ttf </font> </family> - <family lang="und-Guru" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansGurmukhiUI-Regular"> + <family lang="und-Guru" variant="compact"> + <font postScriptName="NotoSansGurmukhiUI-Regular" supportedAxes="wght"> NotoSansGurmukhiUI-VF.ttf </font> </family> - <family lang="und-Taml" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansTamil-Regular"> + <family lang="und-Taml" variant="elegant"> + <font postScriptName="NotoSansTamil-Regular" supportedAxes="wght"> NotoSansTamil-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifTamil-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifTamil-Regular" supportedAxes="wght"> NotoSerifTamil-VF.ttf </font> </family> - <family lang="und-Taml" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansTamilUI-Regular"> + <family lang="und-Taml" variant="compact"> + <font postScriptName="NotoSansTamilUI-Regular" supportedAxes="wght"> NotoSansTamilUI-VF.ttf </font> </family> - <family lang="und-Mlym" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansMalayalam-Regular"> + <family lang="und-Mlym" variant="elegant"> + <font postScriptName="NotoSansMalayalam-Regular" supportedAxes="wght"> NotoSansMalayalam-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifMalayalam-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifMalayalam-Regular" supportedAxes="wght"> NotoSerifMalayalam-VF.ttf </font> </family> - <family lang="und-Mlym" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansMalayalamUI-Regular"> + <family lang="und-Mlym" variant="compact"> + <font postScriptName="NotoSansMalayalamUI-Regular" supportedAxes="wght"> NotoSansMalayalamUI-VF.ttf </font> </family> - <family lang="und-Beng" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansBengali-Regular"> + <family lang="und-Beng" variant="elegant"> + <font postScriptName="NotoSansBengali-Regular" supportedAxes="wght"> NotoSansBengali-VF.ttf </font> <font fallbackFor="serif" postScriptName="NotoSerifBengali-Regular"> NotoSerifBengali-VF.ttf </font> </family> - <family lang="und-Beng" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansBengaliUI-Regular"> + <family lang="und-Beng" variant="compact"> + <font postScriptName="NotoSansBengaliUI-Regular" supportedAxes="wght"> NotoSansBengaliUI-VF.ttf </font> </family> - <family lang="und-Telu" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansTelugu-Regular"> + <family lang="und-Telu" variant="elegant"> + <font postScriptName="NotoSansTelugu-Regular" supportedAxes="wght"> NotoSansTelugu-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifTelugu-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifTelugu-Regular" supportedAxes="wght"> NotoSerifTelugu-VF.ttf </font> </family> - <family lang="und-Telu" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansTeluguUI-Regular"> + <family lang="und-Telu" variant="compact"> + <font postScriptName="NotoSansTeluguUI-Regular" supportedAxes="wght"> NotoSansTeluguUI-VF.ttf </font> </family> - <family lang="und-Knda" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansKannada-Regular"> + <family lang="und-Knda" variant="elegant"> + <font postScriptName="NotoSansKannada-Regular" supportedAxes="wght"> NotoSansKannada-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifKannada-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifKannada-Regular" supportedAxes="wght"> NotoSerifKannada-VF.ttf </font> </family> - <family lang="und-Knda" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansKannadaUI-Regular"> + <family lang="und-Knda" variant="compact"> + <font postScriptName="NotoSansKannadaUI-Regular" supportedAxes="wght"> NotoSansKannadaUI-VF.ttf </font> </family> @@ -290,19 +350,20 @@ </font> <font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font> </family> - <family lang="und-Sinh" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansSinhala-Regular"> + <family lang="und-Sinh" variant="elegant"> + <font postScriptName="NotoSansSinhala-Regular" supportedAxes="wght"> NotoSansSinhala-VF.ttf </font> <font fallbackFor="serif" postScriptName="NotoSerifSinhala-Regular"> NotoSerifSinhala-VF.ttf </font> </family> - <family lang="und-Sinh" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansSinhalaUI-Regular"> + <family lang="und-Sinh" variant="compact"> + <font postScriptName="NotoSansSinhalaUI-Regular" supportedAxes="wght"> NotoSansSinhalaUI-VF.ttf </font> </family> + <!-- TODO: NotoSansKhmer uses non-standard wght value, so cannot use auto-adjustment. --> <family lang="und-Khmr" variant="elegant"> <font weight="100" style="normal" postScriptName="NotoSansKhmer-Regular"> NotoSansKhmer-VF.ttf @@ -398,8 +459,8 @@ <family lang="und-Ahom"> <font weight="400" style="normal">NotoSansAhom-Regular.otf</font> </family> - <family lang="und-Adlm" varFamilyType="1"> - <font postScriptName="NotoSansAdlam-Regular"> + <family lang="und-Adlm"> + <font postScriptName="NotoSansAdlam-Regular" supportedAxes="wght"> NotoSansAdlam-VF.ttf </font> </family> @@ -686,8 +747,8 @@ NotoSansTaiViet-Regular.ttf </font> </family> - <family lang="und-Tibt" varFamilyType="1"> - <font postScriptName="NotoSerifTibetan-Regular"> + <family lang="und-Tibt"> + <font postScriptName="NotoSerifTibetan-Regular" supportedAxes="wght"> NotoSerifTibetan-VF.ttf </font> </family> @@ -865,27 +926,27 @@ <family lang="und-Dogr"> <font weight="400" style="normal">NotoSerifDogra-Regular.ttf</font> </family> - <family lang="und-Medf" varFamilyType="1"> - <font postScriptName="NotoSansMedefaidrin-Regular"> + <family lang="und-Medf"> + <font postScriptName="NotoSansMedefaidrin-Regular" supportedAxes="wght"> NotoSansMedefaidrin-VF.ttf </font> </family> - <family lang="und-Soyo" varFamilyType="1"> + <family lang="und-Soyo" supportedAxes="wght"> <font postScriptName="NotoSansSoyombo-Regular"> NotoSansSoyombo-VF.ttf </font> </family> - <family lang="und-Takr" varFamilyType="1"> + <family lang="und-Takr" supportedAxes="wght"> <font postScriptName="NotoSansTakri-Regular"> NotoSansTakri-VF.ttf </font> </family> - <family lang="und-Hmnp" varFamilyType="1"> + <family lang="und-Hmnp" supportedAxes="wght"> <font postScriptName="NotoSerifHmongNyiakeng-Regular"> NotoSerifNyiakengPuachueHmong-VF.ttf </font> </family> - <family lang="und-Yezi" varFamilyType="1"> + <family lang="und-Yezi" supportedAxes="wght"> <font postScriptName="NotoSerifYezidi-Regular"> NotoSerifYezidi-VF.ttf </font> diff --git a/data/fonts/font_fallback_cjkvf.xml b/data/fonts/font_fallback_cjkvf.xml index 75bc74ebb553..c1ca67ef456a 100644 --- a/data/fonts/font_fallback_cjkvf.xml +++ b/data/fonts/font_fallback_cjkvf.xml @@ -11,12 +11,84 @@ effectively add 300 to the weight, this ensures that 900 is the bold paired with the 500 weight, ensuring adequate contrast. - TODO(rsheeter) update comment; ordering to match 800 to 900 is no longer required + + The font_fallback.xml defines the list of font used by the system. + + `familyset` node: + A `familyset` element must be a root node of the font_fallback.xml. No attributes are allowed + to `familyset` node. + The `familyset` node can contains `family` and `alias` nodes. Any other nodes will be ignored. + + `family` node: + A `family` node defines a single font family definition. + A font family is a set of fonts for drawing text in various styles such as weight, slant. + There are three types of families, default family, named family and locale fallback family. + + The default family is a special family node appeared the first node of the `familyset` node. + The default family is used as first priority fallback. + Only `name` attribute can be used for default family node. If the `name` attribute is + specified, This family will also works as named family. + + The named family is a family that has name attribute. The named family defines a new fallback. + For example, if the name attribute is "serif", it creates serif fallback. Developers can + access the fallback by using Typeface#create API. + The named family can not have attribute other than `name` attribute. The `name` attribute + cannot be empty. + + The locale fallback family is a font family that is used for fallback. The fallback family is + used when the named family or default family cannot be used. The locale fallback family can + have `lang` attribute and `variant` attribute. The `lang` attribute is an optional comma + separated BCP-47i language tag. The `variant` is an optional attribute that can be one one + `element`, `compact`. If a `variant` attribute is not specified, it is treated as default. + + `alias` node: + An `alias` node defines a alias of named family with changing weight offset. An `alias` node + can have mandatory `name` and `to` attribute and optional `weight` attribute. This `alias` + defines new fallback that has the name of specified `name` attribute. The fallback list is + the same to the fallback that of the name specified with `to` attribute. If `weight` attribute + is specified, the base weight offset is shifted to the specified value. For example, if the + `weight` is 500, the output text is drawn with 500 of weight. + + `font` node: + A `font` node defines a single font definition. There are two types of fonts, static font and + variable font. + + A static font can have `weight`, `style`, `index` and `postScriptName` attributes. A `weight` + is a mandatory attribute that defines the weight of the font. Any number between 0 to 1000 is + valid. A `style` is a mandatory attribute that defines the style of the font. A 'style' + attribute can be `normal` or `italic`. An `index` is an optional attribute that defines the + index of the font collection. If this is not specified, it is treated as 0. If the font file + is not a font collection, this attribute is ignored. A `postScriptName` attribute is an + optional attribute. A PostScript name is used for identifying target of system font update. + If this is not specified, the system assumes the filename is same to PostScript name of the + font file. For example, if the font file is "Roboto-Regular.ttf", the system assume the + PostScript name of this font is "Roboto-Regular". + + A variable font can be only defined for the variable font file. A variable font can have + `axis` child nodes for specifying axis values. A variable font can have all attribute of + static font and can have additional `supportedAxes` attribute. A `supportedAxes` attribute + is a comma separated supported axis tags. As of Android V, only `wght` and `ital` axes can + be specified. + + If `supportedAxes` attribute is not specified, this `font` node works as static font of the + single instance of variable font specified with `axis` children. + + If `supportedAxes` attribute is specified, the system dynamically create font instance for the + given weight and style value. If `wght` is specified in `supportedAxes` attribute the `weight` + attribute and `axis` child that has `wght` tag become optional and ignored because it is + determined by system at runtime. Similarly, if `ital` is specified in `supportedAxes` + attribute, the `style` attribute and `axis` child that has `ital` tag become optional and + ignored. + + `axis` node: + An `axis` node defines a font variation value for a tag. An `axis` node can have two mandatory + attributes, `tag` and `value`. If the font is variable font and the same tag `axis` node is + specified in `supportedAxes` attribute, the style value works like a default instance. --> -<familyset version="23"> +<familyset> <!-- first font is default --> - <family name="sans-serif" varFamilyType="2"> - <font>Roboto-Regular.ttf + <family name="sans-serif"> + <font supportedAxes="wght,ital">Roboto-Regular.ttf <axis tag="wdth" stylevalue="100" /> </font> </family> @@ -32,8 +104,8 @@ <alias name="tahoma" to="sans-serif" /> <alias name="verdana" to="sans-serif" /> - <family name="sans-serif-condensed" varFamilyType="2"> - <font>Roboto-Regular.ttf + <family name="sans-serif-condensed"> + <font supportedAxes="wght,ital">Roboto-Regular.ttf <axis tag="wdth" stylevalue="75" /> </font> </family> @@ -72,8 +144,8 @@ <font weight="400" style="normal" postScriptName="ComingSoon-Regular">ComingSoon.ttf</font> </family> - <family name="cursive" varFamilyType="1"> - <font>DancingScript-Regular.ttf</font> + <family name="cursive"> + <font supportedAxes="wght">DancingScript-Regular.ttf</font> </family> <family name="sans-serif-smallcaps"> @@ -90,8 +162,8 @@ </family> <alias name="source-sans-pro-semi-bold" to="source-sans-pro" weight="600"/> - <family name="roboto-flex" varFamilyType="2"> - <font>RobotoFlex-Regular.ttf + <family name="roboto-flex"> + <font supportedAxes="wght">RobotoFlex-Regular.ttf <axis tag="wdth" stylevalue="100" /> </font> </family> @@ -109,11 +181,11 @@ </font> <font weight="700" style="normal">NotoNaskhArabicUI-Bold.ttf</font> </family> - <family lang="und-Ethi" varFamilyType="1"> - <font postScriptName="NotoSansEthiopic-Regular"> + <family lang="und-Ethi"> + <font postScriptName="NotoSansEthiopic-Regular" supportedAxes="wght"> NotoSansEthiopic-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifEthiopic-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifEthiopic-Regular" supportedAxes="wght"> NotoSerifEthiopic-VF.ttf </font> </family> @@ -140,32 +212,32 @@ </font> <font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font> </family> - <family lang="und-Armn" varFamilyType="1"> - <font postScriptName="NotoSansArmenian-Regular"> + <family lang="und-Armn"> + <font postScriptName="NotoSansArmenian-Regular" supportedAxes="wght"> NotoSansArmenian-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifArmenian-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifArmenian-Regular" supportedAxes="wght"> NotoSerifArmenian-VF.ttf </font> </family> - <family lang="und-Geor,und-Geok" varFamilyType="1"> - <font postScriptName="NotoSansGeorgian-Regular"> + <family lang="und-Geor,und-Geok"> + <font postScriptName="NotoSansGeorgian-Regular" supportedAxes="wght"> NotoSansGeorgian-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifGeorgian-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifGeorgian-Regular" supportedAxes="wght"> NotoSerifGeorgian-VF.ttf </font> </family> - <family lang="und-Deva" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansDevanagari-Regular"> + <family lang="und-Deva" variant="elegant"> + <font postScriptName="NotoSansDevanagari-Regular" supportedAxes="wght"> NotoSansDevanagari-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifDevanagari-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifDevanagari-Regular" supportedAxes="wght"> NotoSerifDevanagari-VF.ttf </font> </family> - <family lang="und-Deva" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansDevanagariUI-Regular"> + <family lang="und-Deva" variant="compact"> + <font postScriptName="NotoSansDevanagariUI-Regular" supportedAxes="wght"> NotoSansDevanagariUI-VF.ttf </font> </family> @@ -178,21 +250,9 @@ NotoSansGujarati-Regular.ttf </font> <font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font> - <font weight="400" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="400"/> - </font> - <font weight="500" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="500"/> - </font> - <font weight="600" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="600"/> - </font> - <font weight="700" style="normal" fallbackFor="serif" - postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf - <axis tag="wght" stylevalue="700"/> + <font style="normal" fallbackFor="serif" postScriptName="NotoSerifGujarati-Regular" + supportedAxes="wght"> + NotoSerifGujarati-VF.ttf </font> </family> <family lang="und-Gujr" variant="compact"> @@ -201,81 +261,81 @@ </font> <font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font> </family> - <family lang="und-Guru" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansGurmukhi-Regular"> + <family lang="und-Guru" variant="elegant"> + <font postScriptName="NotoSansGurmukhi-Regular" supportedAxes="wght"> NotoSansGurmukhi-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifGurmukhi-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifGurmukhi-Regular" supportedAxes="wght"> NotoSerifGurmukhi-VF.ttf </font> </family> - <family lang="und-Guru" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansGurmukhiUI-Regular"> + <family lang="und-Guru" variant="compact"> + <font postScriptName="NotoSansGurmukhiUI-Regular" supportedAxes="wght"> NotoSansGurmukhiUI-VF.ttf </font> </family> - <family lang="und-Taml" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansTamil-Regular"> + <family lang="und-Taml" variant="elegant"> + <font postScriptName="NotoSansTamil-Regular" supportedAxes="wght"> NotoSansTamil-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifTamil-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifTamil-Regular" supportedAxes="wght"> NotoSerifTamil-VF.ttf </font> </family> - <family lang="und-Taml" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansTamilUI-Regular"> + <family lang="und-Taml" variant="compact"> + <font postScriptName="NotoSansTamilUI-Regular" supportedAxes="wght"> NotoSansTamilUI-VF.ttf </font> </family> - <family lang="und-Mlym" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansMalayalam-Regular"> + <family lang="und-Mlym" variant="elegant"> + <font postScriptName="NotoSansMalayalam-Regular" supportedAxes="wght"> NotoSansMalayalam-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifMalayalam-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifMalayalam-Regular" supportedAxes="wght"> NotoSerifMalayalam-VF.ttf </font> </family> - <family lang="und-Mlym" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansMalayalamUI-Regular"> + <family lang="und-Mlym" variant="compact"> + <font postScriptName="NotoSansMalayalamUI-Regular" supportedAxes="wght"> NotoSansMalayalamUI-VF.ttf </font> </family> - <family lang="und-Beng" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansBengali-Regular"> + <family lang="und-Beng" variant="elegant"> + <font postScriptName="NotoSansBengali-Regular" supportedAxes="wght"> NotoSansBengali-VF.ttf </font> <font fallbackFor="serif" postScriptName="NotoSerifBengali-Regular"> NotoSerifBengali-VF.ttf </font> </family> - <family lang="und-Beng" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansBengaliUI-Regular"> + <family lang="und-Beng" variant="compact"> + <font postScriptName="NotoSansBengaliUI-Regular" supportedAxes="wght"> NotoSansBengaliUI-VF.ttf </font> </family> - <family lang="und-Telu" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansTelugu-Regular"> + <family lang="und-Telu" variant="elegant"> + <font postScriptName="NotoSansTelugu-Regular" supportedAxes="wght"> NotoSansTelugu-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifTelugu-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifTelugu-Regular" supportedAxes="wght"> NotoSerifTelugu-VF.ttf </font> </family> - <family lang="und-Telu" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansTeluguUI-Regular"> + <family lang="und-Telu" variant="compact"> + <font postScriptName="NotoSansTeluguUI-Regular" supportedAxes="wght"> NotoSansTeluguUI-VF.ttf </font> </family> - <family lang="und-Knda" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansKannada-Regular"> + <family lang="und-Knda" variant="elegant"> + <font postScriptName="NotoSansKannada-Regular" supportedAxes="wght"> NotoSansKannada-VF.ttf </font> - <font fallbackFor="serif" postScriptName="NotoSerifKannada-Regular"> + <font fallbackFor="serif" postScriptName="NotoSerifKannada-Regular" supportedAxes="wght"> NotoSerifKannada-VF.ttf </font> </family> - <family lang="und-Knda" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansKannadaUI-Regular"> + <family lang="und-Knda" variant="compact"> + <font postScriptName="NotoSansKannadaUI-Regular" supportedAxes="wght"> NotoSansKannadaUI-VF.ttf </font> </family> @@ -290,19 +350,20 @@ </font> <font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font> </family> - <family lang="und-Sinh" variant="elegant" varFamilyType="1"> - <font postScriptName="NotoSansSinhala-Regular"> + <family lang="und-Sinh" variant="elegant"> + <font postScriptName="NotoSansSinhala-Regular" supportedAxes="wght"> NotoSansSinhala-VF.ttf </font> <font fallbackFor="serif" postScriptName="NotoSerifSinhala-Regular"> NotoSerifSinhala-VF.ttf </font> </family> - <family lang="und-Sinh" variant="compact" varFamilyType="1"> - <font postScriptName="NotoSansSinhalaUI-Regular"> + <family lang="und-Sinh" variant="compact"> + <font postScriptName="NotoSansSinhalaUI-Regular" supportedAxes="wght"> NotoSansSinhalaUI-VF.ttf </font> </family> + <!-- TODO: NotoSansKhmer uses non-standard wght value, so cannot use auto-adjustment. --> <family lang="und-Khmr" variant="elegant"> <font weight="100" style="normal" postScriptName="NotoSansKhmer-Regular"> NotoSansKhmer-VF.ttf @@ -398,8 +459,8 @@ <family lang="und-Ahom"> <font weight="400" style="normal">NotoSansAhom-Regular.otf</font> </family> - <family lang="und-Adlm" varFamilyType="1"> - <font postScriptName="NotoSansAdlam-Regular"> + <family lang="und-Adlm"> + <font postScriptName="NotoSansAdlam-Regular" supportedAxes="wght"> NotoSansAdlam-VF.ttf </font> </family> @@ -686,8 +747,8 @@ NotoSansTaiViet-Regular.ttf </font> </family> - <family lang="und-Tibt" varFamilyType="1"> - <font postScriptName="NotoSerifTibetan-Regular"> + <family lang="und-Tibt"> + <font postScriptName="NotoSerifTibetan-Regular" supportedAxes="wght"> NotoSerifTibetan-VF.ttf </font> </family> @@ -707,123 +768,36 @@ <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font> </family> <family lang="zh-Hans"> - <font weight="100" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> + <font weight="400" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin" + supportedAxes="wght"> NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="100"/> - </font> - <font weight="200" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="200"/> - </font> - <font weight="300" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="300"/> - </font> - <font weight="400" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="400"/> - </font> - <font weight="500" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="500"/> - </font> - <font weight="600" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="600"/> - </font> - <font weight="700" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="700"/> - </font> - <font weight="800" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="800"/> - </font> - <font weight="900" style="normal" index="2" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="900"/> + <!-- The default instance of NotoSansCJK-Regular.ttc is wght=100, so specify wght=400 + for making regular style as default. --> + <axis tag="wght" stylevalue="400" /> </font> <font weight="400" style="normal" index="2" fallbackFor="serif" postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc </font> </family> <family lang="zh-Hant,zh-Bopo"> - <font weight="100" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="100"/> - </font> - <font weight="200" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="200"/> - </font> - <font weight="300" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="300"/> - </font> - <font weight="400" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="400"/> - </font> - <font weight="500" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> + <font weight="400" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin" + supportedAxes="wght"> NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="500"/> - </font> - <font weight="600" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="600"/> - </font> - <font weight="700" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="700"/> - </font> - <font weight="800" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="800"/> - </font> - <font weight="900" style="normal" index="3" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="900"/> + <!-- The default instance of NotoSansCJK-Regular.ttc is wght=100, so specify wght=400 + for making regular style as default. --> + <axis tag="wght" stylevalue="400" /> </font> <font weight="400" style="normal" index="3" fallbackFor="serif" postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc </font> </family> <family lang="ja"> - <font weight="100" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> + <font weight="400" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin" + supportedAxes="wght"> NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="100"/> - </font> - <font weight="200" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="200"/> - </font> - <font weight="300" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="300"/> - </font> - <font weight="400" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="400"/> - </font> - <font weight="500" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="500"/> - </font> - <font weight="600" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="600"/> - </font> - <font weight="700" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="700"/> - </font> - <font weight="800" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="800"/> - </font> - <font weight="900" style="normal" index="0" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="900"/> + <!-- The default instance of NotoSansCJK-Regular.ttc is wght=100, so specify wght=400 + for making regular style as default. --> + <axis tag="wght" stylevalue="400" /> </font> <font weight="400" style="normal" index="0" fallbackFor="serif" postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc @@ -840,41 +814,12 @@ </font> </family> <family lang="ko"> - <font weight="100" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="100"/> - </font> - <font weight="200" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="200"/> - </font> - <font weight="300" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="300"/> - </font> - <font weight="400" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="400"/> - </font> - <font weight="500" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="500"/> - </font> - <font weight="600" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="600"/> - </font> - <font weight="700" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="700"/> - </font> - <font weight="800" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> - NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="800"/> - </font> - <font weight="900" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin"> + <font weight="400" style="normal" index="1" postScriptName="NotoSansCJKjp-Thin" + supportedAxes="wght"> NotoSansCJK-Regular.ttc - <axis tag="wght" stylevalue="900"/> + <!-- The default instance of NotoSansCJK-Regular.ttc is wght=100, so specify wght=400 + for making regular style as default. --> + <axis tag="wght" stylevalue="400" /> </font> <font weight="400" style="normal" index="1" fallbackFor="serif" postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc @@ -997,27 +942,27 @@ <family lang="und-Dogr"> <font weight="400" style="normal">NotoSerifDogra-Regular.ttf</font> </family> - <family lang="und-Medf" varFamilyType="1"> - <font postScriptName="NotoSansMedefaidrin-Regular"> + <family lang="und-Medf"> + <font postScriptName="NotoSansMedefaidrin-Regular" supportedAxes="wght"> NotoSansMedefaidrin-VF.ttf </font> </family> - <family lang="und-Soyo" varFamilyType="1"> + <family lang="und-Soyo" supportedAxes="wght"> <font postScriptName="NotoSansSoyombo-Regular"> NotoSansSoyombo-VF.ttf </font> </family> - <family lang="und-Takr" varFamilyType="1"> + <family lang="und-Takr" supportedAxes="wght"> <font postScriptName="NotoSansTakri-Regular"> NotoSansTakri-VF.ttf </font> </family> - <family lang="und-Hmnp" varFamilyType="1"> + <family lang="und-Hmnp" supportedAxes="wght"> <font postScriptName="NotoSerifHmongNyiakeng-Regular"> NotoSerifNyiakengPuachueHmong-VF.ttf </font> </family> - <family lang="und-Yezi" varFamilyType="1"> + <family lang="und-Yezi" supportedAxes="wght"> <font postScriptName="NotoSerifYezidi-Regular"> NotoSerifYezidi-VF.ttf </font> diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index 52b0b95d3e76..17c2dd94cd36 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -16,10 +16,6 @@ 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; @@ -32,7 +28,6 @@ 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; @@ -65,6 +60,7 @@ public class FontListParser { private static final String VARIANT_ELEGANT = "elegant"; // XML constants for Font. + public static final String ATTR_SUPPORTED_AXES = "supportedAxes"; public static final String ATTR_INDEX = "index"; public static final String ATTR_WEIGHT = "weight"; public static final String ATTR_POSTSCRIPT_NAME = "postScriptName"; @@ -78,6 +74,10 @@ public class FontListParser { public static final String ATTR_TAG = "tag"; public static final String ATTR_STYLEVALUE = "stylevalue"; + // The tag string for variable font type resolution. + private static final String TAG_WGHT = "wght"; + private static final String TAG_ITAL = "ital"; + /* Parse fallback list (no names) */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException { @@ -263,7 +263,6 @@ 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; @@ -286,45 +285,12 @@ 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, - varFamilyType); + return new FontConfig.FontFamily(fonts, LocaleList.forLanguageTags(lang), intVariant); } private static void throwIfAttributeExists(String attrName, XmlPullParser parser) { @@ -407,6 +373,7 @@ public class FontListParser { boolean isItalic = STYLE_ITALIC.equals(parser.getAttributeValue(null, ATTR_STYLE)); String fallbackFor = parser.getAttributeValue(null, ATTR_FALLBACK_FOR); String postScriptName = parser.getAttributeValue(null, ATTR_POSTSCRIPT_NAME); + final String supportedAxes = parser.getAttributeValue(null, ATTR_SUPPORTED_AXES); StringBuilder filename = new StringBuilder(); while (keepReading(parser)) { if (parser.getEventType() == XmlPullParser.TEXT) { @@ -422,6 +389,18 @@ public class FontListParser { } String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); + int varTypeAxes = 0; + if (supportedAxes != null) { + for (String tag : supportedAxes.split(",")) { + String strippedTag = tag.strip(); + if (strippedTag.equals(TAG_WGHT)) { + varTypeAxes |= FontConfig.Font.VAR_TYPE_AXES_WGHT; + } else if (strippedTag.equals(TAG_ITAL)) { + varTypeAxes |= FontConfig.Font.VAR_TYPE_AXES_ITAL; + } + } + } + if (postScriptName == null) { // If post script name was not provided, assume the file name is same to PostScript // name. @@ -462,7 +441,8 @@ public class FontListParser { ), index, varSettings, - fallbackFor); + fallbackFor, + varTypeAxes); } private static String findUpdatedFontFile(String psName, diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java index 3ef714ed8bdf..a90961eb6d2e 100644 --- a/graphics/java/android/graphics/fonts/SystemFonts.java +++ b/graphics/java/android/graphics/fonts/SystemFonts.java @@ -100,6 +100,71 @@ public final class SystemFonts { } } + /** @hide */ + @VisibleForTesting + public static @FontFamily.Builder.VariableFontFamilyType int resolveVarFamilyType( + @NonNull FontConfig.FontFamily xmlFamily, + @Nullable String familyName) { + int wghtCount = 0; + int italCount = 0; + int targetFonts = 0; + boolean hasItalicFont = false; + + List<FontConfig.Font> fonts = xmlFamily.getFontList(); + for (int i = 0; i < fonts.size(); ++i) { + FontConfig.Font font = fonts.get(i); + + if (familyName == null) { // for default family + if (font.getFontFamilyName() != null) { + continue; // this font is not for the default family. + } + } else { // for the specific family + if (!familyName.equals(font.getFontFamilyName())) { + continue; // this font is not for given family. + } + } + + final int varTypeAxes = font.getVarTypeAxes(); + if (varTypeAxes == 0) { + // If we see static font, we can immediately return as VAR_TYPE_NONE. + return FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE; + } + + if ((varTypeAxes & FontConfig.Font.VAR_TYPE_AXES_WGHT) != 0) { + wghtCount++; + } + + if ((varTypeAxes & FontConfig.Font.VAR_TYPE_AXES_ITAL) != 0) { + italCount++; + } + + if (font.getStyle().getSlant() == FontStyle.FONT_SLANT_ITALIC) { + hasItalicFont = true; + } + targetFonts++; + } + + if (italCount == 0) { // No ital font. + if (targetFonts == 1 && wghtCount == 1) { + // If there is only single font that has wght, use it for regular style and + // use synthetic bolding for italic. + return FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ONLY; + } else if (targetFonts == 2 && wghtCount == 2 && hasItalicFont) { + // If there are two fonts and italic font is available, use them for regular and + // italic separately. (It is impossible to have two italic fonts. It will end up + // with Typeface creation failure.) + return FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_TWO_FONTS_WGHT; + } + } else if (italCount == 1) { + // If ital font is included, a single font should support both wght and ital. + if (wghtCount == 1 && targetFonts == 1) { + return FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_SINGLE_FONT_WGHT_ITAL; + } + } + // Otherwise, unsupported. + return FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE; + } + private static void pushFamilyToFallback(@NonNull FontConfig.FontFamily xmlFamily, @NonNull ArrayMap<String, NativeFamilyListSet> fallbackMap, @NonNull Map<String, ByteBuffer> cache) { @@ -126,7 +191,7 @@ public final class SystemFonts { } final FontFamily defaultFamily = defaultFonts.isEmpty() ? null : createFontFamily( - defaultFonts, languageTags, variant, xmlFamily.getVariableFontFamilyType(), false, + defaultFonts, languageTags, variant, resolveVarFamilyType(xmlFamily, null), false, cache); // Insert family into fallback map. for (int i = 0; i < fallbackMap.size(); i++) { @@ -145,7 +210,7 @@ public final class SystemFonts { } } else { final FontFamily family = createFontFamily(fallback, languageTags, variant, - xmlFamily.getVariableFontFamilyType(), false, cache); + resolveVarFamilyType(xmlFamily, name), false, cache); if (family != null) { familyListSet.familyList.add(family); } else if (defaultFamily != null) { @@ -217,7 +282,8 @@ public final class SystemFonts { final FontFamily family = createFontFamily( xmlFamily.getFontList(), xmlFamily.getLocaleList().toLanguageTags(), xmlFamily.getVariant(), - xmlFamily.getVariableFontFamilyType(), + resolveVarFamilyType(xmlFamily, + null /* all fonts under named family should be treated as default */), true, // named family is always default bufferCache); if (family == null) { diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java index 0f40ca082663..1715254a7403 100644 --- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java @@ -16,8 +16,6 @@ package com.android.server.graphics.fonts; -import static android.graphics.fonts.FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE; - import static com.android.server.graphics.fonts.FontManagerService.SystemFontException; import android.annotation.NonNull; @@ -580,11 +578,11 @@ final class UpdatableFontDir { return null; } resolvedFonts.add(new FontConfig.Font(info.mFile, null, info.getPostScriptName(), - font.getFontStyle(), font.getIndex(), font.getFontVariationSettings(), null)); + font.getFontStyle(), font.getIndex(), font.getFontVariationSettings(), + null /* family name */, FontConfig.Font.VAR_TYPE_AXES_NONE)); } FontConfig.FontFamily family = new FontConfig.FontFamily(resolvedFonts, - LocaleList.getEmptyLocaleList(), FontConfig.FontFamily.VARIANT_DEFAULT, - VARIABLE_FONT_FAMILY_TYPE_NONE); + LocaleList.getEmptyLocaleList(), FontConfig.FontFamily.VARIANT_DEFAULT); return new FontConfig.NamedFamilyList(Collections.singletonList(family), fontFamily.getName()); } diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java index 3de167e72ba0..dacff4c07759 100644 --- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java +++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.fail; import android.content.Context; import android.graphics.FontListParser; -import android.graphics.fonts.FontFamily; import android.graphics.fonts.FontManager; import android.graphics.fonts.FontStyle; import android.graphics.fonts.FontUpdateRequest; @@ -324,15 +323,16 @@ public final class UpdatableFontDirTest { Function<Map<String, File>, FontConfig> configSupplier = (map) -> { FontConfig.Font fooFont = new FontConfig.Font( new File(mPreinstalledFontDirs.get(0), "foo.ttf"), null, "foo", - new FontStyle(400, FontStyle.FONT_SLANT_UPRIGHT), 0, null, null); + new FontStyle(400, FontStyle.FONT_SLANT_UPRIGHT), 0, null, null, + FontConfig.Font.VAR_TYPE_AXES_NONE); FontConfig.Font barFont = new FontConfig.Font( new File(mPreinstalledFontDirs.get(1), "bar.ttf"), null, "bar", - new FontStyle(400, FontStyle.FONT_SLANT_UPRIGHT), 0, null, null); + new FontStyle(400, FontStyle.FONT_SLANT_UPRIGHT), 0, null, null, + FontConfig.Font.VAR_TYPE_AXES_NONE); FontConfig.FontFamily family = new FontConfig.FontFamily( Arrays.asList(fooFont, barFont), null, - FontConfig.FontFamily.VARIANT_DEFAULT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE); + FontConfig.FontFamily.VARIANT_DEFAULT); return new FontConfig(Collections.emptyList(), Collections.emptyList(), Collections.singletonList(new FontConfig.NamedFamilyList( @@ -492,10 +492,9 @@ public final class UpdatableFontDirTest { mConfigFile, mCurrentTimeSupplier, (map) -> { FontConfig.Font font = new FontConfig.Font( file, null, "bar", new FontStyle(400, FontStyle.FONT_SLANT_UPRIGHT), - 0, null, null); + 0, null, null, FontConfig.Font.VAR_TYPE_AXES_NONE); FontConfig.FontFamily family = new FontConfig.FontFamily( - Collections.singletonList(font), null, FontConfig.FontFamily.VARIANT_DEFAULT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE); + Collections.singletonList(font), null, FontConfig.FontFamily.VARIANT_DEFAULT); return new FontConfig( Collections.emptyList(), Collections.emptyList(), @@ -647,10 +646,9 @@ public final class UpdatableFontDirTest { mConfigFile, mCurrentTimeSupplier, (map) -> { FontConfig.Font font = new FontConfig.Font( file, null, "test", new FontStyle(400, FontStyle.FONT_SLANT_UPRIGHT), 0, null, - null); + null, FontConfig.Font.VAR_TYPE_AXES_NONE); FontConfig.FontFamily family = new FontConfig.FontFamily( - Collections.singletonList(font), null, FontConfig.FontFamily.VARIANT_DEFAULT, - FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE); + Collections.singletonList(font), null, FontConfig.FontFamily.VARIANT_DEFAULT); return new FontConfig(Collections.emptyList(), Collections.emptyList(), Collections.singletonList(new FontConfig.NamedFamilyList( Collections.singletonList(family), "sans-serif")), |