Loading core/jni/android/graphics/Typeface.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,8 @@ static jint Typeface_getBaseWeight(JNIEnv* env, jobject obj, jlong faceHandle) { return face->fBaseWeight; } static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) { static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray, int weight, int italic) { ScopedLongArrayRO families(env, familyArray); std::vector<std::shared_ptr<minikin::FontFamily>> familyVec; familyVec.reserve(families.size()); Loading @@ -95,7 +96,8 @@ static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArr FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]); familyVec.emplace_back(family->family); } return reinterpret_cast<jlong>(Typeface::createFromFamilies(std::move(familyVec))); return reinterpret_cast<jlong>( Typeface::createFromFamilies(std::move(familyVec), weight, italic)); } static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) { Loading Loading @@ -133,7 +135,7 @@ static const JNINativeMethod gTypefaceMethods[] = { { "nativeUnref", "(J)V", (void*)Typeface_unref }, { "nativeGetStyle", "(J)I", (void*)Typeface_getStyle }, { "nativeGetBaseWeight", "(J)I", (void*)Typeface_getBaseWeight }, { "nativeCreateFromArray", "([J)J", { "nativeCreateFromArray", "([JII)J", (void*)Typeface_createFromArray }, { "nativeSetDefault", "(J)V", (void*)Typeface_setDefault }, { "nativeGetSupportedAxes", "(J)[I", (void*)Typeface_getSupportedAxes }, Loading graphics/java/android/graphics/Typeface.java +48 −24 Original line number Diff line number Diff line Loading @@ -173,7 +173,8 @@ public class Typeface { if (sFallbackFonts != null) { synchronized (sDynamicTypefaceCache) { final String key = Builder.createAssetUid( mgr, path, 0 /* ttcIndex */, null /* axes */); mgr, path, 0 /* ttcIndex */, null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */); Typeface typeface = sDynamicTypefaceCache.get(key); if (typeface != null) return typeface; Loading @@ -186,7 +187,8 @@ public class Typeface { return null; } FontFamily[] families = {fontFamily}; typeface = createFromFamiliesWithDefault(families); typeface = createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); sDynamicTypefaceCache.put(key, typeface); return typeface; } Loading Loading @@ -251,10 +253,12 @@ public class Typeface { fontFamily.allowUnsupportedFont(); fontFamily.freeze(); FontFamily[] familyChain = { fontFamily }; typeface = createFromFamiliesWithDefault(familyChain); typeface = createFromFamiliesWithDefault(familyChain, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); synchronized (sDynamicTypefaceCache) { final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */); null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */); sDynamicTypefaceCache.put(key, typeface); } return typeface; Loading @@ -268,7 +272,8 @@ public class Typeface { */ public static Typeface findFromCache(AssetManager mgr, String path) { synchronized (sDynamicTypefaceCache) { final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */); final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */); Typeface typeface = sDynamicTypefaceCache.get(key); if (typeface != null) { return typeface; Loading Loading @@ -406,7 +411,9 @@ public class Typeface { FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR); return; } Typeface typeface = Typeface.createFromFamiliesWithDefault(new FontFamily[] { fontFamily }); Typeface typeface = Typeface.createFromFamiliesWithDefault( new FontFamily[] { fontFamily }, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); synchronized (sDynamicTypefaceCache) { String key = createProviderUid(request.getProviderAuthority(), request.getQuery()); sDynamicTypefaceCache.put(key, typeface); Loading Loading @@ -715,7 +722,7 @@ public class Typeface { * @return Unique id for a given AssetManager and asset path. */ private static String createAssetUid(final AssetManager mgr, String path, int ttcIndex, @Nullable FontVariationAxis[] axes) { @Nullable FontVariationAxis[] axes, int weight, int italic) { final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers(); final StringBuilder builder = new StringBuilder(); final int size = pkgs.size(); Loading @@ -727,6 +734,10 @@ public class Typeface { builder.append("-"); builder.append(Integer.toString(ttcIndex)); builder.append("-"); builder.append(Integer.toString(weight)); builder.append("-"); builder.append(Integer.toString(italic)); builder.append("-"); if (axes != null) { for (FontVariationAxis axis : axes) { builder.append(axis.getTag()); Loading Loading @@ -791,7 +802,7 @@ public class Typeface { * @return Newly created Typeface. May return null if some parameters are invalid. */ public Typeface build() { if (mFd != null) { // set source by setSourceFromFile(FileDescriptor) if (mFd != null) { // Builder is created with file descriptor. try (FileInputStream fis = new FileInputStream(mFd)) { FileChannel channel = fis.getChannel(); long size = channel.size(); Loading @@ -806,12 +817,13 @@ public class Typeface { return resolveFallbackTypeface(); } FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, mWeight, mItalic); } catch (IOException e) { return resolveFallbackTypeface(); } } else if (mAssetManager != null) { // set source by setSourceFromAsset() final String key = createAssetUid(mAssetManager, mPath, mTtcIndex, mAxes); } else if (mAssetManager != null) { // Builder is created with asset manager. final String key = createAssetUid( mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic); synchronized (sLock) { Typeface typeface = sDynamicTypefaceCache.get(key); if (typeface != null) return typeface; Loading @@ -825,11 +837,11 @@ public class Typeface { return resolveFallbackTypeface(); } FontFamily[] families = { fontFamily }; typeface = createFromFamiliesWithDefault(families); typeface = createFromFamiliesWithDefault(families, mWeight, mItalic); sDynamicTypefaceCache.put(key, typeface); return typeface; } } else if (mPath != null) { // set source by setSourceFromFile(File) } else if (mPath != null) { // Builder is created with file path. final FontFamily fontFamily = new FontFamily(); if (!fontFamily.addFont(mPath, mTtcIndex, mAxes, mWeight, mItalic)) { fontFamily.abortCreation(); Loading @@ -839,7 +851,7 @@ public class Typeface { return resolveFallbackTypeface(); } FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, mWeight, mItalic); } else if (mFonts != null) { final FontFamily fontFamily = new FontFamily(); boolean atLeastOneFont = false; Loading @@ -865,7 +877,7 @@ public class Typeface { } fontFamily.freeze(); FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, mWeight, mItalic); } // Must not reach here. Loading Loading @@ -969,7 +981,7 @@ public class Typeface { if (typeface != null) return typeface; final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */); null /* axes */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); typeface = sDynamicTypefaceCache.get(key); if (typeface != null) return typeface; Loading @@ -984,7 +996,8 @@ public class Typeface { fontFamily.allowUnsupportedFont(); fontFamily.freeze(); final FontFamily[] families = { fontFamily }; typeface = createFromFamiliesWithDefault(families); typeface = createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); sDynamicTypefaceCache.put(key, typeface); return typeface; } else { Loading Loading @@ -1037,7 +1050,8 @@ public class Typeface { fontFamily.allowUnsupportedFont(); fontFamily.freeze(); FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); } else { fontFamily.abortCreation(); } Loading @@ -1055,16 +1069,25 @@ public class Typeface { for (int i = 0; i < families.length; i++) { ptrArray[i] = families[i].mNativePtr; } return new Typeface(nativeCreateFromArray(ptrArray)); return new Typeface(nativeCreateFromArray( ptrArray, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); } /** * Create a new typeface from an array of font families, including * also the font families in the fallback list. * * @param weight the weight for this family. {@link RESOLVE_BY_FONT_TABLE} can be used. In that * case, the table information in the first family's font is used. If the first * family has multiple fonts, the closest to the regular weight and upright font * is used. * @param italic the italic information for this family. {@link RESOLVE_BY_FONT_TABLE} can be * used. In that case, the table information in the first family's font is used. * If the first family has multiple fonts, the closest to the regular weight and * upright font is used. * @param families array of font families */ private static Typeface createFromFamiliesWithDefault(FontFamily[] families) { private static Typeface createFromFamiliesWithDefault(FontFamily[] families, int weight, int italic) { long[] ptrArray = new long[families.length + sFallbackFonts.length]; for (int i = 0; i < families.length; i++) { ptrArray[i] = families[i].mNativePtr; Loading @@ -1072,7 +1095,7 @@ public class Typeface { for (int i = 0; i < sFallbackFonts.length; i++) { ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr; } return new Typeface(nativeCreateFromArray(ptrArray)); return new Typeface(nativeCreateFromArray(ptrArray, weight, italic)); } // don't allow clients to call this directly Loading Loading @@ -1155,7 +1178,8 @@ public class Typeface { } else { FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath); FontFamily[] families = { fontFamily }; typeface = Typeface.createFromFamiliesWithDefault(families); typeface = Typeface.createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); } systemFonts.put(f.getName(), typeface); } Loading Loading @@ -1262,7 +1286,7 @@ public class Typeface { private static native void nativeUnref(long native_instance); private static native int nativeGetStyle(long native_instance); private static native int nativeGetBaseWeight(long native_instance); private static native long nativeCreateFromArray(long[] familyArray); private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic); private static native void nativeSetDefault(long native_instance); private static native int[] nativeGetSupportedAxes(long native_instance); } libs/hwui/hwui/Typeface.cpp +49 −17 Original line number Diff line number Diff line Loading @@ -39,14 +39,22 @@ namespace android { // Resolve the 1..9 weight based on base weight and bold flag // This indicates that the passed information should be resolved by OS/2 table. // This value must be the same as the android.graphics.Typeface$Builder.RESOLVE_BY_FONT_TABLE. constexpr int RESOLVE_BY_FONT_TABLE = -1; // Resolve the 1..10 weight based on base weight and bold flag static void resolveStyle(Typeface* typeface) { int weight = typeface->fBaseWeight / 100; // TODO: Better to use raw base weight value for font selection instead of dividing by 100. int weight = (typeface->fBaseWeight + 50) / 100; if (typeface->fSkiaStyle & SkTypeface::kBold) { weight += 3; } if (weight > 9) { weight = 9; if (weight > 10) { weight = 10; } if (weight < 1) { weight = 1; } bool italic = (typeface->fSkiaStyle & SkTypeface::kItalic) != 0; typeface->fStyle = minikin::FontStyle(weight, italic); Loading Loading @@ -115,26 +123,50 @@ Typeface* Typeface::createWeightAlias(Typeface* src, int weight) { } Typeface* Typeface::createFromFamilies( std::vector<std::shared_ptr<minikin::FontFamily>>&& families) { std::vector<std::shared_ptr<minikin::FontFamily>>&& families, int weight, int italic) { Typeface* result = new Typeface; result->fFontCollection.reset(new minikin::FontCollection(families)); if (families.empty()) { ALOGW("createFromFamilies creating empty collection"); result->fSkiaStyle = SkTypeface::kNormal; } else { if (weight == RESOLVE_BY_FONT_TABLE || italic == RESOLVE_BY_FONT_TABLE) { int weightFromFont; bool italicFromFont; const minikin::FontStyle defaultStyle; const std::shared_ptr<minikin::FontFamily>& firstFamily = families[0]; const minikin::MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font; const minikin::MinikinFont* mf = families.empty() ? nullptr : families[0]->getClosestMatch(defaultStyle).font; if (mf != nullptr) { SkTypeface* skTypeface = reinterpret_cast<const 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->fSkiaStyle = skTypeface->style(); const SkFontStyle& style = skTypeface->fontStyle(); weightFromFont = style.weight(); italicFromFont = style.slant() != SkFontStyle::kUpright_Slant; } else { result->fSkiaStyle = SkTypeface::kNormal; // We can't obtain any information from fonts. Just use default values. weightFromFont = SkFontStyle::kNormal_Weight; italicFromFont = false; } if (weight == RESOLVE_BY_FONT_TABLE) { weight = weightFromFont; } if (italic == RESOLVE_BY_FONT_TABLE) { italic = italicFromFont? 1 : 0; } } // Sanitize the invalid value passed from public API. if (weight < 0) { weight = SkFontStyle::kNormal_Weight; } result->fBaseWeight = 400; result->fBaseWeight = weight; // This bold detection comes from SkTypefae.h const bool isBold = weight >= SkFontStyle::kSemiBold_Weight; const bool isItalic = italic == 1; // TODO: remove fSkiaStyle result->fSkiaStyle = isBold ? (isItalic ? SkTypeface::kBoldItalic : SkTypeface::kBold) : (isItalic ? SkTypeface::kItalic : SkTypeface::kNormal); resolveStyle(result); return result; } Loading Loading @@ -165,7 +197,7 @@ void Typeface::setRobotoTypefaceForTest() { Typeface* hwTypeface = new Typeface(); hwTypeface->fFontCollection = collection; hwTypeface->fSkiaStyle = SkTypeface::kNormal; hwTypeface->fBaseWeight = 400; hwTypeface->fBaseWeight = SkFontStyle::kSemiBold_Weight; hwTypeface->fStyle = minikin::FontStyle(4 /* weight */, false /* italic */); Typeface::setDefault(hwTypeface); Loading libs/hwui/hwui/Typeface.h +2 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,8 @@ struct ANDROID_API Typeface { static Typeface* createWeightAlias(Typeface* src, int baseweight); static Typeface* createFromFamilies( std::vector<std::shared_ptr<minikin::FontFamily>>&& families); std::vector<std::shared_ptr<minikin::FontFamily>>&& families, int weight, int italic); static void setDefault(Typeface* face); Loading Loading
core/jni/android/graphics/Typeface.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,8 @@ static jint Typeface_getBaseWeight(JNIEnv* env, jobject obj, jlong faceHandle) { return face->fBaseWeight; } static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) { static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray, int weight, int italic) { ScopedLongArrayRO families(env, familyArray); std::vector<std::shared_ptr<minikin::FontFamily>> familyVec; familyVec.reserve(families.size()); Loading @@ -95,7 +96,8 @@ static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArr FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]); familyVec.emplace_back(family->family); } return reinterpret_cast<jlong>(Typeface::createFromFamilies(std::move(familyVec))); return reinterpret_cast<jlong>( Typeface::createFromFamilies(std::move(familyVec), weight, italic)); } static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) { Loading Loading @@ -133,7 +135,7 @@ static const JNINativeMethod gTypefaceMethods[] = { { "nativeUnref", "(J)V", (void*)Typeface_unref }, { "nativeGetStyle", "(J)I", (void*)Typeface_getStyle }, { "nativeGetBaseWeight", "(J)I", (void*)Typeface_getBaseWeight }, { "nativeCreateFromArray", "([J)J", { "nativeCreateFromArray", "([JII)J", (void*)Typeface_createFromArray }, { "nativeSetDefault", "(J)V", (void*)Typeface_setDefault }, { "nativeGetSupportedAxes", "(J)[I", (void*)Typeface_getSupportedAxes }, Loading
graphics/java/android/graphics/Typeface.java +48 −24 Original line number Diff line number Diff line Loading @@ -173,7 +173,8 @@ public class Typeface { if (sFallbackFonts != null) { synchronized (sDynamicTypefaceCache) { final String key = Builder.createAssetUid( mgr, path, 0 /* ttcIndex */, null /* axes */); mgr, path, 0 /* ttcIndex */, null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */); Typeface typeface = sDynamicTypefaceCache.get(key); if (typeface != null) return typeface; Loading @@ -186,7 +187,8 @@ public class Typeface { return null; } FontFamily[] families = {fontFamily}; typeface = createFromFamiliesWithDefault(families); typeface = createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); sDynamicTypefaceCache.put(key, typeface); return typeface; } Loading Loading @@ -251,10 +253,12 @@ public class Typeface { fontFamily.allowUnsupportedFont(); fontFamily.freeze(); FontFamily[] familyChain = { fontFamily }; typeface = createFromFamiliesWithDefault(familyChain); typeface = createFromFamiliesWithDefault(familyChain, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); synchronized (sDynamicTypefaceCache) { final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */); null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */); sDynamicTypefaceCache.put(key, typeface); } return typeface; Loading @@ -268,7 +272,8 @@ public class Typeface { */ public static Typeface findFromCache(AssetManager mgr, String path) { synchronized (sDynamicTypefaceCache) { final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */); final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */); Typeface typeface = sDynamicTypefaceCache.get(key); if (typeface != null) { return typeface; Loading Loading @@ -406,7 +411,9 @@ public class Typeface { FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR); return; } Typeface typeface = Typeface.createFromFamiliesWithDefault(new FontFamily[] { fontFamily }); Typeface typeface = Typeface.createFromFamiliesWithDefault( new FontFamily[] { fontFamily }, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); synchronized (sDynamicTypefaceCache) { String key = createProviderUid(request.getProviderAuthority(), request.getQuery()); sDynamicTypefaceCache.put(key, typeface); Loading Loading @@ -715,7 +722,7 @@ public class Typeface { * @return Unique id for a given AssetManager and asset path. */ private static String createAssetUid(final AssetManager mgr, String path, int ttcIndex, @Nullable FontVariationAxis[] axes) { @Nullable FontVariationAxis[] axes, int weight, int italic) { final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers(); final StringBuilder builder = new StringBuilder(); final int size = pkgs.size(); Loading @@ -727,6 +734,10 @@ public class Typeface { builder.append("-"); builder.append(Integer.toString(ttcIndex)); builder.append("-"); builder.append(Integer.toString(weight)); builder.append("-"); builder.append(Integer.toString(italic)); builder.append("-"); if (axes != null) { for (FontVariationAxis axis : axes) { builder.append(axis.getTag()); Loading Loading @@ -791,7 +802,7 @@ public class Typeface { * @return Newly created Typeface. May return null if some parameters are invalid. */ public Typeface build() { if (mFd != null) { // set source by setSourceFromFile(FileDescriptor) if (mFd != null) { // Builder is created with file descriptor. try (FileInputStream fis = new FileInputStream(mFd)) { FileChannel channel = fis.getChannel(); long size = channel.size(); Loading @@ -806,12 +817,13 @@ public class Typeface { return resolveFallbackTypeface(); } FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, mWeight, mItalic); } catch (IOException e) { return resolveFallbackTypeface(); } } else if (mAssetManager != null) { // set source by setSourceFromAsset() final String key = createAssetUid(mAssetManager, mPath, mTtcIndex, mAxes); } else if (mAssetManager != null) { // Builder is created with asset manager. final String key = createAssetUid( mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic); synchronized (sLock) { Typeface typeface = sDynamicTypefaceCache.get(key); if (typeface != null) return typeface; Loading @@ -825,11 +837,11 @@ public class Typeface { return resolveFallbackTypeface(); } FontFamily[] families = { fontFamily }; typeface = createFromFamiliesWithDefault(families); typeface = createFromFamiliesWithDefault(families, mWeight, mItalic); sDynamicTypefaceCache.put(key, typeface); return typeface; } } else if (mPath != null) { // set source by setSourceFromFile(File) } else if (mPath != null) { // Builder is created with file path. final FontFamily fontFamily = new FontFamily(); if (!fontFamily.addFont(mPath, mTtcIndex, mAxes, mWeight, mItalic)) { fontFamily.abortCreation(); Loading @@ -839,7 +851,7 @@ public class Typeface { return resolveFallbackTypeface(); } FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, mWeight, mItalic); } else if (mFonts != null) { final FontFamily fontFamily = new FontFamily(); boolean atLeastOneFont = false; Loading @@ -865,7 +877,7 @@ public class Typeface { } fontFamily.freeze(); FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, mWeight, mItalic); } // Must not reach here. Loading Loading @@ -969,7 +981,7 @@ public class Typeface { if (typeface != null) return typeface; final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */); null /* axes */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); typeface = sDynamicTypefaceCache.get(key); if (typeface != null) return typeface; Loading @@ -984,7 +996,8 @@ public class Typeface { fontFamily.allowUnsupportedFont(); fontFamily.freeze(); final FontFamily[] families = { fontFamily }; typeface = createFromFamiliesWithDefault(families); typeface = createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); sDynamicTypefaceCache.put(key, typeface); return typeface; } else { Loading Loading @@ -1037,7 +1050,8 @@ public class Typeface { fontFamily.allowUnsupportedFont(); fontFamily.freeze(); FontFamily[] families = { fontFamily }; return createFromFamiliesWithDefault(families); return createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); } else { fontFamily.abortCreation(); } Loading @@ -1055,16 +1069,25 @@ public class Typeface { for (int i = 0; i < families.length; i++) { ptrArray[i] = families[i].mNativePtr; } return new Typeface(nativeCreateFromArray(ptrArray)); return new Typeface(nativeCreateFromArray( ptrArray, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); } /** * Create a new typeface from an array of font families, including * also the font families in the fallback list. * * @param weight the weight for this family. {@link RESOLVE_BY_FONT_TABLE} can be used. In that * case, the table information in the first family's font is used. If the first * family has multiple fonts, the closest to the regular weight and upright font * is used. * @param italic the italic information for this family. {@link RESOLVE_BY_FONT_TABLE} can be * used. In that case, the table information in the first family's font is used. * If the first family has multiple fonts, the closest to the regular weight and * upright font is used. * @param families array of font families */ private static Typeface createFromFamiliesWithDefault(FontFamily[] families) { private static Typeface createFromFamiliesWithDefault(FontFamily[] families, int weight, int italic) { long[] ptrArray = new long[families.length + sFallbackFonts.length]; for (int i = 0; i < families.length; i++) { ptrArray[i] = families[i].mNativePtr; Loading @@ -1072,7 +1095,7 @@ public class Typeface { for (int i = 0; i < sFallbackFonts.length; i++) { ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr; } return new Typeface(nativeCreateFromArray(ptrArray)); return new Typeface(nativeCreateFromArray(ptrArray, weight, italic)); } // don't allow clients to call this directly Loading Loading @@ -1155,7 +1178,8 @@ public class Typeface { } else { FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath); FontFamily[] families = { fontFamily }; typeface = Typeface.createFromFamiliesWithDefault(families); typeface = Typeface.createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE); } systemFonts.put(f.getName(), typeface); } Loading Loading @@ -1262,7 +1286,7 @@ public class Typeface { private static native void nativeUnref(long native_instance); private static native int nativeGetStyle(long native_instance); private static native int nativeGetBaseWeight(long native_instance); private static native long nativeCreateFromArray(long[] familyArray); private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic); private static native void nativeSetDefault(long native_instance); private static native int[] nativeGetSupportedAxes(long native_instance); }
libs/hwui/hwui/Typeface.cpp +49 −17 Original line number Diff line number Diff line Loading @@ -39,14 +39,22 @@ namespace android { // Resolve the 1..9 weight based on base weight and bold flag // This indicates that the passed information should be resolved by OS/2 table. // This value must be the same as the android.graphics.Typeface$Builder.RESOLVE_BY_FONT_TABLE. constexpr int RESOLVE_BY_FONT_TABLE = -1; // Resolve the 1..10 weight based on base weight and bold flag static void resolveStyle(Typeface* typeface) { int weight = typeface->fBaseWeight / 100; // TODO: Better to use raw base weight value for font selection instead of dividing by 100. int weight = (typeface->fBaseWeight + 50) / 100; if (typeface->fSkiaStyle & SkTypeface::kBold) { weight += 3; } if (weight > 9) { weight = 9; if (weight > 10) { weight = 10; } if (weight < 1) { weight = 1; } bool italic = (typeface->fSkiaStyle & SkTypeface::kItalic) != 0; typeface->fStyle = minikin::FontStyle(weight, italic); Loading Loading @@ -115,26 +123,50 @@ Typeface* Typeface::createWeightAlias(Typeface* src, int weight) { } Typeface* Typeface::createFromFamilies( std::vector<std::shared_ptr<minikin::FontFamily>>&& families) { std::vector<std::shared_ptr<minikin::FontFamily>>&& families, int weight, int italic) { Typeface* result = new Typeface; result->fFontCollection.reset(new minikin::FontCollection(families)); if (families.empty()) { ALOGW("createFromFamilies creating empty collection"); result->fSkiaStyle = SkTypeface::kNormal; } else { if (weight == RESOLVE_BY_FONT_TABLE || italic == RESOLVE_BY_FONT_TABLE) { int weightFromFont; bool italicFromFont; const minikin::FontStyle defaultStyle; const std::shared_ptr<minikin::FontFamily>& firstFamily = families[0]; const minikin::MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font; const minikin::MinikinFont* mf = families.empty() ? nullptr : families[0]->getClosestMatch(defaultStyle).font; if (mf != nullptr) { SkTypeface* skTypeface = reinterpret_cast<const 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->fSkiaStyle = skTypeface->style(); const SkFontStyle& style = skTypeface->fontStyle(); weightFromFont = style.weight(); italicFromFont = style.slant() != SkFontStyle::kUpright_Slant; } else { result->fSkiaStyle = SkTypeface::kNormal; // We can't obtain any information from fonts. Just use default values. weightFromFont = SkFontStyle::kNormal_Weight; italicFromFont = false; } if (weight == RESOLVE_BY_FONT_TABLE) { weight = weightFromFont; } if (italic == RESOLVE_BY_FONT_TABLE) { italic = italicFromFont? 1 : 0; } } // Sanitize the invalid value passed from public API. if (weight < 0) { weight = SkFontStyle::kNormal_Weight; } result->fBaseWeight = 400; result->fBaseWeight = weight; // This bold detection comes from SkTypefae.h const bool isBold = weight >= SkFontStyle::kSemiBold_Weight; const bool isItalic = italic == 1; // TODO: remove fSkiaStyle result->fSkiaStyle = isBold ? (isItalic ? SkTypeface::kBoldItalic : SkTypeface::kBold) : (isItalic ? SkTypeface::kItalic : SkTypeface::kNormal); resolveStyle(result); return result; } Loading Loading @@ -165,7 +197,7 @@ void Typeface::setRobotoTypefaceForTest() { Typeface* hwTypeface = new Typeface(); hwTypeface->fFontCollection = collection; hwTypeface->fSkiaStyle = SkTypeface::kNormal; hwTypeface->fBaseWeight = 400; hwTypeface->fBaseWeight = SkFontStyle::kSemiBold_Weight; hwTypeface->fStyle = minikin::FontStyle(4 /* weight */, false /* italic */); Typeface::setDefault(hwTypeface); Loading
libs/hwui/hwui/Typeface.h +2 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,8 @@ struct ANDROID_API Typeface { static Typeface* createWeightAlias(Typeface* src, int baseweight); static Typeface* createFromFamilies( std::vector<std::shared_ptr<minikin::FontFamily>>&& families); std::vector<std::shared_ptr<minikin::FontFamily>>&& families, int weight, int italic); static void setDefault(Typeface* face); Loading