Merge "New weight-aware font config" into lmp-dev
This commit is contained in:
@@ -62,10 +62,26 @@ static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr,
|
||||
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 @@ static jboolean FontFamily_addFontFromAsset(JNIEnv* env, jobject, jlong familyPt
|
||||
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 },
|
||||
};
|
||||
|
||||
|
||||
@@ -41,6 +41,12 @@ static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandl
|
||||
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 void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
|
||||
|
||||
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",
|
||||
|
||||
@@ -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 @@ static void getDefaultTypefaceOnce() {
|
||||
// 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 @@ TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Sty
|
||||
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 @@ TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size
|
||||
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 @@ TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size
|
||||
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 @@ void TypefaceImpl_unref(TypefaceImpl* face) {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -28,6 +28,13 @@ namespace android {
|
||||
|
||||
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_resolveDefault(TypefaceImpl* src);
|
||||
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -18,8 +18,6 @@ package android.graphics;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* A family of typefaces with different styles.
|
||||
*
|
||||
@@ -64,6 +62,10 @@ public class FontFamily {
|
||||
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 @@ public class FontFamily {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -33,23 +33,48 @@ import java.util.List;
|
||||
*/
|
||||
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 @@ public class FontListParser {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -66,8 +66,7 @@ public class Typeface {
|
||||
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 @@ public class Typeface {
|
||||
}
|
||||
|
||||
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 @@ public class Typeface {
|
||||
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 @@ public class Typeface {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user