summaryrefslogtreecommitdiffstats
path: root/core/jni/android
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2014-08-25 13:47:16 -0700
committerRaph Levien <raph@google.com>2014-08-26 19:37:45 -0700
commit117cbebe810613d4a6de034f02652cdbbfef4cde (patch)
tree163e0944d265b23001c9644c570a04f47ae3b030 /core/jni/android
parent0db4f35e0bbc25ee25ebe2d57174893217248597 (diff)
downloadframeworks_base-117cbebe810613d4a6de034f02652cdbbfef4cde.zip
frameworks_base-117cbebe810613d4a6de034f02652cdbbfef4cde.tar.gz
frameworks_base-117cbebe810613d4a6de034f02652cdbbfef4cde.tar.bz2
New weight-aware font config
Parse new fonts.xml config file, and resolve weight selection based on the base weight of the font (as defined by a weight alias specified in the config file) and the requested bold flag. This change improves the appearance of bold spans for alternate weights of Roboto. In addition, this patch enables weight selection for fallback fonts. For example, if an additional font with a weight of 100 is added to the Hebrew font family in the fallback list, then requesting "sans-serif-thin" would select that font for Hebrew text. Bug: 14538154 Change-Id: I99a04fad4f7bf01c75726e760d42735dd9003496
Diffstat (limited to 'core/jni/android')
-rw-r--r--core/jni/android/graphics/FontFamily.cpp29
-rw-r--r--core/jni/android/graphics/Typeface.cpp7
-rw-r--r--core/jni/android/graphics/TypefaceImpl.cpp64
-rw-r--r--core/jni/android/graphics/TypefaceImpl.h9
4 files changed, 71 insertions, 38 deletions
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 @@ 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 },
};
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 @@ 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",
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 @@ 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) {
diff --git a/core/jni/android/graphics/TypefaceImpl.h b/core/jni/android/graphics/TypefaceImpl.h
index 12b3403..d129f62 100644
--- a/core/jni/android/graphics/TypefaceImpl.h
+++ b/core/jni/android/graphics/TypefaceImpl.h
@@ -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);