OSDN Git Service

Remove FontVariationAxis.InvalidFormatException.
[android-x86/frameworks-base.git] / graphics / java / android / graphics / FontListParser.java
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
17 package android.graphics;
18
19 import android.text.FontConfig;
20 import android.graphics.fonts.FontVariationAxis;
21 import android.util.Xml;
22
23 import org.xmlpull.v1.XmlPullParser;
24 import org.xmlpull.v1.XmlPullParserException;
25
26 import android.annotation.Nullable;
27 import com.android.internal.annotations.VisibleForTesting;
28
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.regex.Pattern;
34
35 /**
36  * Parser for font config files.
37  *
38  * @hide
39  */
40 public class FontListParser {
41
42     /* Parse fallback list (no names) */
43     public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
44         try {
45             XmlPullParser parser = Xml.newPullParser();
46             parser.setInput(in, null);
47             parser.nextTag();
48             return readFamilies(parser);
49         } finally {
50             in.close();
51         }
52     }
53
54     private static FontConfig readFamilies(XmlPullParser parser)
55             throws XmlPullParserException, IOException {
56         List<FontConfig.Family> families = new ArrayList<>();
57         List<FontConfig.Alias> aliases = new ArrayList<>();
58
59         parser.require(XmlPullParser.START_TAG, null, "familyset");
60         while (parser.next() != XmlPullParser.END_TAG) {
61             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
62             String tag = parser.getName();
63             if (tag.equals("family")) {
64                 families.add(readFamily(parser));
65             } else if (tag.equals("alias")) {
66                 aliases.add(readAlias(parser));
67             } else {
68                 skip(parser);
69             }
70         }
71         return new FontConfig(families.toArray(new FontConfig.Family[families.size()]),
72                 aliases.toArray(new FontConfig.Alias[aliases.size()]));
73     }
74
75     private static FontConfig.Family readFamily(XmlPullParser parser)
76             throws XmlPullParserException, IOException {
77         String name = parser.getAttributeValue(null, "name");
78         String lang = parser.getAttributeValue(null, "lang");
79         String variant = parser.getAttributeValue(null, "variant");
80         List<FontConfig.Font> fonts = new ArrayList<FontConfig.Font>();
81         while (parser.next() != XmlPullParser.END_TAG) {
82             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
83             String tag = parser.getName();
84             if (tag.equals("font")) {
85                 fonts.add(readFont(parser));
86             } else {
87                 skip(parser);
88             }
89         }
90         int intVariant = FontConfig.Family.VARIANT_DEFAULT;
91         if (variant != null) {
92             if (variant.equals("compact")) {
93                 intVariant = FontConfig.Family.VARIANT_COMPACT;
94             } else if (variant.equals("elegant")) {
95                 intVariant = FontConfig.Family.VARIANT_ELEGANT;
96             }
97         }
98         return new FontConfig.Family(name, fonts.toArray(new FontConfig.Font[fonts.size()]), lang,
99                 intVariant);
100     }
101
102     /** Matches leading and trailing XML whitespace. */
103     private static final Pattern FILENAME_WHITESPACE_PATTERN =
104             Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
105
106     private static FontConfig.Font readFont(XmlPullParser parser)
107             throws XmlPullParserException, IOException {
108         String indexStr = parser.getAttributeValue(null, "index");
109         int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
110         List<FontVariationAxis> axes = new ArrayList<FontVariationAxis>();
111         String weightStr = parser.getAttributeValue(null, "weight");
112         int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
113         boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
114         StringBuilder filename = new StringBuilder();
115         while (parser.next() != XmlPullParser.END_TAG) {
116             if (parser.getEventType() == XmlPullParser.TEXT) {
117                 filename.append(parser.getText());
118             }
119             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
120             String tag = parser.getName();
121             if (tag.equals("axis")) {
122                 axes.add(readAxis(parser));
123             } else {
124                 skip(parser);
125             }
126         }
127         String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
128         return new FontConfig.Font(sanitizedName, index,
129                 axes.toArray(new FontVariationAxis[axes.size()]), weight, isItalic);
130     }
131
132     private static FontVariationAxis readAxis(XmlPullParser parser)
133             throws XmlPullParserException, IOException {
134         String tagStr = parser.getAttributeValue(null, "tag");
135         String styleValueStr = parser.getAttributeValue(null, "stylevalue");
136         skip(parser);  // axis tag is empty, ignore any contents and consume end tag
137         return new FontVariationAxis(tagStr, Float.parseFloat(styleValueStr));
138     }
139
140     private static FontConfig.Alias readAlias(XmlPullParser parser)
141             throws XmlPullParserException, IOException {
142         String name = parser.getAttributeValue(null, "name");
143         String toName = parser.getAttributeValue(null, "to");
144         String weightStr = parser.getAttributeValue(null, "weight");
145         int weight;
146         if (weightStr == null) {
147             weight = 400;
148         } else {
149             weight = Integer.parseInt(weightStr);
150         }
151         skip(parser);  // alias tag is empty, ignore any contents and consume end tag
152         return new FontConfig.Alias(name, toName, weight);
153     }
154
155     private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
156         int depth = 1;
157         while (depth > 0) {
158             switch (parser.next()) {
159             case XmlPullParser.START_TAG:
160                 depth++;
161                 break;
162             case XmlPullParser.END_TAG:
163                 depth--;
164                 break;
165             }
166         }
167     }
168 }