This reverts commit 0d253e46aa.
The original CL changed Typeface internal methods and broke
TypefaceCompatApi26Impl in support library which uses reflections.
Ideally, TypefaceCompatApi26Impl must fall back to public API
implementation but due to lack of method availability check, it ended up
crashing the application.
The original patch didn't change any behaviors in MR1, so reverting
that change is the best solution for MR1.
Bug: 64033594
Change-Id: Ie86afeb1b809e57915d62c1db5a70c8d210d2354
Test: N/A
169 lines
6.5 KiB
Java
169 lines
6.5 KiB
Java
/*
|
|
* Copyright (C) 2014 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 android.text.FontConfig;
|
|
import android.graphics.fonts.FontVariationAxis;
|
|
import android.util.Xml;
|
|
|
|
import org.xmlpull.v1.XmlPullParser;
|
|
import org.xmlpull.v1.XmlPullParserException;
|
|
|
|
import android.annotation.Nullable;
|
|
import com.android.internal.annotations.VisibleForTesting;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.regex.Pattern;
|
|
|
|
/**
|
|
* Parser for font config files.
|
|
*
|
|
* @hide
|
|
*/
|
|
public class FontListParser {
|
|
|
|
/* Parse fallback list (no names) */
|
|
public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
|
|
try {
|
|
XmlPullParser parser = Xml.newPullParser();
|
|
parser.setInput(in, null);
|
|
parser.nextTag();
|
|
return readFamilies(parser);
|
|
} finally {
|
|
in.close();
|
|
}
|
|
}
|
|
|
|
private static FontConfig readFamilies(XmlPullParser parser)
|
|
throws XmlPullParserException, IOException {
|
|
List<FontConfig.Family> families = new ArrayList<>();
|
|
List<FontConfig.Alias> aliases = new ArrayList<>();
|
|
|
|
parser.require(XmlPullParser.START_TAG, null, "familyset");
|
|
while (parser.next() != XmlPullParser.END_TAG) {
|
|
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
|
|
String tag = parser.getName();
|
|
if (tag.equals("family")) {
|
|
families.add(readFamily(parser));
|
|
} else if (tag.equals("alias")) {
|
|
aliases.add(readAlias(parser));
|
|
} else {
|
|
skip(parser);
|
|
}
|
|
}
|
|
return new FontConfig(families.toArray(new FontConfig.Family[families.size()]),
|
|
aliases.toArray(new FontConfig.Alias[aliases.size()]));
|
|
}
|
|
|
|
private static FontConfig.Family readFamily(XmlPullParser parser)
|
|
throws XmlPullParserException, IOException {
|
|
String name = parser.getAttributeValue(null, "name");
|
|
String lang = parser.getAttributeValue(null, "lang");
|
|
String variant = parser.getAttributeValue(null, "variant");
|
|
List<FontConfig.Font> fonts = new ArrayList<FontConfig.Font>();
|
|
while (parser.next() != XmlPullParser.END_TAG) {
|
|
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
|
|
String tag = parser.getName();
|
|
if (tag.equals("font")) {
|
|
fonts.add(readFont(parser));
|
|
} else {
|
|
skip(parser);
|
|
}
|
|
}
|
|
int intVariant = FontConfig.Family.VARIANT_DEFAULT;
|
|
if (variant != null) {
|
|
if (variant.equals("compact")) {
|
|
intVariant = FontConfig.Family.VARIANT_COMPACT;
|
|
} else if (variant.equals("elegant")) {
|
|
intVariant = FontConfig.Family.VARIANT_ELEGANT;
|
|
}
|
|
}
|
|
return new FontConfig.Family(name, fonts.toArray(new FontConfig.Font[fonts.size()]), lang,
|
|
intVariant);
|
|
}
|
|
|
|
/** Matches leading and trailing XML whitespace. */
|
|
private static final Pattern FILENAME_WHITESPACE_PATTERN =
|
|
Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
|
|
|
|
private static FontConfig.Font readFont(XmlPullParser parser)
|
|
throws XmlPullParserException, IOException {
|
|
String indexStr = parser.getAttributeValue(null, "index");
|
|
int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
|
|
List<FontVariationAxis> axes = new ArrayList<FontVariationAxis>();
|
|
String weightStr = parser.getAttributeValue(null, "weight");
|
|
int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
|
|
boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
|
|
StringBuilder filename = new StringBuilder();
|
|
while (parser.next() != XmlPullParser.END_TAG) {
|
|
if (parser.getEventType() == XmlPullParser.TEXT) {
|
|
filename.append(parser.getText());
|
|
}
|
|
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
|
|
String tag = parser.getName();
|
|
if (tag.equals("axis")) {
|
|
axes.add(readAxis(parser));
|
|
} else {
|
|
skip(parser);
|
|
}
|
|
}
|
|
String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
|
|
return new FontConfig.Font(sanitizedName, index,
|
|
axes.toArray(new FontVariationAxis[axes.size()]), weight, isItalic);
|
|
}
|
|
|
|
private static FontVariationAxis readAxis(XmlPullParser parser)
|
|
throws XmlPullParserException, IOException {
|
|
String tagStr = parser.getAttributeValue(null, "tag");
|
|
String styleValueStr = parser.getAttributeValue(null, "stylevalue");
|
|
skip(parser); // axis tag is empty, ignore any contents and consume end tag
|
|
return new FontVariationAxis(tagStr, Float.parseFloat(styleValueStr));
|
|
}
|
|
|
|
private static FontConfig.Alias readAlias(XmlPullParser parser)
|
|
throws XmlPullParserException, IOException {
|
|
String name = parser.getAttributeValue(null, "name");
|
|
String toName = parser.getAttributeValue(null, "to");
|
|
String weightStr = parser.getAttributeValue(null, "weight");
|
|
int weight;
|
|
if (weightStr == null) {
|
|
weight = 400;
|
|
} else {
|
|
weight = Integer.parseInt(weightStr);
|
|
}
|
|
skip(parser); // alias tag is empty, ignore any contents and consume end tag
|
|
return new FontConfig.Alias(name, toName, weight);
|
|
}
|
|
|
|
private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
|
|
int depth = 1;
|
|
while (depth > 0) {
|
|
switch (parser.next()) {
|
|
case XmlPullParser.START_TAG:
|
|
depth++;
|
|
break;
|
|
case XmlPullParser.END_TAG:
|
|
depth--;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|