diff options
author | Raph Levien <raph@google.com> | 2014-08-25 13:47:16 -0700 |
---|---|---|
committer | Raph Levien <raph@google.com> | 2014-08-26 19:37:45 -0700 |
commit | 117cbebe810613d4a6de034f02652cdbbfef4cde (patch) | |
tree | 163e0944d265b23001c9644c570a04f47ae3b030 /core/jni/android | |
parent | 0db4f35e0bbc25ee25ebe2d57174893217248597 (diff) | |
download | frameworks_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.cpp | 29 | ||||
-rw-r--r-- | core/jni/android/graphics/Typeface.cpp | 7 | ||||
-rw-r--r-- | core/jni/android/graphics/TypefaceImpl.cpp | 64 | ||||
-rw-r--r-- | core/jni/android/graphics/TypefaceImpl.h | 9 |
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); |