19a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien/* 29a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * Copyright (C) 2014 The Android Open Source Project 39a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * 49a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 59a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * you may not use this file except in compliance with the License. 69a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * You may obtain a copy of the License at 79a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * 89a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * http://www.apache.org/licenses/LICENSE-2.0 99a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * 109a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * Unless required by applicable law or agreed to in writing, software 119a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * distributed under the License is distributed on an "AS IS" BASIS, 129a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * See the License for the specific language governing permissions and 149a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * limitations under the License. 159a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien */ 169a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 179a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienpackage android.graphics; 189a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 199a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport android.util.Xml; 209a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 219a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport org.xmlpull.v1.XmlPullParser; 229a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport org.xmlpull.v1.XmlPullParserException; 239a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 249a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.io.IOException; 259a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.io.InputStream; 269a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.util.ArrayList; 279a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.util.List; 289a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 299a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien/** 309a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * Parser for font config files. 319a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * 329a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * @hide 339a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien */ 349a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienpublic class FontListParser { 359a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 36117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public static class Config { 37117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien Config() { 38117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien families = new ArrayList<Family>(); 39117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien aliases = new ArrayList<Alias>(); 40117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 41117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public List<Family> families; 42117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public List<Alias> aliases; 43117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 44117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien 45117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public static class Font { 46117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien Font(String fontName, int weight, boolean isItalic) { 47117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien this.fontName = fontName; 48117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien this.weight = weight; 49117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien this.isItalic = isItalic; 50117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 51117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public String fontName; 52117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public int weight; 53117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public boolean isItalic; 54117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 55117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien 56117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public static class Alias { 57117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public String name; 58117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public String toName; 59117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public int weight; 60117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 61117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien 629a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien public static class Family { 63117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public Family(String name, List<Font> fonts, String lang, String variant) { 64117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien this.name = name; 65117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien this.fonts = fonts; 66f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien this.lang = lang; 67f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien this.variant = variant; 689a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 699a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 70117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public String name; 71117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public List<Font> fonts; 72f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien public String lang; 73f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien public String variant; 749a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 759a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 769a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien /* Parse fallback list (no names) */ 77117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien public static Config parse(InputStream in) throws XmlPullParserException, IOException { 789a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien try { 799a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien XmlPullParser parser = Xml.newPullParser(); 809a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien parser.setInput(in, null); 819a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien parser.nextTag(); 829a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien return readFamilies(parser); 839a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } finally { 849a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien in.close(); 859a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 869a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 879a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 88117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien private static Config readFamilies(XmlPullParser parser) 899a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien throws XmlPullParserException, IOException { 90117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien Config config = new Config(); 919a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien parser.require(XmlPullParser.START_TAG, null, "familyset"); 929a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien while (parser.next() != XmlPullParser.END_TAG) { 939a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien if (parser.getEventType() != XmlPullParser.START_TAG) continue; 949a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien if (parser.getName().equals("family")) { 95117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien config.families.add(readFamily(parser)); 96117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } else if (parser.getName().equals("alias")) { 97117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien config.aliases.add(readAlias(parser)); 989a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } else { 999a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien skip(parser); 1009a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1019a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 102117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien return config; 1039a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1049a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 1059a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien private static Family readFamily(XmlPullParser parser) 1069a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien throws XmlPullParserException, IOException { 107117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien String name = parser.getAttributeValue(null, "name"); 108117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien String lang = parser.getAttributeValue(null, "lang"); 109117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien String variant = parser.getAttributeValue(null, "variant"); 110117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien List<Font> fonts = new ArrayList<Font>(); 1119a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien while (parser.next() != XmlPullParser.END_TAG) { 1129a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien if (parser.getEventType() != XmlPullParser.START_TAG) continue; 1139a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien String tag = parser.getName(); 114117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien if (tag.equals("font")) { 115117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien String weightStr = parser.getAttributeValue(null, "weight"); 116117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien int weight = weightStr == null ? 400 : Integer.parseInt(weightStr); 117117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style")); 118117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien String filename = parser.nextText(); 119117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien String fullFilename = "/system/fonts/" + filename; 120117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien fonts.add(new Font(fullFilename, weight, isItalic)); 121117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } else { 122117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien skip(parser); 1239a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1249a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 125117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien return new Family(name, fonts, lang, variant); 126117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 127117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien 128117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien private static Alias readAlias(XmlPullParser parser) 129117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien throws XmlPullParserException, IOException { 130117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien Alias alias = new Alias(); 131117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien alias.name = parser.getAttributeValue(null, "name"); 132117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien alias.toName = parser.getAttributeValue(null, "to"); 133117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien String weightStr = parser.getAttributeValue(null, "weight"); 134117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien if (weightStr == null) { 135117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien alias.weight = 400; 136117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } else { 137117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien alias.weight = Integer.parseInt(weightStr); 138117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 139117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien skip(parser); // alias tag is empty, ignore any contents and consume end tag 140117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien return alias; 1419a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1429a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 1439a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException { 1449a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien int depth = 1; 1459a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien while (depth > 0) { 1469a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien switch (parser.next()) { 1479a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien case XmlPullParser.START_TAG: 1489a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien depth++; 1499a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien break; 1509a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien case XmlPullParser.END_TAG: 1519a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien depth--; 1529a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien break; 1539a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1549a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1559a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1569a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien} 157