Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 373b15bd authored by Seigo Nonaka's avatar Seigo Nonaka
Browse files

Fix double bolding

resolveStyle increases minikinStyle's weight value based on Skia's style
value. Since we compute Skia's style based on given weight value, we
should not add extra bold weight to minikinStyle.

This CL also fixes misunderstanding of base weight.
The base weight is only used for computing weight relative to the
weighted alias. Thus, base weight should not be updated except for
createWeightAlias method.

To be clear, this CL changes the function names but keeps the same
semantics as before.

Test: adb shell /data/nativetest/hwui_unit_tests/hwui_unit_tests
Test: am instrument -w -e class android.graphics.cts.TypefaceTest\
      android.graphics.cts/android.support.test.runner.AndroidJUnitRunner
Bug: 37880319
Merged-In: Ied73189b11792fb062da46f45afd2db664e6ecb4

Change-Id: I82350a1bfb99ce198b955f127949e21bccccb1cb
parent 718688f3
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -41,9 +41,6 @@

namespace android {

// Must be same with Java constant in Typeface.Builder. See Typeface.java
constexpr jint RESOLVE_BY_FONT_TABLE = -1;

struct NativeFamilyBuilder {
    NativeFamilyBuilder(uint32_t langId, int variant)
        : langId(langId), variant(variant), allowUnsupportedFont(false) {}
+8 −9
Original line number Diff line number Diff line
@@ -30,14 +30,14 @@ using namespace android;

static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) {
    Typeface* family = reinterpret_cast<Typeface*>(familyHandle);
    Typeface* face = Typeface::createFromTypeface(family, (SkTypeface::Style)style);
    Typeface* face = Typeface::createRelative(family, (SkTypeface::Style)style);
    // TODO: the following logic shouldn't be necessary, the above should always succeed.
    // Try to find the closest matching font, using the standard heuristic
    if (NULL == face) {
        face = Typeface::createFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
        face = Typeface::createRelative(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
    }
    for (int i = 0; NULL == face && i < 4; i++) {
        face = Typeface::createFromTypeface(family, (SkTypeface::Style)i);
        face = Typeface::createRelative(family, (SkTypeface::Style)i);
    }
    return reinterpret_cast<jlong>(face);
}
@@ -45,8 +45,7 @@ static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandl
static jlong Typeface_createFromTypefaceWithExactStyle(JNIEnv* env, jobject, jlong nativeInstance,
        jint weight, jboolean italic) {
    Typeface* baseTypeface = reinterpret_cast<Typeface*>(nativeInstance);
    return reinterpret_cast<jlong>(
            Typeface::createFromTypefaceWithStyle(baseTypeface, weight, italic));
    return reinterpret_cast<jlong>(Typeface::createAbsolute(baseTypeface, weight, italic));
}

static jlong Typeface_createFromTypefaceWithVariation(JNIEnv* env, jobject, jlong familyHandle,
@@ -68,7 +67,7 @@ static jlong Typeface_createFromTypefaceWithVariation(JNIEnv* env, jobject, jlon

static jlong Typeface_createWeightAlias(JNIEnv* env, jobject, jlong familyHandle, jint weight) {
    Typeface* family = reinterpret_cast<Typeface*>(familyHandle);
    Typeface* face = Typeface::createWeightAlias(family, weight);
    Typeface* face = Typeface::createWithDifferentBaseWeight(family, weight);
    return reinterpret_cast<jlong>(face);
}

@@ -82,9 +81,9 @@ static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
    return face->fSkiaStyle;
}

static jint Typeface_getBaseWeight(JNIEnv* env, jobject obj, jlong faceHandle) {
static jint Typeface_getWeight(JNIEnv* env, jobject obj, jlong faceHandle) {
    Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
    return face->fBaseWeight;
    return face->fStyle.getWeight() * 100;
}

static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray,
@@ -134,7 +133,7 @@ static const JNINativeMethod gTypefaceMethods[] = {
    { "nativeCreateWeightAlias",  "(JI)J", (void*)Typeface_createWeightAlias },
    { "nativeUnref",              "(J)V",  (void*)Typeface_unref },
    { "nativeGetStyle",           "(J)I",  (void*)Typeface_getStyle },
    { "nativeGetBaseWeight",      "(J)I",  (void*)Typeface_getBaseWeight },
    { "nativeGetWeight",      "(J)I",  (void*)Typeface_getWeight },
    { "nativeCreateFromArray",    "([JII)J",
                                           (void*)Typeface_createFromArray },
    { "nativeSetDefault",         "(J)V",   (void*)Typeface_setDefault },
+4 −4
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class Typeface {
    public static final int BOLD_ITALIC = 3;

    private int mStyle = 0;
    private int mBaseWeight = 0;
    private int mWeight = 0;

    // Value for weight and italic. Indicates the value is resolved by font metadata.
    // Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
@@ -544,7 +544,7 @@ public class Typeface {
                return base;
            }

            final int weight = (mWeight == RESOLVE_BY_FONT_TABLE) ? base.mBaseWeight : mWeight;
            final int weight = (mWeight == RESOLVE_BY_FONT_TABLE) ? base.mWeight : mWeight;
            final boolean italic =
                    (mItalic == RESOLVE_BY_FONT_TABLE) ? (base.mStyle & ITALIC) != 0 : mItalic == 1;
            final int key = weight << 1 | (italic ? 1 : 0);
@@ -882,7 +882,7 @@ public class Typeface {

        native_instance = ni;
        mStyle = nativeGetStyle(ni);
        mBaseWeight = nativeGetBaseWeight(ni);
        mWeight = nativeGetWeight(ni);
    }

    private static FontFamily makeFamilyFromParsed(FontConfig.Family family,
@@ -1068,7 +1068,7 @@ public class Typeface {
    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 int  nativeGetBaseWeight(long native_instance);
    private static native int  nativeGetWeight(long native_instance);
    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);
+1 −0
Original line number Diff line number Diff line
@@ -319,6 +319,7 @@ LOCAL_SRC_FILES += \
    tests/unit/TestUtilsTests.cpp \
    tests/unit/TextDropShadowCacheTests.cpp \
    tests/unit/TextureCacheTests.cpp \
    tests/unit/TypefaceTests.cpp \
    tests/unit/VectorDrawableTests.cpp \

include $(LOCAL_PATH)/hwui_static_deps.mk
+38 −37
Original line number Diff line number Diff line
@@ -36,28 +36,33 @@
#include <minikin/FontFamily.h>
#include <minikin/Layout.h>
#include <utils/Log.h>
#include <utils/MathUtils.h>

namespace android {

// 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;
static SkTypeface::Style computeSkiaStyle(int weight, bool italic) {
    // This bold detection comes from SkTypeface.h
    if (weight >= SkFontStyle::kSemiBold_Weight) {
        return italic ? SkTypeface::kBoldItalic : SkTypeface::kBold;
    } else {
        return italic ? SkTypeface::kItalic : SkTypeface::kNormal;
    }
}

// Resolve the 1..10 weight based on base weight and bold flag
static void resolveStyle(Typeface* typeface) {
static minikin::FontStyle computeMinikinStyle(int weight, bool italic) {
    // 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 > 10) {
        weight = 10;
    const int minikinWeight = uirenderer::MathUtils::clamp((weight + 50) / 100, 1, 10);
    return minikin::FontStyle(minikinWeight, italic);
}
    if (weight < 1) {
        weight = 1;

// Resolve the relative weight from the baseWeight and target style.
static minikin::FontStyle computeRelativeStyle(int baseWeight, SkTypeface::Style relativeStyle) {
    int weight = baseWeight;
    if ((relativeStyle & SkTypeface::kBold) != 0) {
        weight += 300;
    }
    bool italic = (typeface->fSkiaStyle & SkTypeface::kItalic) != 0;
    typeface->fStyle = minikin::FontStyle(weight, italic);
    bool italic = (relativeStyle & SkTypeface::kItalic) != 0;
    return computeMinikinStyle(weight, italic);
}

Typeface* gDefaultTypeface = NULL;
@@ -67,26 +72,26 @@ Typeface* Typeface::resolveDefault(Typeface* src) {
    return src == nullptr ? gDefaultTypeface : src;
}

Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {
Typeface* Typeface::createRelative(Typeface* src, SkTypeface::Style style) {
    Typeface* resolvedFace = Typeface::resolveDefault(src);
    Typeface* result = new Typeface;
    if (result != nullptr) {
        result->fFontCollection = resolvedFace->fFontCollection;
        result->fSkiaStyle = style;
        result->fBaseWeight = resolvedFace->fBaseWeight;
        resolveStyle(result);
        result->fSkiaStyle = style;
        result->fStyle = computeRelativeStyle(result->fBaseWeight, style);
    }
    return result;
}

Typeface* Typeface::createFromTypefaceWithStyle(Typeface* base, int weight, bool italic) {
Typeface* Typeface::createAbsolute(Typeface* base, int weight, bool italic) {
    Typeface* resolvedFace = Typeface::resolveDefault(base);
    Typeface* result = new Typeface();
    if (result != nullptr) {
        result->fFontCollection = resolvedFace->fFontCollection;
        result->fBaseWeight = weight;
        result->fStyle = minikin::FontStyle(weight / 100, italic);
        result->fSkiaStyle = resolvedFace->fSkiaStyle;
        result->fBaseWeight = resolvedFace->fBaseWeight;
        result->fSkiaStyle = computeSkiaStyle(weight, italic);
        result->fStyle = computeMinikinStyle(weight, italic);
    }
    return result;
}
@@ -103,21 +108,23 @@ Typeface* Typeface::createFromTypefaceWithVariation(Typeface* src,
            // So we will reuse the same collection with incrementing reference count.
            result->fFontCollection = resolvedFace->fFontCollection;
        }
        result->fSkiaStyle = resolvedFace->fSkiaStyle;
        // Do not update styles.
        // TODO: We may want to update base weight if the 'wght' is specified.
        result->fBaseWeight = resolvedFace->fBaseWeight;
        resolveStyle(result);
        result->fSkiaStyle = resolvedFace->fSkiaStyle;
        result->fStyle = resolvedFace->fStyle;
    }
    return result;
}

Typeface* Typeface::createWeightAlias(Typeface* src, int weight) {
Typeface* Typeface::createWithDifferentBaseWeight(Typeface* src, int weight) {
    Typeface* resolvedFace = Typeface::resolveDefault(src);
    Typeface* result = new Typeface;
    if (result != nullptr) {
        result->fFontCollection = resolvedFace->fFontCollection;
        result->fSkiaStyle = resolvedFace->fSkiaStyle;
        result->fBaseWeight = weight;
        resolveStyle(result);
        result->fSkiaStyle = resolvedFace->fSkiaStyle;
        result->fStyle = computeRelativeStyle(weight, result->fSkiaStyle);
    }
    return result;
}
@@ -160,14 +167,8 @@ Typeface* Typeface::createFromFamilies(
    }

    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);
    result->fSkiaStyle = computeSkiaStyle(weight, italic);
    result->fStyle = computeMinikinStyle(weight, italic);
    return result;
}

@@ -197,7 +198,7 @@ void Typeface::setRobotoTypefaceForTest() {
    Typeface* hwTypeface = new Typeface();
    hwTypeface->fFontCollection = collection;
    hwTypeface->fSkiaStyle = SkTypeface::kNormal;
    hwTypeface->fBaseWeight = SkFontStyle::kSemiBold_Weight;
    hwTypeface->fBaseWeight = SkFontStyle::kNormal_Weight;
    hwTypeface->fStyle = minikin::FontStyle(4 /* weight */, false /* italic */);

    Typeface::setDefault(hwTypeface);
Loading