summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/graphics/fonts/FontFamilyUpdateRequest.java11
-rw-r--r--core/java/android/graphics/fonts/FontUpdateRequest.java319
2 files changed, 312 insertions, 18 deletions
diff --git a/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java b/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
index 8c7695ad5a5a..fbc951e2f6e6 100644
--- a/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
+++ b/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
@@ -16,6 +16,7 @@
package android.graphics.fonts;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
@@ -213,6 +214,16 @@ public final class FontFamilyUpdateRequest {
public List<FontVariationAxis> getAxes() {
return mAxes;
}
+
+ /**
+ * Returns the index of collection
+ *
+ * TODO(183752879): Make font index configurable and make this SystemApi.
+ * @hide
+ */
+ public @IntRange(from = 0) int getIndex() {
+ return 0;
+ }
}
/**
diff --git a/core/java/android/graphics/fonts/FontUpdateRequest.java b/core/java/android/graphics/fonts/FontUpdateRequest.java
index b79c8f62d492..4dd5a72d446e 100644
--- a/core/java/android/graphics/fonts/FontUpdateRequest.java
+++ b/core/java/android/graphics/fonts/FontUpdateRequest.java
@@ -17,19 +17,24 @@
package android.graphics.fonts;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.LocaleList;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.text.FontConfig;
+import android.util.TypedXmlSerializer;
-import java.io.File;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* Represents a font update request. Currently only font install request is supported.
@@ -47,6 +52,273 @@ public final class FontUpdateRequest implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}
+ /**
+ * Font object used for update.
+ *
+ * Here is an example of Family/Font XML.
+ * <family name="my-sans">
+ * <font name="MySans" weight="400" slant="0" axis="'wght' 400 'ital' 0" index="0" />
+ * <font name="MySans" weight="400" slant="0" axis="'wght' 400 'ital' 1" index="0" />
+ * <font name="MySans" weight="400" slant="0" axis="'wght' 700 'ital' 0" index="0" />
+ * <font name="MySans" weight="400" slant="0" axis="'wght' 700 'ital' 1" index="0" />
+ * </family>
+ *
+ * @see Font#readFromXml(XmlPullParser)
+ * @see Font#writeToXml(TypedXmlSerializer, Font)
+ * @see Family#readFromXml(XmlPullParser)
+ * @see Family#writeFamilyToXml(TypedXmlSerializer, Family)
+ */
+ public static final class Font implements Parcelable {
+ private static final String ATTR_INDEX = "index";
+ private static final String ATTR_WEIGHT = "weight";
+ private static final String ATTR_SLANT = "slant";
+ private static final String ATTR_AXIS = "axis";
+ private static final String ATTR_POSTSCRIPT_NAME = "name";
+
+ private final @NonNull String mPostScriptName;
+ private final @NonNull FontStyle mFontStyle;
+ private final @IntRange(from = 0) int mIndex;
+ private final @NonNull String mFontVariationSettings;
+
+ public Font(@NonNull String postScriptName, @NonNull FontStyle fontStyle,
+ @IntRange(from = 0) int index, @NonNull String fontVariationSettings) {
+ mPostScriptName = postScriptName;
+ mFontStyle = fontStyle;
+ mIndex = index;
+ mFontVariationSettings = fontVariationSettings;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString8(mPostScriptName);
+ dest.writeInt(mFontStyle.getWeight());
+ dest.writeInt(mFontStyle.getSlant());
+ dest.writeInt(mIndex);
+ dest.writeString8(mFontVariationSettings);
+ }
+
+ public static final @NonNull Creator<Font> CREATOR = new Creator<Font>() {
+ @Override
+ public Font createFromParcel(Parcel source) {
+ String fontName = source.readString8();
+ int weight = source.readInt();
+ int slant = source.readInt();
+ int index = source.readInt();
+ String varSettings = source.readString8();
+ return new Font(fontName, new FontStyle(weight, slant), index, varSettings);
+ }
+
+ @Override
+ public Font[] newArray(int size) {
+ return new Font[size];
+ }
+ };
+
+ /**
+ * Write {@link Font} instance to XML file.
+ *
+ * For the XML format, see {@link Font} class comment.
+ *
+ * @param out output XML serializer
+ * @param font a Font instance to be written.
+ */
+ public static void writeToXml(TypedXmlSerializer out, Font font) throws IOException {
+ out.attribute(null, ATTR_POSTSCRIPT_NAME, font.getPostScriptName());
+ out.attributeInt(null, ATTR_INDEX, font.getIndex());
+ out.attributeInt(null, ATTR_WEIGHT, font.getFontStyle().getWeight());
+ out.attributeInt(null, ATTR_SLANT, font.getFontStyle().getSlant());
+ out.attribute(null, ATTR_AXIS, font.getFontVariationSettings());
+ }
+
+ /**
+ * Read {@link Font} instance from &lt;font&gt; element in XML
+ *
+ * For the XML format, see {@link Font} class comment.
+ *
+ * @param parser a parser that point &lt;font&gt; element.
+ * @return a font instance
+ * @throws IOException if font element is invalid.
+ */
+ public static Font readFromXml(XmlPullParser parser) throws IOException {
+ String psName = parser.getAttributeValue(null, ATTR_POSTSCRIPT_NAME);
+ if (psName == null) {
+ throw new IOException("name attribute is missing font tag.");
+ }
+ int index = getAttributeValueInt(parser, ATTR_INDEX, 0);
+ int weight = getAttributeValueInt(parser, ATTR_WEIGHT, FontStyle.FONT_WEIGHT_NORMAL);
+ int slant = getAttributeValueInt(parser, ATTR_SLANT, FontStyle.FONT_SLANT_UPRIGHT);
+ String varSettings = parser.getAttributeValue(null, ATTR_AXIS);
+ if (varSettings == null) {
+ varSettings = "";
+ }
+ return new Font(psName, new FontStyle(weight, slant), index, varSettings);
+ }
+
+ public @NonNull String getPostScriptName() {
+ return mPostScriptName;
+ }
+
+ public @NonNull FontStyle getFontStyle() {
+ return mFontStyle;
+ }
+
+ public @IntRange(from = 0) int getIndex() {
+ return mIndex;
+ }
+
+ public @NonNull String getFontVariationSettings() {
+ return mFontVariationSettings;
+ }
+
+ @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
+ && mPostScriptName.equals(font.mPostScriptName)
+ && mFontStyle.equals(font.mFontStyle)
+ && mFontVariationSettings.equals(font.mFontVariationSettings);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPostScriptName, mFontStyle, mIndex, mFontVariationSettings);
+ }
+
+ @Override
+ public String toString() {
+ return "Font{"
+ + "mPostScriptName='" + mPostScriptName + '\''
+ + ", mFontStyle=" + mFontStyle
+ + ", mIndex=" + mIndex
+ + ", mFontVariationSettings='" + mFontVariationSettings + '\''
+ + '}';
+ }
+ }
+
+ /**
+ * Font Family object used for update request.
+ */
+ public static final class Family implements Parcelable {
+ private static final String TAG_FAMILY = "family";
+ private static final String ATTR_NAME = "name";
+ private static final String TAG_FONT = "font";
+
+ private final @Nullable String mName;
+ private final @NonNull List<Font> mFonts;
+
+ public Family(String name, List<Font> fonts) {
+ mName = name;
+ mFonts = fonts;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString8(mName);
+ dest.writeParcelableList(mFonts, flags);
+ }
+
+ public static final @NonNull Creator<Family> CREATOR = new Creator<Family>() {
+
+ @Override
+ public Family createFromParcel(Parcel source) {
+ String familyName = source.readString8();
+ List<Font> fonts = source.readParcelableList(
+ new ArrayList<>(), Font.class.getClassLoader());
+ return new Family(familyName, fonts);
+ }
+
+ @Override
+ public Family[] newArray(int size) {
+ return new Family[size];
+ }
+ };
+
+ /**
+ * Write {@link Family} instance to XML.
+ *
+ * For the XML format, see {@link Font} class comment.
+ *
+ * @param out an output XML serializer
+ * @param family a {@link Family} instance to be written
+ */
+ public static void writeFamilyToXml(@NonNull TypedXmlSerializer out, @NonNull Family family)
+ throws IOException {
+ out.attribute(null, ATTR_NAME, family.getName());
+ List<Font> fonts = family.getFonts();
+ for (int i = 0; i < fonts.size(); ++i) {
+ Font font = fonts.get(i);
+ out.startTag(null, TAG_FONT);
+ Font.writeToXml(out, font);
+ out.endTag(null, TAG_FONT);
+ }
+ }
+
+ /**
+ * Read a {@link Family} instance from &lt;family&gt; element in XML
+ *
+ * For the XML format, see {@link Font} class comment.
+ *
+ * @param parser an XML parser that points &lt;family&gt; element.
+ * @return an {@link Family} instance
+ */
+ public static @NonNull Family readFromXml(@NonNull XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ List<Font> fonts = new ArrayList<>();
+ if (parser.getEventType() != XmlPullParser.START_TAG
+ || !parser.getName().equals(TAG_FAMILY)) {
+ throw new IOException("Unexpected parser state: must be START_TAG with family");
+ }
+ String name = parser.getAttributeValue(null, ATTR_NAME);
+ int type = 0;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_FONT)) {
+ fonts.add(Font.readFromXml(parser));
+ } else if (type == XmlPullParser.END_TAG && parser.getName().equals(TAG_FAMILY)) {
+ break;
+ }
+ }
+ return new Family(name, fonts);
+ }
+
+ public @NonNull String getName() {
+ return mName;
+ }
+
+ public @NonNull List<Font> getFonts() {
+ return mFonts;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Family family = (Family) o;
+ return mName.equals(family.mName) && mFonts.equals(family.mFonts);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mName, mFonts);
+ }
+
+ @Override
+ public String toString() {
+ return "Family{mName='" + mName + '\'' + ", mFonts=" + mFonts + '}';
+ }
+ }
+
public static final Creator<FontUpdateRequest> CREATOR = new Creator<FontUpdateRequest>() {
@Override
public FontUpdateRequest createFromParcel(Parcel in) {
@@ -68,7 +340,7 @@ public final class FontUpdateRequest implements Parcelable {
private final byte[] mSignature;
// NonNull if mType == TYPE_UPDATE_FONT_FAMILY.
@Nullable
- private final FontConfig.FontFamily mFontFamily;
+ private final Family mFontFamily;
public FontUpdateRequest(@NonNull ParcelFileDescriptor fd, @NonNull byte[] signature) {
mType = TYPE_UPDATE_FONT_FILE;
@@ -77,31 +349,29 @@ public final class FontUpdateRequest implements Parcelable {
mFontFamily = null;
}
- public FontUpdateRequest(@NonNull FontConfig.FontFamily fontFamily) {
+ public FontUpdateRequest(@NonNull Family fontFamily) {
mType = TYPE_UPDATE_FONT_FAMILY;
mFd = null;
mSignature = null;
mFontFamily = fontFamily;
}
- public FontUpdateRequest(@NonNull String postScriptName,
+ public FontUpdateRequest(@NonNull String familyName,
@NonNull List<FontFamilyUpdateRequest.Font> variations) {
- // TODO: Serialize the request directly instead of reusing FontConfig.FontFamily.
- this(createFontFamily(postScriptName, variations));
+ this(createFontFamily(familyName, variations));
}
- private static FontConfig.FontFamily createFontFamily(@NonNull String postScriptName,
+ private static Family createFontFamily(@NonNull String familyName,
@NonNull List<FontFamilyUpdateRequest.Font> fonts) {
- List<FontConfig.Font> configFonts = new ArrayList<>(fonts.size());
+ List<Font> updateFonts = new ArrayList<>(fonts.size());
for (FontFamilyUpdateRequest.Font font : fonts) {
- // TODO: Support .otf.
- configFonts.add(new FontConfig.Font(new File(font.getPostScriptName() + ".ttf"), null,
- font.getStyle(), 0 /* index */,
- FontVariationAxis.toFontVariationSettings(font.getAxes()),
- null /* fontFamilyName */));
- }
- return new FontConfig.FontFamily(configFonts, postScriptName,
- LocaleList.getEmptyLocaleList(), FontConfig.FontFamily.VARIANT_DEFAULT);
+ updateFonts.add(new Font(
+ font.getPostScriptName(),
+ font.getStyle(),
+ font.getIndex(),
+ FontVariationAxis.toFontVariationSettings(font.getAxes())));
+ }
+ return new Family(familyName, updateFonts);
}
protected FontUpdateRequest(Parcel in) {
@@ -126,7 +396,7 @@ public final class FontUpdateRequest implements Parcelable {
}
@Nullable
- public FontConfig.FontFamily getFontFamily() {
+ public Family getFontFamily() {
return mFontFamily;
}
@@ -142,4 +412,17 @@ public final class FontUpdateRequest implements Parcelable {
dest.writeBlob(mSignature);
dest.writeParcelable(mFontFamily, flags);
}
+
+ // Utility functions
+ private static int getAttributeValueInt(XmlPullParser parser, String name, int defaultValue) {
+ try {
+ String value = parser.getAttributeValue(null, name);
+ if (value == null) {
+ return defaultValue;
+ }
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
}