Merge "Add FontListParser#writeFamily()." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5d2f4fc3b3
@@ -36,6 +36,7 @@ import java.io.File;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,6 +156,32 @@ public final class FontConfig implements Parcelable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
FontConfig that = (FontConfig) o;
|
||||||
|
return mLastModifiedTimeMillis == that.mLastModifiedTimeMillis
|
||||||
|
&& mConfigVersion == that.mConfigVersion
|
||||||
|
&& Objects.equals(mFamilies, that.mFamilies)
|
||||||
|
&& Objects.equals(mAliases, that.mAliases);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mFamilies, mAliases, mLastModifiedTimeMillis, mConfigVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FontConfig{"
|
||||||
|
+ "mFamilies=" + mFamilies
|
||||||
|
+ ", mAliases=" + mAliases
|
||||||
|
+ ", mLastModifiedTimeMillis=" + mLastModifiedTimeMillis
|
||||||
|
+ ", mConfigVersion=" + mConfigVersion
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents single font entry in system font configuration.
|
* Represents single font entry in system font configuration.
|
||||||
*
|
*
|
||||||
@@ -317,6 +344,37 @@ public final class FontConfig implements Parcelable {
|
|||||||
public boolean isItalic() {
|
public boolean isItalic() {
|
||||||
return getStyle().getSlant() == FontStyle.FONT_SLANT_ITALIC;
|
return getStyle().getSlant() == FontStyle.FONT_SLANT_ITALIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Font font = (Font) o;
|
||||||
|
return mIndex == font.mIndex
|
||||||
|
&& Objects.equals(mFile, font.mFile)
|
||||||
|
&& Objects.equals(mOriginalFile, font.mOriginalFile)
|
||||||
|
&& Objects.equals(mStyle, font.mStyle)
|
||||||
|
&& Objects.equals(mFontVariationSettings, font.mFontVariationSettings)
|
||||||
|
&& Objects.equals(mFontFamilyName, font.mFontFamilyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mFile, mOriginalFile, mStyle, mIndex, mFontVariationSettings,
|
||||||
|
mFontFamilyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Font{"
|
||||||
|
+ "mFile=" + mFile
|
||||||
|
+ ", mOriginalFile=" + mOriginalFile
|
||||||
|
+ ", mStyle=" + mStyle
|
||||||
|
+ ", mIndex=" + mIndex
|
||||||
|
+ ", mFontVariationSettings='" + mFontVariationSettings + '\''
|
||||||
|
+ ", mFontFamilyName='" + mFontFamilyName + '\''
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -398,6 +456,30 @@ public final class FontConfig implements Parcelable {
|
|||||||
return new Alias[size];
|
return new Alias[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Alias alias = (Alias) o;
|
||||||
|
return mWeight == alias.mWeight
|
||||||
|
&& Objects.equals(mName, alias.mName)
|
||||||
|
&& Objects.equals(mOriginal, alias.mOriginal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mName, mOriginal, mWeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Alias{"
|
||||||
|
+ "mName='" + mName + '\''
|
||||||
|
+ ", mOriginal='" + mOriginal + '\''
|
||||||
|
+ ", mWeight=" + mWeight
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -413,7 +495,7 @@ public final class FontConfig implements Parcelable {
|
|||||||
public static final class FontFamily implements Parcelable {
|
public static final class FontFamily implements Parcelable {
|
||||||
private final @NonNull List<Font> mFonts;
|
private final @NonNull List<Font> mFonts;
|
||||||
private final @Nullable String mName;
|
private final @Nullable String mName;
|
||||||
private final @Nullable LocaleList mLocaleList;
|
private final @NonNull LocaleList mLocaleList;
|
||||||
private final @Variant int mVariant;
|
private final @Variant int mVariant;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -454,7 +536,7 @@ public final class FontConfig implements Parcelable {
|
|||||||
* @hide Only system server can create this instance and passed via IPC.
|
* @hide Only system server can create this instance and passed via IPC.
|
||||||
*/
|
*/
|
||||||
public FontFamily(@NonNull List<Font> fonts, @Nullable String name,
|
public FontFamily(@NonNull List<Font> fonts, @Nullable String name,
|
||||||
@Nullable LocaleList localeList, @Variant int variant) {
|
@NonNull LocaleList localeList, @Variant int variant) {
|
||||||
mFonts = fonts;
|
mFonts = fonts;
|
||||||
mName = name;
|
mName = name;
|
||||||
mLocaleList = localeList;
|
mLocaleList = localeList;
|
||||||
@@ -493,8 +575,6 @@ public final class FontConfig implements Parcelable {
|
|||||||
*
|
*
|
||||||
* The locale list will be used for deciding which font family should be used in fallback
|
* The locale list will be used for deciding which font family should be used in fallback
|
||||||
* list.
|
* list.
|
||||||
*
|
|
||||||
* @return non-null if a locale list is available. Otherwise null.
|
|
||||||
*/
|
*/
|
||||||
public @NonNull LocaleList getLocaleList() {
|
public @NonNull LocaleList getLocaleList() {
|
||||||
return mLocaleList;
|
return mLocaleList;
|
||||||
@@ -559,5 +639,31 @@ public final class FontConfig implements Parcelable {
|
|||||||
public @NonNull String getLanguages() {
|
public @NonNull String getLanguages() {
|
||||||
return mLocaleList.toLanguageTags();
|
return mLocaleList.toLanguageTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
FontFamily that = (FontFamily) o;
|
||||||
|
return mVariant == that.mVariant
|
||||||
|
&& Objects.equals(mFonts, that.mFonts)
|
||||||
|
&& Objects.equals(mName, that.mName)
|
||||||
|
&& Objects.equals(mLocaleList, that.mLocaleList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mFonts, mName, mLocaleList, mVariant);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FontFamily{"
|
||||||
|
+ "mFonts=" + mFonts
|
||||||
|
+ ", mName='" + mName + '\''
|
||||||
|
+ ", mLocaleList=" + mLocaleList
|
||||||
|
+ ", mVariant=" + mVariant
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,245 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
import static android.graphics.fonts.FontStyle.FONT_SLANT_ITALIC;
|
||||||
|
import static android.graphics.fonts.FontStyle.FONT_SLANT_UPRIGHT;
|
||||||
|
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 com.google.common.truth.Truth.assertThat;
|
||||||
|
import static com.google.common.truth.Truth.assertWithMessage;
|
||||||
|
|
||||||
|
import android.graphics.fonts.FontStyle;
|
||||||
|
import android.os.LocaleList;
|
||||||
|
import android.text.FontConfig;
|
||||||
|
import android.util.TypedXmlSerializer;
|
||||||
|
import android.util.Xml;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public final class FontListParserTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void named() throws Exception {
|
||||||
|
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
|
||||||
|
+ "<family name='sans-serif'>"
|
||||||
|
+ " <font>test.ttf</font>"
|
||||||
|
+ "</family>";
|
||||||
|
FontConfig.FontFamily expected = new FontConfig.FontFamily(
|
||||||
|
Arrays.asList(
|
||||||
|
new FontConfig.Font(new File("test.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", null)),
|
||||||
|
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
|
||||||
|
|
||||||
|
FontConfig.FontFamily family = readFamily(xml);
|
||||||
|
assertThat(family).isEqualTo(expected);
|
||||||
|
|
||||||
|
String serialized = writeFamily(family);
|
||||||
|
assertWithMessage("serialized = " + serialized)
|
||||||
|
.that(readFamily(serialized)).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fallback() throws Exception {
|
||||||
|
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
|
||||||
|
+ "<family lang='en'>"
|
||||||
|
+ " <font>test.ttf</font>"
|
||||||
|
+ " <font fallbackFor='serif'>test.ttf</font>"
|
||||||
|
+ "</family>";
|
||||||
|
FontConfig.FontFamily expected = new FontConfig.FontFamily(
|
||||||
|
Arrays.asList(
|
||||||
|
new FontConfig.Font(new File("test.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", null),
|
||||||
|
new FontConfig.Font(new File("test.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", "serif")),
|
||||||
|
null, LocaleList.forLanguageTags("en"), VARIANT_DEFAULT);
|
||||||
|
|
||||||
|
FontConfig.FontFamily family = readFamily(xml);
|
||||||
|
assertThat(family).isEqualTo(expected);
|
||||||
|
|
||||||
|
String serialized = writeFamily(family);
|
||||||
|
assertWithMessage("serialized = " + serialized)
|
||||||
|
.that(readFamily(serialized)).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compact() throws Exception {
|
||||||
|
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
|
||||||
|
+ "<family lang='en' variant='compact'>"
|
||||||
|
+ " <font>test.ttf</font>"
|
||||||
|
+ "</family>";
|
||||||
|
FontConfig.FontFamily expected = new FontConfig.FontFamily(
|
||||||
|
Arrays.asList(
|
||||||
|
new FontConfig.Font(new File("test.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", null)),
|
||||||
|
null, LocaleList.forLanguageTags("en"), VARIANT_COMPACT);
|
||||||
|
|
||||||
|
FontConfig.FontFamily family = readFamily(xml);
|
||||||
|
assertThat(family).isEqualTo(expected);
|
||||||
|
|
||||||
|
String serialized = writeFamily(family);
|
||||||
|
assertWithMessage("serialized = " + serialized)
|
||||||
|
.that(readFamily(serialized)).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void elegant() throws Exception {
|
||||||
|
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
|
||||||
|
+ "<family lang='en' variant='elegant'>"
|
||||||
|
+ " <font>test.ttf</font>"
|
||||||
|
+ "</family>";
|
||||||
|
FontConfig.FontFamily expected = new FontConfig.FontFamily(
|
||||||
|
Arrays.asList(
|
||||||
|
new FontConfig.Font(new File("test.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", null)),
|
||||||
|
null, LocaleList.forLanguageTags("en"), VARIANT_ELEGANT);
|
||||||
|
|
||||||
|
FontConfig.FontFamily family = readFamily(xml);
|
||||||
|
assertThat(family).isEqualTo(expected);
|
||||||
|
|
||||||
|
String serialized = writeFamily(family);
|
||||||
|
assertWithMessage("serialized = " + serialized)
|
||||||
|
.that(readFamily(serialized)).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void styles() throws Exception {
|
||||||
|
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
|
||||||
|
+ "<family name='sans-serif'>"
|
||||||
|
+ " <font style='normal'>normal.ttf</font>"
|
||||||
|
+ " <font weight='100'>weight.ttf</font>"
|
||||||
|
+ " <font style='italic'>italic.ttf</font>"
|
||||||
|
+ "</family>";
|
||||||
|
FontConfig.FontFamily expected = new FontConfig.FontFamily(
|
||||||
|
Arrays.asList(
|
||||||
|
new FontConfig.Font(new File("normal.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", null),
|
||||||
|
new FontConfig.Font(new File("weight.ttf"), null,
|
||||||
|
new FontStyle(100, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", null),
|
||||||
|
new FontConfig.Font(new File("italic.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC),
|
||||||
|
0, "", null)),
|
||||||
|
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
|
||||||
|
FontConfig.FontFamily family = readFamily(xml);
|
||||||
|
assertThat(family).isEqualTo(expected);
|
||||||
|
|
||||||
|
String serialized = writeFamily(family);
|
||||||
|
assertWithMessage("serialized = " + serialized)
|
||||||
|
.that(readFamily(serialized)).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void variable() throws Exception {
|
||||||
|
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
|
||||||
|
+ "<family name='sans-serif'>"
|
||||||
|
+ " <font>test-VF.ttf"
|
||||||
|
+ " <axis tag='wdth' stylevalue='100' />"
|
||||||
|
+ " <axis tag='wght' stylevalue='200' />"
|
||||||
|
+ " </font>"
|
||||||
|
+ " <font>test-VF.ttf"
|
||||||
|
+ " <axis tag='wdth' stylevalue='400' />"
|
||||||
|
+ " <axis tag='wght' stylevalue='700' />"
|
||||||
|
+ " </font>"
|
||||||
|
+ "</family>";
|
||||||
|
FontConfig.FontFamily expected = new FontConfig.FontFamily(
|
||||||
|
Arrays.asList(
|
||||||
|
new FontConfig.Font(new File("test-VF.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "'wdth' 100.0,'wght' 200.0", null),
|
||||||
|
new FontConfig.Font(new File("test-VF.ttf"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "'wdth' 400.0,'wght' 700.0", null)),
|
||||||
|
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
|
||||||
|
FontConfig.FontFamily family = readFamily(xml);
|
||||||
|
assertThat(family).isEqualTo(expected);
|
||||||
|
|
||||||
|
String serialized = writeFamily(family);
|
||||||
|
assertWithMessage("serialized = " + serialized)
|
||||||
|
.that(readFamily(serialized)).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ttc() throws Exception {
|
||||||
|
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
|
||||||
|
+ "<family name='sans-serif'>"
|
||||||
|
+ " <font index='0'>test.ttc</font>"
|
||||||
|
+ " <font index='1'>test.ttc</font>"
|
||||||
|
+ "</family>";
|
||||||
|
FontConfig.FontFamily expected = new FontConfig.FontFamily(
|
||||||
|
Arrays.asList(
|
||||||
|
new FontConfig.Font(new File("test.ttc"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
0, "", null),
|
||||||
|
new FontConfig.Font(new File("test.ttc"), null,
|
||||||
|
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
|
||||||
|
1, "", null)),
|
||||||
|
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
|
||||||
|
FontConfig.FontFamily family = readFamily(xml);
|
||||||
|
assertThat(family).isEqualTo(expected);
|
||||||
|
|
||||||
|
String serialized = writeFamily(family);
|
||||||
|
assertWithMessage("serialized = " + serialized)
|
||||||
|
.that(readFamily(serialized)).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FontConfig.FontFamily readFamily(String xml)
|
||||||
|
throws IOException, XmlPullParserException {
|
||||||
|
StandardCharsets.UTF_8.name();
|
||||||
|
ByteArrayInputStream buffer = new ByteArrayInputStream(
|
||||||
|
xml.getBytes(StandardCharsets.UTF_8));
|
||||||
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
|
parser.setInput(buffer, "UTF-8");
|
||||||
|
parser.nextTag();
|
||||||
|
return FontListParser.readFamily(parser, "", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String writeFamily(FontConfig.FontFamily family) throws IOException {
|
||||||
|
TypedXmlSerializer out = Xml.newFastSerializer();
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
out.setOutput(buffer, "UTF-8");
|
||||||
|
out.startTag(null, "family");
|
||||||
|
FontListParser.writeFamily(out, family);
|
||||||
|
out.endTag(null, "family");
|
||||||
|
out.endDocument();
|
||||||
|
return buffer.toString("UTF-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,8 @@ import android.graphics.fonts.FontVariationAxis;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.LocaleList;
|
import android.os.LocaleList;
|
||||||
import android.text.FontConfig;
|
import android.text.FontConfig;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.TypedXmlSerializer;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
@@ -45,6 +47,27 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
public class FontListParser {
|
public class FontListParser {
|
||||||
|
|
||||||
|
// XML constants for FontFamily.
|
||||||
|
private static final String ATTR_NAME = "name";
|
||||||
|
private static final String ATTR_LANG = "lang";
|
||||||
|
private static final String ATTR_VARIANT = "variant";
|
||||||
|
private static final String TAG_FONT = "font";
|
||||||
|
private static final String VARIANT_COMPACT = "compact";
|
||||||
|
private static final String VARIANT_ELEGANT = "elegant";
|
||||||
|
|
||||||
|
// XML constants for Font.
|
||||||
|
public static final String ATTR_INDEX = "index";
|
||||||
|
public static final String ATTR_WEIGHT = "weight";
|
||||||
|
public static final String ATTR_STYLE = "style";
|
||||||
|
public static final String ATTR_FALLBACK_FOR = "fallbackFor";
|
||||||
|
public static final String STYLE_ITALIC = "italic";
|
||||||
|
public static final String STYLE_NORMAL = "normal";
|
||||||
|
public static final String TAG_AXIS = "axis";
|
||||||
|
|
||||||
|
// XML constants for FontVariationAxis.
|
||||||
|
public static final String ATTR_TAG = "tag";
|
||||||
|
public static final String ATTR_STYLEVALUE = "stylevalue";
|
||||||
|
|
||||||
/* Parse fallback list (no names) */
|
/* Parse fallback list (no names) */
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||||
public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
|
public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
|
||||||
@@ -148,7 +171,7 @@ public class FontListParser {
|
|||||||
while (parser.next() != XmlPullParser.END_TAG) {
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
|
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
|
||||||
final String tag = parser.getName();
|
final String tag = parser.getName();
|
||||||
if (tag.equals("font")) {
|
if (tag.equals(TAG_FONT)) {
|
||||||
fonts.add(readFont(parser, fontDir, updatableFontMap));
|
fonts.add(readFont(parser, fontDir, updatableFontMap));
|
||||||
} else {
|
} else {
|
||||||
skip(parser);
|
skip(parser);
|
||||||
@@ -156,15 +179,41 @@ public class FontListParser {
|
|||||||
}
|
}
|
||||||
int intVariant = FontConfig.FontFamily.VARIANT_DEFAULT;
|
int intVariant = FontConfig.FontFamily.VARIANT_DEFAULT;
|
||||||
if (variant != null) {
|
if (variant != null) {
|
||||||
if (variant.equals("compact")) {
|
if (variant.equals(VARIANT_COMPACT)) {
|
||||||
intVariant = FontConfig.FontFamily.VARIANT_COMPACT;
|
intVariant = FontConfig.FontFamily.VARIANT_COMPACT;
|
||||||
} else if (variant.equals("elegant")) {
|
} else if (variant.equals(VARIANT_ELEGANT)) {
|
||||||
intVariant = FontConfig.FontFamily.VARIANT_ELEGANT;
|
intVariant = FontConfig.FontFamily.VARIANT_ELEGANT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new FontConfig.FontFamily(fonts, name, LocaleList.forLanguageTags(lang), intVariant);
|
return new FontConfig.FontFamily(fonts, name, LocaleList.forLanguageTags(lang), intVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a family tag representing {@code fontFamily}. The tag should be started by the caller.
|
||||||
|
*/
|
||||||
|
public static void writeFamily(TypedXmlSerializer out, FontConfig.FontFamily fontFamily)
|
||||||
|
throws IOException {
|
||||||
|
if (!TextUtils.isEmpty(fontFamily.getName())) {
|
||||||
|
out.attribute(null, ATTR_NAME, fontFamily.getName());
|
||||||
|
}
|
||||||
|
if (!fontFamily.getLocaleList().isEmpty()) {
|
||||||
|
out.attribute(null, ATTR_LANG, fontFamily.getLocaleList().toLanguageTags());
|
||||||
|
}
|
||||||
|
switch (fontFamily.getVariant()) {
|
||||||
|
case FontConfig.FontFamily.VARIANT_COMPACT:
|
||||||
|
out.attribute(null, ATTR_VARIANT, VARIANT_COMPACT);
|
||||||
|
break;
|
||||||
|
case FontConfig.FontFamily.VARIANT_ELEGANT:
|
||||||
|
out.attribute(null, ATTR_VARIANT, VARIANT_ELEGANT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (FontConfig.Font font : fontFamily.getFontList()) {
|
||||||
|
out.startTag(null, TAG_FONT);
|
||||||
|
writeFont(out, font);
|
||||||
|
out.endTag(null, TAG_FONT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Matches leading and trailing XML whitespace. */
|
/** Matches leading and trailing XML whitespace. */
|
||||||
private static final Pattern FILENAME_WHITESPACE_PATTERN =
|
private static final Pattern FILENAME_WHITESPACE_PATTERN =
|
||||||
Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
|
Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
|
||||||
@@ -175,13 +224,13 @@ public class FontListParser {
|
|||||||
@Nullable Map<String, File> updatableFontMap)
|
@Nullable Map<String, File> updatableFontMap)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
|
|
||||||
String indexStr = parser.getAttributeValue(null, "index");
|
String indexStr = parser.getAttributeValue(null, ATTR_INDEX);
|
||||||
int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
|
int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
|
||||||
List<FontVariationAxis> axes = new ArrayList<>();
|
List<FontVariationAxis> axes = new ArrayList<>();
|
||||||
String weightStr = parser.getAttributeValue(null, "weight");
|
String weightStr = parser.getAttributeValue(null, ATTR_WEIGHT);
|
||||||
int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
|
int weight = weightStr == null ? FontStyle.FONT_WEIGHT_NORMAL : Integer.parseInt(weightStr);
|
||||||
boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
|
boolean isItalic = STYLE_ITALIC.equals(parser.getAttributeValue(null, ATTR_STYLE));
|
||||||
String fallbackFor = parser.getAttributeValue(null, "fallbackFor");
|
String fallbackFor = parser.getAttributeValue(null, ATTR_FALLBACK_FOR);
|
||||||
StringBuilder filename = new StringBuilder();
|
StringBuilder filename = new StringBuilder();
|
||||||
while (parser.next() != XmlPullParser.END_TAG) {
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
if (parser.getEventType() == XmlPullParser.TEXT) {
|
if (parser.getEventType() == XmlPullParser.TEXT) {
|
||||||
@@ -189,7 +238,7 @@ public class FontListParser {
|
|||||||
}
|
}
|
||||||
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
|
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
|
||||||
String tag = parser.getName();
|
String tag = parser.getName();
|
||||||
if (tag.equals("axis")) {
|
if (tag.equals(TAG_AXIS)) {
|
||||||
axes.add(readAxis(parser));
|
axes.add(readAxis(parser));
|
||||||
} else {
|
} else {
|
||||||
skip(parser);
|
skip(parser);
|
||||||
@@ -237,14 +286,48 @@ public class FontListParser {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void writeFont(TypedXmlSerializer out, FontConfig.Font font)
|
||||||
|
throws IOException {
|
||||||
|
if (font.getTtcIndex() != 0) {
|
||||||
|
out.attributeInt(null, ATTR_INDEX, font.getTtcIndex());
|
||||||
|
}
|
||||||
|
if (font.getStyle().getWeight() != FontStyle.FONT_WEIGHT_NORMAL) {
|
||||||
|
out.attributeInt(null, ATTR_WEIGHT, font.getStyle().getWeight());
|
||||||
|
}
|
||||||
|
if (font.getStyle().getSlant() == FontStyle.FONT_SLANT_ITALIC) {
|
||||||
|
out.attribute(null, ATTR_STYLE, STYLE_ITALIC);
|
||||||
|
} else {
|
||||||
|
out.attribute(null, ATTR_STYLE, STYLE_NORMAL);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(font.getFontFamilyName())) {
|
||||||
|
out.attribute(null, ATTR_FALLBACK_FOR, font.getFontFamilyName());
|
||||||
|
}
|
||||||
|
out.text(font.getFile().getName());
|
||||||
|
FontVariationAxis[] axes =
|
||||||
|
FontVariationAxis.fromFontVariationSettings(font.getFontVariationSettings());
|
||||||
|
if (axes != null) {
|
||||||
|
for (FontVariationAxis axis : axes) {
|
||||||
|
out.startTag(null, TAG_AXIS);
|
||||||
|
writeAxis(out, axis);
|
||||||
|
out.endTag(null, TAG_AXIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static FontVariationAxis readAxis(XmlPullParser parser)
|
private static FontVariationAxis readAxis(XmlPullParser parser)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
String tagStr = parser.getAttributeValue(null, "tag");
|
String tagStr = parser.getAttributeValue(null, ATTR_TAG);
|
||||||
String styleValueStr = parser.getAttributeValue(null, "stylevalue");
|
String styleValueStr = parser.getAttributeValue(null, ATTR_STYLEVALUE);
|
||||||
skip(parser); // axis tag is empty, ignore any contents and consume end tag
|
skip(parser); // axis tag is empty, ignore any contents and consume end tag
|
||||||
return new FontVariationAxis(tagStr, Float.parseFloat(styleValueStr));
|
return new FontVariationAxis(tagStr, Float.parseFloat(styleValueStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void writeAxis(TypedXmlSerializer out, FontVariationAxis axis)
|
||||||
|
throws IOException {
|
||||||
|
out.attribute(null, ATTR_TAG, axis.getTag());
|
||||||
|
out.attributeFloat(null, ATTR_STYLEVALUE, axis.getStyleValue());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads alias elements
|
* Reads alias elements
|
||||||
*/
|
*/
|
||||||
@@ -255,7 +338,7 @@ public class FontListParser {
|
|||||||
String weightStr = parser.getAttributeValue(null, "weight");
|
String weightStr = parser.getAttributeValue(null, "weight");
|
||||||
int weight;
|
int weight;
|
||||||
if (weightStr == null) {
|
if (weightStr == null) {
|
||||||
weight = 400;
|
weight = FontStyle.FONT_WEIGHT_NORMAL;
|
||||||
} else {
|
} else {
|
||||||
weight = Integer.parseInt(weightStr);
|
weight = Integer.parseInt(weightStr);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user