blob: 0291d7484dc5faaced28e7a86c40be784ea3a0b3 [file] [log] [blame]
/*
* Copyright (C) 2018 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.fonts;
import android.annotation.NonNull;
import android.graphics.FontListParser;
import android.text.FontConfig;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
/**
* Parser for font customization
*
* @hide
*/
public class FontCustomizationParser {
/**
* Represents a customization XML
*/
public static class Result {
ArrayList<FontConfig.Family> mAdditionalNamedFamilies = new ArrayList<>();
ArrayList<FontConfig.Alias> mAdditionalAliases = new ArrayList<>();
}
/**
* Parses the customization XML
*
* Caller must close the input stream
*/
public static Result parse(@NonNull InputStream in, @NonNull String fontDir)
throws XmlPullParserException, IOException {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, null);
parser.nextTag();
return readFamilies(parser, fontDir);
}
private static void validate(Result result) {
HashSet<String> familyNames = new HashSet<>();
for (int i = 0; i < result.mAdditionalNamedFamilies.size(); ++i) {
final FontConfig.Family family = result.mAdditionalNamedFamilies.get(i);
final String name = family.getName();
if (name == null) {
throw new IllegalArgumentException("new-named-family requires name attribute");
}
if (!familyNames.add(name)) {
throw new IllegalArgumentException(
"new-named-family requires unique name attribute");
}
}
}
private static Result readFamilies(XmlPullParser parser, String fontDir)
throws XmlPullParserException, IOException {
Result out = new Result();
parser.require(XmlPullParser.START_TAG, null, "fonts-modification");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
String tag = parser.getName();
if (tag.equals("family")) {
readFamily(parser, fontDir, out);
} else if (tag.equals("alias")) {
out.mAdditionalAliases.add(FontListParser.readAlias(parser));
} else {
FontListParser.skip(parser);
}
}
validate(out);
return out;
}
private static void readFamily(XmlPullParser parser, String fontDir, Result out)
throws XmlPullParserException, IOException {
final String customizationType = parser.getAttributeValue(null, "customizationType");
if (customizationType == null) {
throw new IllegalArgumentException("customizationType must be specified");
}
if (customizationType.equals("new-named-family")) {
out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir));
} else {
throw new IllegalArgumentException("Unknown customizationType=" + customizationType);
}
}
}