diff options
author | Xavier Ducrohet <xav@android.com> | 2011-10-04 18:01:07 -0700 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2011-10-04 18:02:10 -0700 |
commit | 178006a0e05b41b4c4de93aec30368a9102ca140 (patch) | |
tree | 5261679b7d2ae70313d6896a54b6301c69a13179 /tools | |
parent | 3c1951c442e40f7f46775acfc8a22c24f04d8cfc (diff) | |
download | frameworks_base-178006a0e05b41b4c4de93aec30368a9102ca140.zip frameworks_base-178006a0e05b41b4c4de93aec30368a9102ca140.tar.gz frameworks_base-178006a0e05b41b4c4de93aec30368a9102ca140.tar.bz2 |
Layoutlib now parses system_fonts.xml instead of its own.
Also parse fallback_fonts.
This lets layoutlib automatically use the same fonts as the base
platforms, for instance it now uses the new ICS fonts.
Change-Id: Id6e778dc0e3f2a9112601e0eaf8499a9713ec433
Diffstat (limited to 'tools')
-rw-r--r-- | tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java | 12 | ||||
-rw-r--r-- | tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java | 302 |
2 files changed, 135 insertions, 179 deletions
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java index 0f084f7..dd14355 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java @@ -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; /** @@ -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 = @@ -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); } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java index f62fad2..0d1ba7c 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java @@ -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; @@ -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); + // parse the fallback fonts + handler = parseFontFile(parserFactory, fontOsLocation, FONTS_FALLBACK); + List<FontInfo> fallbackFonts = handler.getFontList(); - return definitionParser.getFontLoader(); + return new FontLoader(systemFonts, fallbackFonts); } catch (ParserConfigurationException e) { // return null below } catch (SAXException e) { @@ -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); } /** @@ -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; - } - - // 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); + public synchronized List<Font> getFont(String family, int style) { + List<Font> result = new ArrayList<Font>(); - 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]); - 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; - } - } - } + // 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; + } } - 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() { @@ -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) @@ -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); - } + mFontInfo = new FontInfo(); } } @@ -304,19 +211,78 @@ 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)) { - mFontInfo = null; + 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) { |