Merge "New weight-aware font config" into lmp-dev
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 1d465b3..bfb30b7 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -62,10 +62,26 @@
         ALOGE("addFont failed to create font %s", str.c_str());
         return false;
     }
-    FontFamily* fontFamily = (FontFamily*)familyPtr;
+    FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
     return addSkTypeface(fontFamily, face);
 }
 
+static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr,
+        jstring path, jint weight, jboolean isItalic) {
+    NPE_CHECK_RETURN_ZERO(env, path);
+    ScopedUtfChars str(env, path);
+    SkTypeface* face = SkTypeface::CreateFromFile(str.c_str());
+    if (face == NULL) {
+        ALOGE("addFont failed to create font %s", str.c_str());
+        return false;
+    }
+    FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
+    MinikinFont* minikinFont = new MinikinFontSkia(face);
+    fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic));
+    minikinFont->Unref();
+    return true;
+}
+
 static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPtr,
         jobject jassetMgr, jstring jpath) {
     NPE_CHECK_RETURN_ZERO(env, jassetMgr);
@@ -92,17 +108,18 @@
         ALOGE("addFontFromAsset failed to create font %s", str.c_str());
         return false;
     }
-    FontFamily* fontFamily = (FontFamily*)familyPtr;
+    FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
     return addSkTypeface(fontFamily, face);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 static JNINativeMethod gFontFamilyMethods[] = {
-    { "nCreateFamily",            "(Ljava/lang/String;I)J", (void*)FontFamily_create },
-    { "nUnrefFamily",             "(J)V", (void*)FontFamily_unref },
-    { "nAddFont",                 "(JLjava/lang/String;)Z", (void*)FontFamily_addFont },
-    { "nAddFontFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z",
+    { "nCreateFamily",         "(Ljava/lang/String;I)J", (void*)FontFamily_create },
+    { "nUnrefFamily",          "(J)V", (void*)FontFamily_unref },
+    { "nAddFont",              "(JLjava/lang/String;)Z", (void*)FontFamily_addFont },
+    { "nAddFontWeightStyle",   "(JLjava/lang/String;IZ)Z", (void*)FontFamily_addFontWeightStyle },
+    { "nAddFontFromAsset",     "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z",
                                            (void*)FontFamily_addFontFromAsset },
 };
 
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index cf4e838..2029658 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -41,6 +41,12 @@
     return reinterpret_cast<jlong>(face);
 }
 
