FontListParser.java revision 3fa667e22401bf3ba96957fe31167bf05d164c55
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics;
18
19import android.util.Xml;
20
21import org.xmlpull.v1.XmlPullParser;
22import org.xmlpull.v1.XmlPullParserException;
23
24import java.io.IOException;
25import java.io.InputStream;
26import java.util.ArrayList;
27import java.util.List;
28
29/**
30 * Parser for font config files.
31 *
32 * @hide
33 */
34public class FontListParser {
35
36    public static class Config {
37        Config() {
38            families = new ArrayList<Family>();
39            aliases = new ArrayList<Alias>();
40        }
41        public List<Family> families;
42        public List<Alias> aliases;
43    }
44
45    public static class Font {
46        Font(String fontName, int ttcIndex, int weight, boolean isItalic) {
47            this.fontName = fontName;
48            this.ttcIndex = ttcIndex;
49            this.weight = weight;
50            this.isItalic = isItalic;
51        }
52        public String fontName;
53        public int ttcIndex;
54        public int weight;
55        public boolean isItalic;
56    }
57
58    public static class Alias {
59        public String name;
60        public String toName;
61        public int weight;
62    }
63
64    public static class Family {
65        public Family(String name, List<Font> fonts, String lang, String variant) {
66            this.name = name;
67            this.fonts = fonts;
68            this.lang = lang;
69            this.variant = variant;
70        }
71
72        public String name;
73        public List<Font> fonts;
74        public String lang;
75        public String variant;
76    }
77
78    /* Parse fallback list (no names) */
79    public static Config parse(InputStream in) throws XmlPullParserException, IOException {
80        try {
81            XmlPullParser parser = Xml.newPullParser();
82            parser.setInput(in, null);
83            parser.nextTag();
84            return readFamilies(parser);
85        } finally {
86            in.close();
87        }
88    }
89
90    private static Config readFamilies(XmlPullParser parser)
91            throws XmlPullParserException, IOException {
92        Config config = new Config();
93        parser.require(XmlPullParser.START_TAG, null, "familyset");
94        while (parser.next() != XmlPullParser.END_TAG) {
95            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
96            if (parser.getName().equals("family")) {
97                config.families.add(readFamily(parser));
98            } else if (parser.getName().equals("alias")) {
99                config.aliases.add(readAlias(parser));
100            } else {
101                skip(parser);
102            }
103        }
104        return config;
105    }
106
107    private static Family readFamily(XmlPullParser parser)
108            throws XmlPullParserException, IOException {
109        String name = parser.getAttributeValue(null, "name");
110        String lang = parser.getAttributeValue(null, "lang");
111        String variant = parser.getAttributeValue(null, "variant");
112        List<Font> fonts = new ArrayList<Font>();
113        while (parser.next() != XmlPullParser.END_TAG) {
114            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
115            String tag = parser.getName();
116            if (tag.equals("font")) {
117                int ttcIndex = Integer.parseInt(parser.getAttributeValue("0", "ttcIndex"));
118                String weightStr = parser.getAttributeValue(null, "weight");
119                int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
120                boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
121                String filename = parser.nextText();
122                String fullFilename = "/system/fonts/" + filename;
123                fonts.add(new Font(fullFilename, ttcIndex, weight, isItalic));
124            } else {
125                skip(parser);
126            }
127        }
128        return new Family(name, fonts, lang, variant);
129    }
130
131    private static Alias readAlias(XmlPullParser parser)
132            throws XmlPullParserException, IOException {
133        Alias alias = new Alias();
134        alias.name = parser.getAttributeValue(null, "name");
135        alias.toName = parser.getAttributeValue(null, "to");
136        String weightStr = parser.getAttributeValue(null, "weight");
137        if (weightStr == null) {
138            alias.weight = 400;
139        } else {
140            alias.weight = Integer.parseInt(weightStr);
141        }
142        skip(parser);  // alias tag is empty, ignore any contents and consume end tag
143        return alias;
144    }
145
146    private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
147        int depth = 1;
148        while (depth > 0) {
149            switch (parser.next()) {
150            case XmlPullParser.START_TAG:
151                depth++;
152                break;
153            case XmlPullParser.END_TAG:
154                depth--;
155                break;
156            }
157        }
158    }
159}
160