Loading data/fonts/fonts.xmldeleted 100644 → 0 +0 −48 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2008 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. --> <!-- This is only used by the layoutlib to display layouts in ADT. --> <fonts> <font ttf="DroidSans"> <name>sans-serif</name> <name>arial</name> <name>helvetica</name> <name>tahoma</name> <name>verdana</name> </font> <font ttf="DroidSerif"> <name>serif</name> <name>times</name> <name>times new roman</name> <name>palatino</name> <name>georgia</name> <name>baskerville</name> <name>goudy</name> <name>fantasy</name> <name>cursive</name> <name>ITC Stone Serif</name> </font> <font ttf="DroidSansMono"> <name>monospace</name> <name>courier</name> <name>courier new</name> <name>monaco</name> </font> <fallback ttf="DroidSansFallback" /> <fallback ttf="MTLmr3m" /> </fonts> tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java +1 −11 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.content.res.AssetManager; import java.awt.Font; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading @@ -50,7 +49,6 @@ public final class Typeface_Delegate { // ---- delegate helper data ---- private static final String DEFAULT_FAMILY = "sans-serif"; private static final int[] STYLE_BUFFER = new int[1]; private static FontLoader sFontLoader; private static final List<Typeface_Delegate> sPostInitDelegate = Loading Loading @@ -178,14 +176,6 @@ public final class Typeface_Delegate { } private void init() { STYLE_BUFFER[0] = mStyle; Font font = sFontLoader.getFont(mFamily, STYLE_BUFFER); if (font != null) { List<Font> list = new ArrayList<Font>(); list.add(font); list.addAll(sFontLoader.getFallBackFonts()); mFonts = Collections.unmodifiableList(list); mStyle = STYLE_BUFFER[0]; } mFonts = sFontLoader.getFont(mFamily, mStyle); } } tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java +134 −168 Original line number Diff line number Diff line Loading @@ -23,17 +23,13 @@ import org.xml.sax.helpers.DefaultHandler; import android.graphics.Typeface; import java.awt.Font; import java.awt.FontFormatException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.parsers.ParserConfigurationException; Loading @@ -47,49 +43,53 @@ import javax.xml.parsers.SAXParserFactory; * fonts.xml file located alongside the ttf files. */ public final class FontLoader { private static final String FONTS_DEFINITIONS = "fonts.xml"; private static final String FONTS_SYSTEM = "system_fonts.xml"; private static final String FONTS_VENDOR = "vendor_fonts.xml"; private static final String FONTS_FALLBACK = "fallback_fonts.xml"; private static final String NODE_FONTS = "fonts"; private static final String NODE_FONT = "font"; private static final String NODE_FAMILYSET = "familyset"; private static final String NODE_FAMILY = "family"; private static final String NODE_NAME = "name"; private static final String NODE_FALLBACK = "fallback"; private static final String ATTR_TTF = "ttf"; private static final String FONT_EXT = ".ttf"; private static final String[] FONT_STYLE_DEFAULT = { "", "-Regular" }; private static final String[] FONT_STYLE_BOLD = { "-Bold" }; private static final String[] FONT_STYLE_ITALIC = { "-Italic" }; private static final String[] FONT_STYLE_BOLDITALIC = { "-BoldItalic" }; // list of font style, in the order matching the Typeface Font style private static final String[][] FONT_STYLES = { FONT_STYLE_DEFAULT, FONT_STYLE_BOLD, FONT_STYLE_ITALIC, FONT_STYLE_BOLDITALIC private static final String NODE_FILE = "file"; private static final String FONT_SUFFIX_NONE = ".ttf"; private static final String FONT_SUFFIX_REGULAR = "-Regular.ttf"; private static final String FONT_SUFFIX_BOLD = "-Bold.ttf"; private static final String FONT_SUFFIX_ITALIC = "-Italic.ttf"; private static final String FONT_SUFFIX_BOLDITALIC = "-BoldItalic.ttf"; // This must match the values of Typeface styles so that we can use them for indices in this // array. private static final int[] AWT_STYLES = new int[] { Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC }; private static int[] DERIVE_BOLD_ITALIC = new int[] { Typeface.ITALIC, Typeface.BOLD, Typeface.NORMAL }; private static int[] DERIVE_ITALIC = new int[] { Typeface.NORMAL }; private static int[] DERIVE_BOLD = new int[] { Typeface.NORMAL }; private final Map<String, String> mFamilyToTtf = new HashMap<String, String>(); private final Map<String, Map<Integer, Font>> mTtfToFontMap = new HashMap<String, Map<Integer, Font>>(); private List<Font> mFallBackFonts = null; private static final List<FontInfo> mMainFonts = new ArrayList<FontInfo>(); private static final List<FontInfo> mFallbackFonts = new ArrayList<FontInfo>(); public static FontLoader create(String fontOsLocation) { try { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); parserFactory.setNamespaceAware(true); SAXParser parser = parserFactory.newSAXParser(); File f = new File(fontOsLocation + File.separator + FONTS_DEFINITIONS); // parse the system fonts FontHandler handler = parseFontFile(parserFactory, fontOsLocation, FONTS_SYSTEM); List<FontInfo> systemFonts = handler.getFontList(); FontDefinitionParser definitionParser = new FontDefinitionParser( fontOsLocation + File.separator); parser.parse(new FileInputStream(f), definitionParser); return definitionParser.getFontLoader(); // parse the fallback fonts handler = parseFontFile(parserFactory, fontOsLocation, FONTS_FALLBACK); List<FontInfo> fallbackFonts = handler.getFontList(); return new FontLoader(systemFonts, fallbackFonts); } catch (ParserConfigurationException e) { // return null below } catch (SAXException e) { Loading @@ -103,35 +103,22 @@ public final class FontLoader { return null; } private FontLoader(List<FontInfo> fontList, List<String> fallBackList) { for (FontInfo info : fontList) { for (String family : info.families) { mFamilyToTtf.put(family, info.ttf); } } private static FontHandler parseFontFile(SAXParserFactory parserFactory, String fontOsLocation, String fontFileName) throws ParserConfigurationException, SAXException, IOException, FileNotFoundException { ArrayList<Font> list = new ArrayList<Font>(); for (String path : fallBackList) { File f = new File(path + FONT_EXT); if (f.isFile()) { try { Font font = Font.createFont(Font.TRUETYPE_FONT, f); if (font != null) { list.add(font); } } catch (FontFormatException e) { // skip this font name } catch (IOException e) { // skip this font name } } } SAXParser parser = parserFactory.newSAXParser(); File f = new File(fontOsLocation, fontFileName); mFallBackFonts = Collections.unmodifiableList(list); FontHandler definitionParser = new FontHandler( fontOsLocation + File.separator); parser.parse(new FileInputStream(f), definitionParser); return definitionParser; } public List<Font> getFallBackFonts() { return mFallBackFonts; private FontLoader(List<FontInfo> fontList, List<FontInfo> fallBackList) { mMainFonts.addAll(fontList); mFallbackFonts.addAll(fallBackList); } /** Loading @@ -143,96 +130,32 @@ public final class FontLoader { * the method returns. * @return the font object or null if no match could be found. */ public synchronized Font getFont(String family, int[] style) { if (family == null) { return null; } public synchronized List<Font> getFont(String family, int style) { List<Font> result = new ArrayList<Font>(); // get the ttf name from the family String ttf = mFamilyToTtf.get(family); if (ttf == null) { return null; } // get the font from the ttf Map<Integer, Font> styleMap = mTtfToFontMap.get(ttf); if (styleMap == null) { styleMap = new HashMap<Integer, Font>(); mTtfToFontMap.put(ttf, styleMap); if (family == null) { return result; } Font f = styleMap.get(style[0]); if (f != null) { return f; } // if it doesn't exist, we create it, and we can't, we try with a simpler style switch (style[0]) { case Typeface.NORMAL: f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); // get the font objects from the main list based on family. for (FontInfo info : mMainFonts) { if (info.families.contains(family)) { result.add(info.font[style]); break; case Typeface.BOLD: case Typeface.ITALIC: f = getFont(ttf, FONT_STYLES[style[0]]); if (f == null) { f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); style[0] = Typeface.NORMAL; } break; case Typeface.BOLD_ITALIC: f = getFont(ttf, FONT_STYLES[style[0]]); if (f == null) { f = getFont(ttf, FONT_STYLES[Typeface.BOLD]); if (f != null) { style[0] = Typeface.BOLD; } else { f = getFont(ttf, FONT_STYLES[Typeface.ITALIC]); if (f != null) { style[0] = Typeface.ITALIC; } else { f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); style[0] = Typeface.NORMAL; } } } break; } if (f != null) { styleMap.put(style[0], f); return f; // add all the fallback fonts for (FontInfo info : mFallbackFonts) { result.add(info.font[style]); } return null; } private Font getFont(String ttf, String[] fontFileSuffix) { for (String suffix : fontFileSuffix) { String name = ttf + suffix + FONT_EXT; File f = new File(name); if (f.isFile()) { try { Font font = Font.createFont(Font.TRUETYPE_FONT, f); if (font != null) { return font; } } catch (FontFormatException e) { // skip this font name } catch (IOException e) { // skip this font name } } } return null; return result; } private final static class FontInfo { String ttf; final Font[] font = new Font[4]; // Matches the 4 type-face styles. final Set<String> families; FontInfo() { Loading @@ -240,21 +163,20 @@ public final class FontLoader { } } private final static class FontDefinitionParser extends DefaultHandler { private final static class FontHandler extends DefaultHandler { private final String mOsFontsLocation; private FontInfo mFontInfo = null; private final StringBuilder mBuilder = new StringBuilder(); private List<FontInfo> mFontList; private List<String> mFallBackList; private List<FontInfo> mFontList = new ArrayList<FontInfo>(); private FontDefinitionParser(String osFontsLocation) { private FontHandler(String osFontsLocation) { super(); mOsFontsLocation = osFontsLocation; } FontLoader getFontLoader() { return new FontLoader(mFontList, mFallBackList); public List<FontInfo> getFontList() { return mFontList; } /* (non-Javadoc) Loading @@ -263,26 +185,11 @@ public final class FontLoader { @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { if (NODE_FONTS.equals(localName)) { if (NODE_FAMILYSET.equals(localName)) { mFontList = new ArrayList<FontInfo>(); mFallBackList = new ArrayList<String>(); } else if (NODE_FONT.equals(localName)) { } else if (NODE_FAMILY.equals(localName)) { if (mFontList != null) { String ttf = attributes.getValue(ATTR_TTF); if (ttf != null) { mFontInfo = new FontInfo(); mFontInfo.ttf = mOsFontsLocation + ttf; mFontList.add(mFontInfo); } } } else if (NODE_NAME.equals(localName)) { // do nothing, we'll handle the name in the endElement } else if (NODE_FALLBACK.equals(localName)) { if (mFallBackList != null) { String ttf = attributes.getValue(ATTR_TTF); if (ttf != null) { mFallBackList.add(mOsFontsLocation + ttf); } } } Loading @@ -304,20 +211,79 @@ public final class FontLoader { */ @Override public void endElement(String uri, String localName, String name) throws SAXException { if (NODE_FONTS.equals(localName)) { // top level, do nothing } else if (NODE_FONT.equals(localName)) { if (NODE_FAMILY.equals(localName)) { if (mFontInfo != null) { // if has a normal font file, add to the list if (mFontInfo.font[Typeface.NORMAL] != null) { mFontList.add(mFontInfo); // create missing font styles, order is important. if (mFontInfo.font[Typeface.BOLD_ITALIC] == null) { computeDerivedFont(Typeface.BOLD_ITALIC, DERIVE_BOLD_ITALIC); } if (mFontInfo.font[Typeface.ITALIC] == null) { computeDerivedFont(Typeface.ITALIC, DERIVE_ITALIC); } if (mFontInfo.font[Typeface.BOLD] == null) { computeDerivedFont(Typeface.BOLD, DERIVE_BOLD); } } mFontInfo = null; } } else if (NODE_NAME.equals(localName)) { // handle a new name for an existing Font Info if (mFontInfo != null) { String family = trimXmlWhitespaces(mBuilder.toString()); mFontInfo.families.add(family); } } else if (NODE_FALLBACK.equals(localName)) { // nothing to do here. } else if (NODE_FILE.equals(localName)) { // handle a new file for an existing Font Info if (mFontInfo != null) { String fileName = trimXmlWhitespaces(mBuilder.toString()); Font font = getFont(fileName); if (font != null) { if (fileName.endsWith(FONT_SUFFIX_REGULAR)) { mFontInfo.font[Typeface.NORMAL] = font; } else if (fileName.endsWith(FONT_SUFFIX_BOLD)) { mFontInfo.font[Typeface.BOLD] = font; } else if (fileName.endsWith(FONT_SUFFIX_ITALIC)) { mFontInfo.font[Typeface.ITALIC] = font; } else if (fileName.endsWith(FONT_SUFFIX_BOLDITALIC)) { mFontInfo.font[Typeface.BOLD_ITALIC] = font; } else if (fileName.endsWith(FONT_SUFFIX_NONE)) { mFontInfo.font[Typeface.NORMAL] = font; } } } } } private Font getFont(String fileName) { try { File file = new File(mOsFontsLocation, fileName); if (file.exists()) { return Font.createFont(Font.TRUETYPE_FONT, file); } } catch (Exception e) { } return null; } private void computeDerivedFont( int toCompute, int[] basedOnList) { for (int basedOn : basedOnList) { if (mFontInfo.font[basedOn] != null) { mFontInfo.font[toCompute] = mFontInfo.font[basedOn].deriveFont(AWT_STYLES[toCompute]); return; } } // we really shouldn't stop there. This means we don't have a NORMAL font... assert false; } private String trimXmlWhitespaces(String value) { if (value == null) { Loading Loading
data/fonts/fonts.xmldeleted 100644 → 0 +0 −48 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2008 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. --> <!-- This is only used by the layoutlib to display layouts in ADT. --> <fonts> <font ttf="DroidSans"> <name>sans-serif</name> <name>arial</name> <name>helvetica</name> <name>tahoma</name> <name>verdana</name> </font> <font ttf="DroidSerif"> <name>serif</name> <name>times</name> <name>times new roman</name> <name>palatino</name> <name>georgia</name> <name>baskerville</name> <name>goudy</name> <name>fantasy</name> <name>cursive</name> <name>ITC Stone Serif</name> </font> <font ttf="DroidSansMono"> <name>monospace</name> <name>courier</name> <name>courier new</name> <name>monaco</name> </font> <fallback ttf="DroidSansFallback" /> <fallback ttf="MTLmr3m" /> </fonts>
tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java +1 −11 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.content.res.AssetManager; import java.awt.Font; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading @@ -50,7 +49,6 @@ public final class Typeface_Delegate { // ---- delegate helper data ---- private static final String DEFAULT_FAMILY = "sans-serif"; private static final int[] STYLE_BUFFER = new int[1]; private static FontLoader sFontLoader; private static final List<Typeface_Delegate> sPostInitDelegate = Loading Loading @@ -178,14 +176,6 @@ public final class Typeface_Delegate { } private void init() { STYLE_BUFFER[0] = mStyle; Font font = sFontLoader.getFont(mFamily, STYLE_BUFFER); if (font != null) { List<Font> list = new ArrayList<Font>(); list.add(font); list.addAll(sFontLoader.getFallBackFonts()); mFonts = Collections.unmodifiableList(list); mStyle = STYLE_BUFFER[0]; } mFonts = sFontLoader.getFont(mFamily, mStyle); } }
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java +134 −168 Original line number Diff line number Diff line Loading @@ -23,17 +23,13 @@ import org.xml.sax.helpers.DefaultHandler; import android.graphics.Typeface; import java.awt.Font; import java.awt.FontFormatException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.parsers.ParserConfigurationException; Loading @@ -47,49 +43,53 @@ import javax.xml.parsers.SAXParserFactory; * fonts.xml file located alongside the ttf files. */ public final class FontLoader { private static final String FONTS_DEFINITIONS = "fonts.xml"; private static final String FONTS_SYSTEM = "system_fonts.xml"; private static final String FONTS_VENDOR = "vendor_fonts.xml"; private static final String FONTS_FALLBACK = "fallback_fonts.xml"; private static final String NODE_FONTS = "fonts"; private static final String NODE_FONT = "font"; private static final String NODE_FAMILYSET = "familyset"; private static final String NODE_FAMILY = "family"; private static final String NODE_NAME = "name"; private static final String NODE_FALLBACK = "fallback"; private static final String ATTR_TTF = "ttf"; private static final String FONT_EXT = ".ttf"; private static final String[] FONT_STYLE_DEFAULT = { "", "-Regular" }; private static final String[] FONT_STYLE_BOLD = { "-Bold" }; private static final String[] FONT_STYLE_ITALIC = { "-Italic" }; private static final String[] FONT_STYLE_BOLDITALIC = { "-BoldItalic" }; // list of font style, in the order matching the Typeface Font style private static final String[][] FONT_STYLES = { FONT_STYLE_DEFAULT, FONT_STYLE_BOLD, FONT_STYLE_ITALIC, FONT_STYLE_BOLDITALIC private static final String NODE_FILE = "file"; private static final String FONT_SUFFIX_NONE = ".ttf"; private static final String FONT_SUFFIX_REGULAR = "-Regular.ttf"; private static final String FONT_SUFFIX_BOLD = "-Bold.ttf"; private static final String FONT_SUFFIX_ITALIC = "-Italic.ttf"; private static final String FONT_SUFFIX_BOLDITALIC = "-BoldItalic.ttf"; // This must match the values of Typeface styles so that we can use them for indices in this // array. private static final int[] AWT_STYLES = new int[] { Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC }; private static int[] DERIVE_BOLD_ITALIC = new int[] { Typeface.ITALIC, Typeface.BOLD, Typeface.NORMAL }; private static int[] DERIVE_ITALIC = new int[] { Typeface.NORMAL }; private static int[] DERIVE_BOLD = new int[] { Typeface.NORMAL }; private final Map<String, String> mFamilyToTtf = new HashMap<String, String>(); private final Map<String, Map<Integer, Font>> mTtfToFontMap = new HashMap<String, Map<Integer, Font>>(); private List<Font> mFallBackFonts = null; private static final List<FontInfo> mMainFonts = new ArrayList<FontInfo>(); private static final List<FontInfo> mFallbackFonts = new ArrayList<FontInfo>(); public static FontLoader create(String fontOsLocation) { try { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); parserFactory.setNamespaceAware(true); SAXParser parser = parserFactory.newSAXParser(); File f = new File(fontOsLocation + File.separator + FONTS_DEFINITIONS); // parse the system fonts FontHandler handler = parseFontFile(parserFactory, fontOsLocation, FONTS_SYSTEM); List<FontInfo> systemFonts = handler.getFontList(); FontDefinitionParser definitionParser = new FontDefinitionParser( fontOsLocation + File.separator); parser.parse(new FileInputStream(f), definitionParser); return definitionParser.getFontLoader(); // parse the fallback fonts handler = parseFontFile(parserFactory, fontOsLocation, FONTS_FALLBACK); List<FontInfo> fallbackFonts = handler.getFontList(); return new FontLoader(systemFonts, fallbackFonts); } catch (ParserConfigurationException e) { // return null below } catch (SAXException e) { Loading @@ -103,35 +103,22 @@ public final class FontLoader { return null; } private FontLoader(List<FontInfo> fontList, List<String> fallBackList) { for (FontInfo info : fontList) { for (String family : info.families) { mFamilyToTtf.put(family, info.ttf); } } private static FontHandler parseFontFile(SAXParserFactory parserFactory, String fontOsLocation, String fontFileName) throws ParserConfigurationException, SAXException, IOException, FileNotFoundException { ArrayList<Font> list = new ArrayList<Font>(); for (String path : fallBackList) { File f = new File(path + FONT_EXT); if (f.isFile()) { try { Font font = Font.createFont(Font.TRUETYPE_FONT, f); if (font != null) { list.add(font); } } catch (FontFormatException e) { // skip this font name } catch (IOException e) { // skip this font name } } } SAXParser parser = parserFactory.newSAXParser(); File f = new File(fontOsLocation, fontFileName); mFallBackFonts = Collections.unmodifiableList(list); FontHandler definitionParser = new FontHandler( fontOsLocation + File.separator); parser.parse(new FileInputStream(f), definitionParser); return definitionParser; } public List<Font> getFallBackFonts() { return mFallBackFonts; private FontLoader(List<FontInfo> fontList, List<FontInfo> fallBackList) { mMainFonts.addAll(fontList); mFallbackFonts.addAll(fallBackList); } /** Loading @@ -143,96 +130,32 @@ public final class FontLoader { * the method returns. * @return the font object or null if no match could be found. */ public synchronized Font getFont(String family, int[] style) { if (family == null) { return null; } public synchronized List<Font> getFont(String family, int style) { List<Font> result = new ArrayList<Font>(); // get the ttf name from the family String ttf = mFamilyToTtf.get(family); if (ttf == null) { return null; } // get the font from the ttf Map<Integer, Font> styleMap = mTtfToFontMap.get(ttf); if (styleMap == null) { styleMap = new HashMap<Integer, Font>(); mTtfToFontMap.put(ttf, styleMap); if (family == null) { return result; } Font f = styleMap.get(style[0]); if (f != null) { return f; } // if it doesn't exist, we create it, and we can't, we try with a simpler style switch (style[0]) { case Typeface.NORMAL: f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); // get the font objects from the main list based on family. for (FontInfo info : mMainFonts) { if (info.families.contains(family)) { result.add(info.font[style]); break; case Typeface.BOLD: case Typeface.ITALIC: f = getFont(ttf, FONT_STYLES[style[0]]); if (f == null) { f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); style[0] = Typeface.NORMAL; } break; case Typeface.BOLD_ITALIC: f = getFont(ttf, FONT_STYLES[style[0]]); if (f == null) { f = getFont(ttf, FONT_STYLES[Typeface.BOLD]); if (f != null) { style[0] = Typeface.BOLD; } else { f = getFont(ttf, FONT_STYLES[Typeface.ITALIC]); if (f != null) { style[0] = Typeface.ITALIC; } else { f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]); style[0] = Typeface.NORMAL; } } } break; } if (f != null) { styleMap.put(style[0], f); return f; // add all the fallback fonts for (FontInfo info : mFallbackFonts) { result.add(info.font[style]); } return null; } private Font getFont(String ttf, String[] fontFileSuffix) { for (String suffix : fontFileSuffix) { String name = ttf + suffix + FONT_EXT; File f = new File(name); if (f.isFile()) { try { Font font = Font.createFont(Font.TRUETYPE_FONT, f); if (font != null) { return font; } } catch (FontFormatException e) { // skip this font name } catch (IOException e) { // skip this font name } } } return null; return result; } private final static class FontInfo { String ttf; final Font[] font = new Font[4]; // Matches the 4 type-face styles. final Set<String> families; FontInfo() { Loading @@ -240,21 +163,20 @@ public final class FontLoader { } } private final static class FontDefinitionParser extends DefaultHandler { private final static class FontHandler extends DefaultHandler { private final String mOsFontsLocation; private FontInfo mFontInfo = null; private final StringBuilder mBuilder = new StringBuilder(); private List<FontInfo> mFontList; private List<String> mFallBackList; private List<FontInfo> mFontList = new ArrayList<FontInfo>(); private FontDefinitionParser(String osFontsLocation) { private FontHandler(String osFontsLocation) { super(); mOsFontsLocation = osFontsLocation; } FontLoader getFontLoader() { return new FontLoader(mFontList, mFallBackList); public List<FontInfo> getFontList() { return mFontList; } /* (non-Javadoc) Loading @@ -263,26 +185,11 @@ public final class FontLoader { @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { if (NODE_FONTS.equals(localName)) { if (NODE_FAMILYSET.equals(localName)) { mFontList = new ArrayList<FontInfo>(); mFallBackList = new ArrayList<String>(); } else if (NODE_FONT.equals(localName)) { } else if (NODE_FAMILY.equals(localName)) { if (mFontList != null) { String ttf = attributes.getValue(ATTR_TTF); if (ttf != null) { mFontInfo = new FontInfo(); mFontInfo.ttf = mOsFontsLocation + ttf; mFontList.add(mFontInfo); } } } else if (NODE_NAME.equals(localName)) { // do nothing, we'll handle the name in the endElement } else if (NODE_FALLBACK.equals(localName)) { if (mFallBackList != null) { String ttf = attributes.getValue(ATTR_TTF); if (ttf != null) { mFallBackList.add(mOsFontsLocation + ttf); } } } Loading @@ -304,20 +211,79 @@ public final class FontLoader { */ @Override public void endElement(String uri, String localName, String name) throws SAXException { if (NODE_FONTS.equals(localName)) { // top level, do nothing } else if (NODE_FONT.equals(localName)) { if (NODE_FAMILY.equals(localName)) { if (mFontInfo != null) { // if has a normal font file, add to the list if (mFontInfo.font[Typeface.NORMAL] != null) { mFontList.add(mFontInfo); // create missing font styles, order is important. if (mFontInfo.font[Typeface.BOLD_ITALIC] == null) { computeDerivedFont(Typeface.BOLD_ITALIC, DERIVE_BOLD_ITALIC); } if (mFontInfo.font[Typeface.ITALIC] == null) { computeDerivedFont(Typeface.ITALIC, DERIVE_ITALIC); } if (mFontInfo.font[Typeface.BOLD] == null) { computeDerivedFont(Typeface.BOLD, DERIVE_BOLD); } } mFontInfo = null; } } else if (NODE_NAME.equals(localName)) { // handle a new name for an existing Font Info if (mFontInfo != null) { String family = trimXmlWhitespaces(mBuilder.toString()); mFontInfo.families.add(family); } } else if (NODE_FALLBACK.equals(localName)) { // nothing to do here. } else if (NODE_FILE.equals(localName)) { // handle a new file for an existing Font Info if (mFontInfo != null) { String fileName = trimXmlWhitespaces(mBuilder.toString()); Font font = getFont(fileName); if (font != null) { if (fileName.endsWith(FONT_SUFFIX_REGULAR)) { mFontInfo.font[Typeface.NORMAL] = font; } else if (fileName.endsWith(FONT_SUFFIX_BOLD)) { mFontInfo.font[Typeface.BOLD] = font; } else if (fileName.endsWith(FONT_SUFFIX_ITALIC)) { mFontInfo.font[Typeface.ITALIC] = font; } else if (fileName.endsWith(FONT_SUFFIX_BOLDITALIC)) { mFontInfo.font[Typeface.BOLD_ITALIC] = font; } else if (fileName.endsWith(FONT_SUFFIX_NONE)) { mFontInfo.font[Typeface.NORMAL] = font; } } } } } private Font getFont(String fileName) { try { File file = new File(mOsFontsLocation, fileName); if (file.exists()) { return Font.createFont(Font.TRUETYPE_FONT, file); } } catch (Exception e) { } return null; } private void computeDerivedFont( int toCompute, int[] basedOnList) { for (int basedOn : basedOnList) { if (mFontInfo.font[basedOn] != null) { mFontInfo.font[toCompute] = mFontInfo.font[basedOn].deriveFont(AWT_STYLES[toCompute]); return; } } // we really shouldn't stop there. This means we don't have a NORMAL font... assert false; } private String trimXmlWhitespaces(String value) { if (value == null) { Loading