+static jlong Typeface_createWeightAlias(JNIEnv* env, jobject, jlong familyHandle, jint weight) {
+    TypefaceImpl* family = reinterpret_cast<TypefaceImpl*>(familyHandle);
+    TypefaceImpl* face = TypefaceImpl_createWeightAlias(family, weight);
+    return reinterpret_cast<jlong>(face);
+}
+
 static void Typeface_unref(JNIEnv* env, jobject obj, jlong faceHandle) {
     TypefaceImpl* face = reinterpret_cast<TypefaceImpl*>(faceHandle);
     TypefaceImpl_unref(face);
@@ -65,6 +71,7 @@
 
 static JNINativeMethod gTypefaceMethods[] = {
     { "nativeCreateFromTypeface", "(JI)J", (void*)Typeface_createFromTypeface },
+    { "nativeCreateWeightAlias",  "(JI)J", (void*)Typeface_createWeightAlias },
     { "nativeUnref",              "(J)V",  (void*)Typeface_unref },
     { "nativeGetStyle",           "(J)I",  (void*)Typeface_getStyle },
     { "nativeCreateFromArray",    "([J)J",
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
index 9ce6de1..7afbeb2 100644
--- a/core/jni/android/graphics/TypefaceImpl.cpp
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -39,14 +39,17 @@
 
 namespace android {
 
-// Any weight greater than or equal to this is considered "bold" for
-// legacy API.
-static const int kBoldThreshold = 6;
-
-static FontStyle styleFromSkiaStyle(SkTypeface::Style skiaStyle) {
-    int weight = (skiaStyle & SkTypeface::kBold) != 0 ? 7 : 4;
-    bool italic = (skiaStyle & SkTypeface::kItalic) != 0;
-    return FontStyle(weight, italic);
+// Resolve the 1..9 weight based on base weight and bold flag
+static void resolveStyle(TypefaceImpl* typeface) {
+    int weight = typeface->fBaseWeight / 100;
+    if (typeface->fSkiaStyle & SkTypeface::kBold) {
+        weight += 3;
+    }
+    if (weight > 9) {
+        weight = 9;
+    }
+    bool italic = (typeface->fSkiaStyle & SkTypeface::kItalic) != 0;
+    typeface->fStyle = FontStyle(weight, italic);
 }
 
 TypefaceImpl* gDefaultTypeface = NULL;
@@ -90,7 +93,9 @@
         // default so we can make progress before that happens.
         gDefaultTypeface = new TypefaceImpl;
         gDefaultTypeface->fFontCollection = makeFontCollection();
-        gDefaultTypeface->fStyle = FontStyle();
+        gDefaultTypeface->fSkiaStyle = SkTypeface::kNormal;
+        gDefaultTypeface->fBaseWeight = 400;
+        resolveStyle(gDefaultTypeface);
     }
 }
 
@@ -109,25 +114,23 @@
     if (result != 0) {
         result->fFontCollection = resolvedFace->fFontCollection;
         result->fFontCollection->Ref();
-        result->fStyle = styleFromSkiaStyle(style);
+        result->fSkiaStyle = style;
+        result->fBaseWeight = resolvedFace->fBaseWeight;
+        resolveStyle(result);
     }
     return result;
 }
 
-static TypefaceImpl* createFromSkTypeface(SkTypeface* typeface) {
-    if (typeface == NULL) {
-        return NULL;
-    }
-    MinikinFont* minikinFont = new MinikinFontSkia(typeface);
-    std::vector<FontFamily *> typefaces;
-    FontFamily* family = new FontFamily();
-    family->addFont(minikinFont);
-    minikinFont->Unref();
-    typefaces.push_back(family);
+TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int weight) {
+    TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(src);
     TypefaceImpl* result = new TypefaceImpl;
-    result->fFontCollection = new FontCollection(typefaces);
-    family->Unref();
-    result->fStyle = FontStyle();  // TODO: improve
+    if (result != 0) {
+        result->fFontCollection = resolvedFace->fFontCollection;
+        result->fFontCollection->Ref();
+        result->fSkiaStyle = resolvedFace->fSkiaStyle;
+        result->fBaseWeight = weight;
+        resolveStyle(result);
+    }
     return result;
 }
 
@@ -141,7 +144,7 @@
     result->fFontCollection = new FontCollection(familyVec);
     if (size == 0) {
         ALOGW("createFromFamilies creating empty collection");
-        result->fStyle = FontStyle();
+        result->fSkiaStyle = SkTypeface::kNormal;
     } else {
         const FontStyle defaultStyle;
         FontFamily* firstFamily = reinterpret_cast<FontFamily*>(families[0]);
@@ -150,11 +153,13 @@
             SkTypeface* skTypeface = reinterpret_cast<MinikinFontSkia*>(mf)->GetSkTypeface();
             // TODO: probably better to query more precise style from family, will be important
             // when we open up API to access 100..900 weights
-            result->fStyle = styleFromSkiaStyle(skTypeface->style());
+            result->fSkiaStyle = skTypeface->style();
         } else {
-            result->fStyle = defaultStyle;
+            result->fSkiaStyle = SkTypeface::kNormal;
         }
     }
+    result->fBaseWeight = 400;
+    resolveStyle(result);
     return result;
 }
 
@@ -166,12 +171,7 @@
 }
 
 int TypefaceImpl_getStyle(TypefaceImpl* face) {
-    FontStyle style = face->fStyle;
-    int result = style.getItalic() ? SkTypeface::kItalic : 0;
-    if (style.getWeight() >= kBoldThreshold) {
-        result |= SkTypeface::kBold;
-    }
-    return result;
+    return face->fSkiaStyle;
 }
 
 void TypefaceImpl_setDefault(TypefaceImpl* face) {
diff --git a/core/jni/android/graphics/TypefaceImpl.h b/core/jni/android/graphics/TypefaceImpl.h
index 12b3403..d129f621 100644
--- a/core/jni/android/graphics/TypefaceImpl.h
+++ b/core/jni/android/graphics/TypefaceImpl.h
@@ -28,6 +28,13 @@
 
 struct TypefaceImpl {
     FontCollection *fFontCollection;
+
+    // style used for constructing and querying Typeface objects
+    SkTypeface::Style fSkiaStyle;
+    // base weight in CSS-style units, 100..900
+    int fBaseWeight;
+
+    // resolved style actually used for rendering
     FontStyle fStyle;
 };
 
@@ -41,6 +48,8 @@
 
 TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style);
 
+TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int baseweight);
+
 // When we remove the USE_MINIKIN ifdef, probably a good idea to move the casting
 // (from jlong to FontFamily*) to the caller in Typeface.cpp.
 TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size);
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 0f0281b..c4a949f 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
+    NOTE: this file is the legacy format, for compatibility with apps. The new,
+    more flexible format is fonts.xml. Please keep the two in sync until the legacy
+    format can be fully removed.
+
     Fallback Fonts
 
     This file specifies the fonts, and the priority order, that will be searched for any
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index a4d4906..04bc67a 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -1,4 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+    NOTE: this is the newer (L) version of the system font configuration,
+    supporting richer weight selection. Some apps will expect the older
+    version, so please keep system_fonts.xml and fallback_fonts.xml in sync
+    with any changes, even though framework will only read this file.
+
+    All fonts withohut names are added to the default list. Fonts are chosen
+    based on a match: full BCP-47 language tag including script, then just
+    language, and finally order (the first font containing the glyph).
+
+    Order of appearance is also the tiebreaker for weight matching. This is
+    the reason why the 900 weights of Roboto precede the 700 weights - we
+    prefer the former when an 800 weight is requested. Since bold spans
+    effectively add 300 to the weight, this ensures that 900 is the bold
+    paired with the 500 weight, ensuring adequate contrast.
+-->
 <familyset version="22">
     <!-- first font is default -->
     <family name="sans-serif">
@@ -10,15 +26,16 @@
         <font weight="400" style="italic">Roboto-Italic.ttf</font>
         <font weight="500" style="normal">Roboto-Medium.ttf</font>
         <font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
-        <font weight="700" style="normal">Roboto-Bold.ttf</font>
-        <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
         <font weight="900" style="normal">Roboto-Black.ttf</font>
         <font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
+        <font weight="700" style="normal">Roboto-Bold.ttf</font>
+        <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
     </family>
 
     <!-- Note that aliases must come after the fonts they reference. -->
     <alias name="sans-serif-thin" to="sans-serif" weight="100" />
     <alias name="sans-serif-light" to="sans-serif" weight="300" />
+    <alias name="sans-serif-medium" to="sans-serif" weight="500" />
     <alias name="sans-serif-black" to="sans-serif" weight="900" />
     <alias name="arial" to="sans-serif" />
     <alias name="helvetica" to="sans-serif" />
@@ -227,6 +244,9 @@
     <family>
         <font weight="400" style="normal">NotoColorEmoji.ttf</font>
     </family>
+    <family>
+        <font weight="400" style="normal">DroidSansFallback.ttf</font>
+    </family>
     <family lang="ja">
         <font weight="400" style="normal">MTLmr3m.ttf</font>
     </family>
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index 11d3165..b8b7e76 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -18,8 +18,6 @@
 
 import android.content.res.AssetManager;
 
-import java.io.File;
-
 /**
  * A family of typefaces with different styles.
  *
@@ -64,6 +62,10 @@
         return nAddFont(mNativePtr, path);
     }
 
+    public boolean addFontWeightStyle(String path, int weight, boolean style) {
+        return nAddFontWeightStyle(mNativePtr, path, weight, style);
+    }
+
     public boolean addFontFromAsset(AssetManager mgr, String path) {
         return nAddFontFromAsset(mNativePtr, mgr, path);
     }
@@ -71,6 +73,8 @@
     private static native long nCreateFamily(String lang, int variant);
     private static native void nUnrefFamily(long nativePtr);
     private static native boolean nAddFont(long nativeFamily, String path);
+    private static native boolean nAddFontWeightStyle(long nativeFamily, String path,
+            int weight, boolean isItalic);
     private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr,
             String path);
 }
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index a863a06..97081f9 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -33,23 +33,48 @@
  */
 public class FontListParser {
 
+    public static class Config {
+        Config() {
+            families = new ArrayList<Family>();
+            aliases = new ArrayList<Alias>();
+        }
+        public List<Family> families;
+        public List<Alias> aliases;
+    }
+
+    public static class Font {
+        Font(String fontName, int weight, boolean isItalic) {
+            this.fontName = fontName;
+            this.weight = weight;
+            this.isItalic = isItalic;
+        }
+        public String fontName;
+        public int weight;
+        public boolean isItalic;
+    }
+
+    public static class Alias {
+        public String name;
+        public String toName;
+        public int weight;
+    }
+
     public static class Family {
-        public Family(List<String> names, List<String> fontFiles, String lang, String variant) {
-            this.names = names;
-            this.fontFiles = fontFiles;
+        public Family(String name, List<Font> fonts, String lang, String variant) {
+            this.name = name;
+            this.fonts = fonts;
             this.lang = lang;
             this.variant = variant;
         }
 
-        public List<String> names;
-        // todo: need attributes for font files
-        public List<String> fontFiles;
+        public String name;
+        public List<Font> fonts;
         public String lang;
         public String variant;
     }
 
     /* Parse fallback list (no names) */
-    public static List<Family> parse(InputStream in) throws XmlPullParserException, IOException {
+    public static Config parse(InputStream in) throws XmlPullParserException, IOException {
         try {
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(in, null);
@@ -60,57 +85,59 @@
         }
     }
 
-    private static List<Family> readFamilies(XmlPullParser parser)
+    private static Config readFamilies(XmlPullParser parser)
             throws XmlPullParserException, IOException {
-        List<Family> families = new ArrayList<Family>();
+        Config config = new Config();
         parser.require(XmlPullParser.START_TAG, null, "familyset");
         while (parser.next() != XmlPullParser.END_TAG) {
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             if (parser.getName().equals("family")) {
-                families.add(readFamily(parser));
+                config.families.add(readFamily(parser));
+            } else if (parser.getName().equals("alias")) {
+                config.aliases.add(readAlias(parser));
             } else {
                 skip(parser);
             }
         }
-        return families;
+        return config;
     }
 
     private static Family readFamily(XmlPullParser parser)
             throws XmlPullParserException, IOException {
-        List<String> names = null;
-        List<String> fontFiles = new ArrayList<String>();
-        String lang = null;
-        String variant = null;
+        String name = parser.getAttributeValue(null, "name");
+        String lang = parser.getAttributeValue(null, "lang");
+        String variant = parser.getAttributeValue(null, "variant");
+        List<Font> fonts = new ArrayList<Font>();
         while (parser.next() != XmlPullParser.END_TAG) {
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             String tag = parser.getName();
-            if (tag.equals("fileset")) {
-                while (parser.next() != XmlPullParser.END_TAG) {
-                    if (parser.getEventType() != XmlPullParser.START_TAG) continue;
-                    if (parser.getName().equals("file")) {
-                        if (lang == null) {
-                            lang = parser.getAttributeValue(null, "lang");
-                        }
-                        if (variant == null) {
-                            variant = parser.getAttributeValue(null, "variant");
-                        }
-                        String filename = parser.nextText();
-                        String fullFilename = "/system/fonts/" + filename;
-                        fontFiles.add(fullFilename);
-                    }
-                }
-            } else if (tag.equals("nameset")) {
-                names = new ArrayList<String>();
-                while (parser.next() != XmlPullParser.END_TAG) {
-                    if (parser.getEventType() != XmlPullParser.START_TAG) continue;
-                    if (parser.getName().equals("name")) {
-                        String name = parser.nextText();
-                        names.add(name);
-                    }
-                }
+            if (tag.equals("font")) {
+                String weightStr = parser.getAttributeValue(null, "weight");
+                int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
+                boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
+                String filename = parser.nextText();
+                String fullFilename = "/system/fonts/" + filename;
+                fonts.add(new Font(fullFilename, weight, isItalic));
+            } else {
+                skip(parser);
             }
         }
-        return new Family(names, fontFiles, lang, variant);
+        return new Family(name, fonts, lang, variant);
+    }
+
+    private static Alias readAlias(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        Alias alias = new Alias();
+        alias.name = parser.getAttributeValue(null, "name");
+        alias.toName = parser.getAttributeValue(null, "to");
+        String weightStr = parser.getAttributeValue(null, "weight");
+        if (weightStr == null) {
+            alias.weight = 400;
+        } else {
+            alias.weight = Integer.parseInt(weightStr);
+        }
+        skip(parser);  // alias tag is empty, ignore any contents and consume end tag
+        return alias;
     }
 
     private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 568d3f2..db42314 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -66,8 +66,7 @@
     static Map<String, Typeface> sSystemFontMap;
     static FontFamily[] sFallbackFonts;
 
-    static final String SYSTEM_FONTS_CONFIG = "system_fonts.xml";
-    static final String FALLBACK_FONTS_CONFIG = "fallback_fonts.xml";
+    static final String FONTS_CONFIG = "fonts.xml";
 
     /**
      * @hide
@@ -261,10 +260,9 @@
     }
 
     private static FontFamily makeFamilyFromParsed(FontListParser.Family family) {
-        // TODO: expand to handle attributes like lang and variant
         FontFamily fontFamily = new FontFamily(family.lang, family.variant);
-        for (String fontFile : family.fontFiles) {
-            fontFamily.addFont(fontFile);
+        for (FontListParser.Font font : family.fonts) {
+            fontFamily.addFontWeightStyle(font.fontName, font.weight, font.isItalic);
         }
         return fontFamily;
     }
@@ -277,48 +275,53 @@
     private static void init() {
         // Load font config and initialize Minikin state
         File systemFontConfigLocation = getSystemFontConfigLocation();
-        File systemConfigFilename = new File(systemFontConfigLocation, SYSTEM_FONTS_CONFIG);
-        File configFilename = new File(systemFontConfigLocation, FALLBACK_FONTS_CONFIG);
+        File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);
         try {
-            // TODO: throws an exception non-Minikin builds, to fail early;
-            // remove when Minikin-only
-            new FontFamily();
+            FileInputStream fontsIn = new FileInputStream(configFilename);
+            FontListParser.Config fontConfig = FontListParser.parse(fontsIn);
 
-            FileInputStream systemIn = new FileInputStream(systemConfigFilename);
-            List<FontListParser.Family> systemFontConfig = FontListParser.parse(systemIn);
-
-            FileInputStream fallbackIn = new FileInputStream(configFilename);
             List<FontFamily> familyList = new ArrayList<FontFamily>();
             // Note that the default typeface is always present in the fallback list;
             // this is an enhancement from pre-Minikin behavior.
-            familyList.add(makeFamilyFromParsed(systemFontConfig.get(0)));
-            for (Family f : FontListParser.parse(fallbackIn)) {
-                familyList.add(makeFamilyFromParsed(f));
+            for (int i = 0; i < fontConfig.families.size(); i++) {
+                Family f = fontConfig.families.get(i);
+                if (i == 0 || f.name == null) {
+                    familyList.add(makeFamilyFromParsed(f));
+                }
             }
             sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]);
             setDefault(Typeface.createFromFamilies(sFallbackFonts));
 
             Map<String, Typeface> systemFonts = new HashMap<String, Typeface>();
-            for (int i = 0; i < systemFontConfig.size(); i++) {
+            for (int i = 0; i < fontConfig.families.size(); i++) {
                 Typeface typeface;
-                Family f = systemFontConfig.get(i);
-                if (i == 0) {
-                    // The first entry is the default typeface; no sense in duplicating
-                    // the corresponding FontFamily.
-                    typeface = sDefaultTypeface;
-                } else {
-                    FontFamily fontFamily = makeFamilyFromParsed(f);
-                    FontFamily[] families = { fontFamily };
-                    typeface = Typeface.createFromFamiliesWithDefault(families);
+                Family f = fontConfig.families.get(i);
+                if (f.name != null) {
+                    if (i == 0) {
+                        // The first entry is the default typeface; no sense in
+                        // duplicating the corresponding FontFamily.
+                        typeface = sDefaultTypeface;
+                    } else {
+                        FontFamily fontFamily = makeFamilyFromParsed(f);
+                        FontFamily[] families = { fontFamily };
+                        typeface = Typeface.createFromFamiliesWithDefault(families);
+                    }
+                    systemFonts.put(f.name, typeface);
                 }
-                for (String name : f.names) {
-                    systemFonts.put(name, typeface);
+            }
+            for (FontListParser.Alias alias : fontConfig.aliases) {
+                Typeface base = systemFonts.get(alias.toName);
+                Typeface newFace = base;
+                int weight = alias.weight;
+                if (weight != 400) {
+                    newFace = new Typeface(nativeCreateWeightAlias(base.native_instance, weight));
                 }
+                systemFonts.put(alias.name, newFace);
             }
             sSystemFontMap = systemFonts;
 
         } catch (RuntimeException e) {
-            Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)");
+            Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)", e);
             // TODO: normal in non-Minikin case, remove or make error when Minikin-only
         } catch (FileNotFoundException e) {
             Log.e(TAG, "Error opening " + configFilename);
@@ -383,6 +386,7 @@
     }
 
     private static native long nativeCreateFromTypeface(long native_instance, int style);
+    private static native long nativeCreateWeightAlias(long native_instance, int weight);
     private static native void nativeUnref(long native_instance);
     private static native int  nativeGetStyle(long native_instance);
     private static native long nativeCreateFromArray(long[] familyArray);